diff --git a/.automated_overrides.eslintrc.json b/.automated_overrides.eslintrc.json new file mode 100644 index 00000000..260a0041 --- /dev/null +++ b/.automated_overrides.eslintrc.json @@ -0,0 +1,19 @@ +{ + "rules": { + "brace-style": ["error", "1tbs"], + "no-trailing-spaces": ["error", { "ignoreComments": true }], + "keyword-spacing": "error", + "eol-last": ["error", "always"], + "no-multi-spaces": ["error", { "ignoreEOLComments": true }], + "semi": ["error", "always"], + "quotes": ["error", "double"], + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-empty": "error" + } +} \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 17331dbd..7096c570 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -35,27 +35,13 @@ "block-scoped-var": "error", "no-new": "error", "no-multi-str": "error", - "no-multi-spaces": ["error", { "ignoreEOLComments": true }], "no-new-wrappers": "error", "no-sequences": "error", "no-self-compare": "error", "no-multi-assign": "error", "no-whitespace-before-property": "error", "no-magic-numbers": ["off", { "ignoreArrayIndexes": true }], - "no-unused-vars": ["error", { "args": "none" }], - "semi": ["error", "always"], - "quotes": ["error", "double"], - "indent": [ - "error", - 4, - { - "SwitchCase": 1 - } - ], - "brace-style": ["error", "1tbs"], - "no-trailing-spaces": ["error", { "ignoreComments": true }], - "keyword-spacing": "error", - "eol-last": ["error", "always"], + "no-unused-vars": ["warn", { "args": "none" }], "jsdoc/check-alignment": "error", "jsdoc/check-param-names": "error", "jsdoc/check-tag-names": "error", @@ -72,7 +58,23 @@ "operator-linebreak": ["error", "after"], "no-unneeded-ternary": ["error", { "defaultAssignment": false }], "arrow-body-style": ["error", "always"], - "regexp/no-unused-capturing-group": "off" + "regexp/no-unused-capturing-group": "off", + "regexp/prefer-w": "off", + "regexp/prefer-d": "off", + + + + "no-empty": "off", + "brace-style": "off", + "no-trailing-spaces": "off", + "keyword-spacing": "off", + "eol-last": "off", + "no-multi-spaces": "off", + "semi": "off", + "quotes": "off", + "indent": "off" + + }, "overrides": [ { diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ea1a7862..83ff2074 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -6,9 +6,6 @@ contact_links: - name: I'm having issues using the software url: https://github.com/Hypfer/Valetudo/discussions/category_choices about: Ask for help in the support section - - name: I have an idea for a feature/an improvement - url: https://github.com/Hypfer/Valetudo/discussions/category_choices - about: Present your idea in the Ideas section - name: I've made a thing utilizing Valetudo url: https://github.com/Hypfer/Valetudo/discussions/category_choices about: Talk about your thing in the Show and tell section diff --git a/.github/workflows/close_threads.yml b/.github/workflows/close_threads.yml new file mode 100644 index 00000000..caaaa7cc --- /dev/null +++ b/.github/workflows/close_threads.yml @@ -0,0 +1,36 @@ +{ + "name": "Close Threads", + "on": { + "schedule": [ + { + "cron": "30 1 * * *" + } + ], + "workflow_dispatch": null + }, + "permissions": { + "issues": "write", + "pull-requests": "write" + }, + "concurrency": { + "group": "lock" + }, + "jobs": { + "close_unconfirmed_after_inactivity": { + "runs-on": "ubuntu-latest", + "steps": [ + { + "uses": "actions/stale@v5", + "with": { + "stale-issue-label": "unconfirmed", + "ignore-updates": true, + "remove-stale-when-updated": false, + "days-before-stale": -1, + "days-before-close": 45, + "close-issue-message": "Closing after being unconfirmed for 45 Days." + } + } + ] + } + } +} diff --git a/.github/workflows/nightly_build.yml b/.github/workflows/nightly_build.yml index 895d2c11..2caa56e3 100644 --- a/.github/workflows/nightly_build.yml +++ b/.github/workflows/nightly_build.yml @@ -14,9 +14,15 @@ 'nightly_build': { 'runs-on': 'ubuntu-latest', + 'if': "github.repository_owner == 'Hypfer'", 'steps': [ - { 'uses': 'actions/checkout@v2' }, + { + 'uses': 'actions/checkout@v3', + 'with': { + 'fetch-depth': 0 + } + }, { 'name': 'Use Node.js 16.x', 'uses': 'actions/setup-node@v3', @@ -39,9 +45,13 @@ 'name': 'UPX-compress valetudo binaries', 'run': 'npm run upx', }, + { + 'name': 'Generate changelog', + 'run': 'npm run generate_nightly_changelog', + }, { 'name': 'Build manifest', - 'run': 'npm run build_release_manifest', + 'run': 'npm run build_release_manifest nightly', }, { 'name': 'Push binaries to nightly repo', diff --git a/.gitignore b/.gitignore index b6cfe6e9..f047159b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ build/ # IntelliJ Idea project files .idea/ +# VSCode project files +.vscode/ /backend/lib/res/valetudo.openapi.schema.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..ed7c08b4 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +# Currently (2022-05-22) we need to ignore peer dependencies as those break the frontend when using react v18 +legacy-peer-deps=true \ No newline at end of file diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index e27f7a8b..00000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v16.2.0 diff --git a/.pedantic_overrides.eslintrc.json b/.pedantic_overrides.eslintrc.json new file mode 100644 index 00000000..cf1751a8 --- /dev/null +++ b/.pedantic_overrides.eslintrc.json @@ -0,0 +1,26 @@ +{ + "rules": { + "no-magic-numbers": [ + "error", + { + "ignoreArrayIndexes": true, + "ignore": [ + -1, + 0, + 1, + + 200, + 400, + 404, + 500, + + 16, + 60, + 10, + 1000, + 1024 + ] + } + ] + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..5db5951e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,81 @@ +# Stage 1 +ARG BUILD_FROM=amd64/alpine:3.15 +FROM node:16.18-alpine3.15 AS BUILD_IMAGE + +# Install dependencies +RUN apk update && \ + apk add --no-cache git && \ + rm -rf /var/cache/apk/* + +# Create working directory +RUN mkdir -p /usr/src/app && chown -R node:node /usr/src/app + +# Configure user +USER node:node + +# Working directory +WORKDIR /usr/src/app + +# Force cache invalidation +ADD https://api.github.com/repos/freeconga/Congatudo/git/refs/heads/master /usr/src/version.json + +# Download valetudo +RUN git clone --depth 1 https://github.com/freeconga/Congatudo --single-branch . + +# Build environment +ENV NODE_ENV=production +ENV PKG_CACHE_PATH=./build_dependencies/pkg + +# Install dependencies +RUN npm ci --production=false + +# Build openapi schema +RUN npm run build_openapi_schema + +# Build frontend +RUN npm run build --workspace=frontend + +# Build args +ARG PKG_TARGET=node16-linuxstatic-x64 +ARG PKG_OPTIONS=expose-gc,max-heap-size=64 + +# Build binary +RUN npx pkg \ + --targets "${PKG_TARGET}" \ + --compress Brotli \ + --no-bytecode \ + --public-packages "*" \ + --options "${PKG_OPTIONS}" \ + --output ./build/valetudo \ + backend + +# Stage 2 +FROM ${BUILD_FROM} + +# Install dependencies +RUN apk update && \ + apk add --no-cache dumb-init && \ + rm -rf /var/cache/apk/* + +# Configure user +RUN addgroup -S node && adduser -S node -G node +RUN mkdir -p /etc/valetudo && chown -R node:node /etc/valetudo +USER node:node + +# Working directory +WORKDIR /usr/local/bin + +# Copy from build image +COPY --chown=node:node --from=BUILD_IMAGE /usr/src/app/build/valetudo ./valetudo + +# Exposed ports +EXPOSE 8080 +EXPOSE 4010 4030 4050 + +# Run environment +ENV LANG C.UTF-8 +ENV VALETUDO_CONFIG_PATH=/etc/valetudo/config.json +ENV NODE_ENV=production + +# Run binary +CMD ["dumb-init", "valetudo"] diff --git a/README.md b/README.md index c0f5d134..cc7f396f 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ There's also [an android companion app](https://valetudo.cloud/pages/companion_a setting-up your newly-rooted vacuum. -For more information, check out the [Valetudo Newcomer Guide Late 2021 Edition](https://valetudo.cloud/pages/general/newcomer_guide_late_2021.html) as well -as the [getting started guide](https://valetudo.cloud/pages/general/getting-started.html) and also the docs in general at [https://valetudo.cloud](https://valetudo.cloud) +For more information, check out the [getting started guide](https://valetudo.cloud/pages/general/getting-started.html) +and also the docs in general at [https://valetudo.cloud](https://valetudo.cloud) There, you will also find a list of [supported robots](https://valetudo.cloud/pages/general/supported-robots.html). @@ -39,15 +39,16 @@ There, you will also find a list of [supported robots](https://valetudo.cloud/pa ![image](https://user-images.githubusercontent.com/974410/143459816-0a5fb9e5-d690-483e-99b0-84c76ef11eaf.png) ![image](https://user-images.githubusercontent.com/974410/143459878-184c7336-002c-4e04-a706-215499338fce.png) -![image](https://user-images.githubusercontent.com/974410/138561874-f5e5fee9-81dd-43fb-9de0-75263169a0e6.png) -![image](https://user-images.githubusercontent.com/974410/138561884-9633600b-3362-454b-b95d-90f8e5951971.png) - +![image](https://user-images.githubusercontent.com/974410/152567792-73e4ba52-f39b-44fd-a0ae-18a5c4115e7f.png) +![image](https://user-images.githubusercontent.com/974410/152567884-b4c06af8-3bfe-4c12-976e-2e424f86df56.png) ### Tablet/Desktop -![image](https://user-images.githubusercontent.com/974410/138562037-05bc5140-d7af-488b-8734-72e66b820192.png) +![image](https://user-images.githubusercontent.com/974410/152569273-23c4ee7e-310b-40f7-8762-eed661547dff.png) + +![image](https://user-images.githubusercontent.com/974410/152568144-4b237999-4373-44e3-9b29-b6498d7db81e.png) -![image](https://user-images.githubusercontent.com/974410/138561911-77aa8d10-3918-4eb7-96ff-8a6d0440dfce.png) +![image](https://user-images.githubusercontent.com/974410/152568471-c111328b-b3d5-4ea8-9a1f-21bb5ae987ca.png) ![image](https://user-images.githubusercontent.com/974410/138562111-3cbfe03c-7a19-4e57-9bfb-6b872239f432.png) diff --git a/assets/icons/segment.svg b/assets/icons/segment.svg index d7827d70..08f1c2ce 100644 --- a/assets/icons/segment.svg +++ b/assets/icons/segment.svg @@ -1,11 +1,9 @@ - - + + - - - - - + + + diff --git a/assets/icons/segment_active.svg b/assets/icons/segment_selected.svg similarity index 65% rename from assets/icons/segment_active.svg rename to assets/icons/segment_selected.svg index 1e99587c..e96662f4 100644 --- a/assets/icons/segment_active.svg +++ b/assets/icons/segment_selected.svg @@ -1,11 +1,7 @@ - - + + - - - - diff --git a/assets/misc/valetudo_home_assistant_mqtt_camera_hack.xcf b/assets/misc/valetudo_home_assistant_mqtt_camera_hack.xcf deleted file mode 100644 index a0adc59f..00000000 Binary files a/assets/misc/valetudo_home_assistant_mqtt_camera_hack.xcf and /dev/null differ diff --git a/assets/misc/valetudo_home_assistant_mqtt_wrapper.xcf b/assets/misc/valetudo_home_assistant_mqtt_wrapper.xcf new file mode 100644 index 00000000..e8c5c8de Binary files /dev/null and b/assets/misc/valetudo_home_assistant_mqtt_wrapper.xcf differ diff --git a/assets/misc/works_with_valetudo_v3.svg b/assets/misc/works_with_valetudo_v3.svg index 23dcf45c..c77a6e92 100644 --- a/assets/misc/works_with_valetudo_v3.svg +++ b/assets/misc/works_with_valetudo_v3.svg @@ -23,9 +23,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1.979899" - inkscape:cx="149.25004" - inkscape:cy="183.09015" + inkscape:zoom="3.959798" + inkscape:cx="309.99056" + inkscape:cy="147.86108" inkscape:document-units="mm" inkscape:current-layer="layer1" inkscape:document-rotation="0" @@ -37,12 +37,12 @@ fit-margin-bottom="0" showguides="true" inkscape:guide-bbox="true" - inkscape:window-width="2560" - inkscape:window-height="1377" - inkscape:window-x="2552" + inkscape:window-width="3840" + inkscape:window-height="1537" + inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" - inkscape:pagecheckerboard="0" + inkscape:pagecheckerboard="true" inkscape:snap-global="false"> - - + inkscape:label="Background" /> + + - { Logger.error("unhandledRejection", { diff --git a/backend/lib/Configuration.js b/backend/lib/Configuration.js index ec3408e6..6366e60a 100644 --- a/backend/lib/Configuration.js +++ b/backend/lib/Configuration.js @@ -8,7 +8,7 @@ const path = require("path"); const DEFAULT_SETTINGS = require("./res/default_config.json"); const Logger = require("./Logger"); const SCHEMAS = require("./doc/Configuration.openapi.json"); -const Tools = require("./Tools"); +const Tools = require("./utils/Tools"); class Configuration { diff --git a/backend/lib/Events.js b/backend/lib/Events.js deleted file mode 100644 index b838b6aa..00000000 --- a/backend/lib/Events.js +++ /dev/null @@ -1,50 +0,0 @@ -const EventEmitter = require("events").EventEmitter; - -class Events { - constructor() { - /** @private */ - this.eventEmitter = new EventEmitter(); - } - - emitMapUpdated() { - this.eventEmitter.emit(Events.MapUpdated); - } - - /** - * @param {() => void} listener - */ - onMapUpdated(listener) { - this.eventEmitter.on(Events.MapUpdated, listener); - } - - /** - * @param {import("./entities/state/RobotState")} status - */ - emitStatusUpdated(status) { - this.eventEmitter.emit(Events.StatusUpdated, status); - } - - /** - * @param {() => void} listener - */ - onStatusUpdated(listener) { - this.eventEmitter.on(Events.StatusUpdated, listener); - } - - emitMqttConfigChanged() { - this.eventEmitter.emit(Events.MqttConfigChanged); - } - - /** - * @param {() => void} listener - */ - onMqttConfigChanged(listener) { - this.eventEmitter.on(Events.MqttConfigChanged, listener); - } -} - -Events.MapUpdated = "MapUpdated"; -Events.StatusUpdated = "StatusUpdated"; -Events.MqttConfigChanged = "MqttConfigChanged"; - -module.exports = Events; diff --git a/backend/lib/Logger.js b/backend/lib/Logger.js index 5c63a247..b144ae54 100644 --- a/backend/lib/Logger.js +++ b/backend/lib/Logger.js @@ -1,7 +1,7 @@ const EventEmitter = require("events").EventEmitter; const fs = require("fs"); const os = require("os"); -const Tools = require("./Tools"); +const Tools = require("./utils/Tools"); const util = require("util"); class Logger { @@ -92,15 +92,20 @@ class Logger { log(level, ...args) { if (this.logLevel["level"] <= Logger.LogLevels[level]["level"]) { const logLinePrefix = this.buildLogLinePrefix(level.toUpperCase()); - Logger.LogLevels[level]["callback"](logLinePrefix, ...args); - const logLine = [logLinePrefix, ...args].map(arg => { if (typeof arg === "string") { return arg; } - return util.inspect(arg); + + return util.inspect( + arg, + { + depth: Infinity + } + ); }).join(" "); + Logger.LogLevels[level]["callback"](logLine); this.logLineToFile(logLine); this._logEventEmitter.emit("LogMessage", logLine); } diff --git a/backend/lib/NTPClient.js b/backend/lib/NTPClient.js index 2853d489..d631abb5 100644 --- a/backend/lib/NTPClient.js +++ b/backend/lib/NTPClient.js @@ -4,7 +4,7 @@ const execSync = require("child_process").execSync; const Logger = require("./Logger"); const States = require("./entities/core/ntpClient"); -const Tools = require("./Tools"); +const Tools = require("./utils/Tools"); class NTPClient { @@ -29,6 +29,8 @@ class NTPClient { this.state = new States.ValetudoNTPClientDisabledState({}); } + // On startup, we need to wait for a while for Valetudo to fully start up (at least when using pkg) or else + // we will get ntp sync timeouts in the log due to something blocking the process for a while setTimeout(() => { this.reconfigure(); }, 10000); diff --git a/backend/lib/NetworkAdvertisementManager.js b/backend/lib/NetworkAdvertisementManager.js index e5a18ff3..fea4207a 100644 --- a/backend/lib/NetworkAdvertisementManager.js +++ b/backend/lib/NetworkAdvertisementManager.js @@ -1,14 +1,14 @@ const Logger = require("./Logger"); -const Tools = require("./Tools"); +const Tools = require("./utils/Tools"); const Bonjour = require("bonjour-service"); -const nodessdp = require("node-ssdp"); +const SSDPServer = require("./utils/SSDPServer"); const NETWORK_STATE_CHECK_INTERVAL = 30 * 1000; class NetworkAdvertisementManager { /** - * This class handles advertisement via both SSDP (UPnP) as well as zeroconf/mdns/bonjour + * This class handles advertisement via both SSDP (UPnP) and zeroconf/mdns/bonjour * * @param {object} options * @param {import("./Configuration")} options.config @@ -23,50 +23,62 @@ class NetworkAdvertisementManager { this.networkStateCheckTimeout = undefined; this.ipAddresses = ""; + this.config.onUpdate((key) => { + if (key === "networkAdvertisement") { + this.restart().catch((err) => { + Logger.warn("Error while restarting NetworkAdvertisementManager due to config change", err); + }); + } + }); + this.setUp(); } + /** + * @public + * @return {{port: number, zeroconfHostname: string}} + */ + getProperties() { + return { + port: this.webserverPort, + zeroconfHostname: Tools.GET_ZEROCONF_HOSTNAME() + }; + } + /** * @private */ setUp() { const networkAdvertisementConfig = this.config.get("networkAdvertisement"); - if (networkAdvertisementConfig.enabled === true && this.config.get("embedded") === true) { - this.setUpSSDP(); - this.setUpBonjour(); + if (this.config.get("embedded") === true) { + if (networkAdvertisementConfig.enabled === true) { + this.setUpSSDP(); + this.setUpBonjour(); - this.ipAddresses = Tools.GET_CURRENT_HOST_IP_ADDRESSES().sort().join(); - this.networkStateCheckTimeout = setTimeout(() => { - this.checkNetworkStateAndReschedule(); - }, NETWORK_STATE_CHECK_INTERVAL); + this.ipAddresses = Tools.GET_CURRENT_HOST_IP_ADDRESSES().sort().join(); + this.networkStateCheckTimeout = setTimeout(() => { + this.checkNetworkStateAndReschedule(); + }, NETWORK_STATE_CHECK_INTERVAL); + } + } else { + Logger.info("Not starting NetworkAdvertisementManager because we're not in embedded mode"); } + } /** * @private */ setUpSSDP() { - this.ssdpServer = new nodessdp.Server({ - location: { - port: this.webserverPort, - path: "/_ssdp/valetudo.xml" - } + this.ssdpServer = new SSDPServer({ + port: this.webserverPort }); - this.ssdpServer.addUSN("upnp:rootdevice"); - this.ssdpServer.addUSN("uuid:" + Tools.GET_SYSTEM_ID() + "::upnp:rootdevice"); - try { - this.ssdpServer.start(err => { - if (err) { - Logger.warn("Error while starting SSDP/UPnP advertisement", err); - } else { - Logger.info("SSDP/UPnP advertisement started"); - } - }); + this.ssdpServer.start(); } catch (e) { - Logger.warn("Exception while starting SSDP/UPnP advertisement", e); + Logger.warn("Error while starting SSDP/UPnP advertisement", e); } } @@ -77,8 +89,8 @@ class NetworkAdvertisementManager { this.bonjourServer = new Bonjour.Bonjour(undefined, (err) => { Logger.warn("Error while responding to mDNS query:", err); - this.restart().then(() => {/*intentional*/}).catch(err => { - this.shutdown().then(() => {/*intentional*/}).catch(err => { + this.restart().catch(err => { + this.shutdown().catch(err => { throw err; }); }); @@ -86,8 +98,8 @@ class NetworkAdvertisementManager { Logger.info("Valetudo can be reached via: " + Tools.GET_ZEROCONF_HOSTNAME()); - this.publishBonjourService("Valetudo " + this.robot.getModelName() + " Web", "http"); - this.publishBonjourService("Valetudo " + this.robot.getModelName(), "valetudo"); + this.publishBonjourService(`Valetudo ${Tools.GET_HUMAN_READABLE_SYSTEM_ID()} Web`, "http"); + this.publishBonjourService(`Valetudo ${Tools.GET_HUMAN_READABLE_SYSTEM_ID()}`, "valetudo"); } /** diff --git a/backend/lib/Valetudo.js b/backend/lib/Valetudo.js index 9b0df5e9..210f3848 100644 --- a/backend/lib/Valetudo.js +++ b/backend/lib/Valetudo.js @@ -5,7 +5,7 @@ const MqttController = require("./mqtt/MqttController"); const NTPClient = require("./NTPClient"); const os = require("os"); const path = require("path"); -const Tools = require("./Tools"); +const Tools = require("./utils/Tools"); const v8 = require("v8"); const ValetudoEventStore = require("./ValetudoEventStore"); const Webserver = require("./webserver/WebServer"); @@ -68,30 +68,33 @@ class Valetudo { robot: this.robot }); + this.mqttController = new MqttController({ + config: this.config, + robot: this.robot + }); + + this.networkAdvertisementManager = new NetworkAdvertisementManager({ + config: this.config, + robot: this.robot + }); + this.webserver = new Webserver({ config: this.config, robot: this.robot, + mqttController: this.mqttController, + networkAdvertisementManager: this.networkAdvertisementManager, ntpClient: this.ntpClient, updater: this.updater, valetudoEventStore: this.valetudoEventStore }); - this.mqttClient = new MqttController({ - config: this.config, - robot: this.robot - }); - this.scheduler = new Scheduler({ config: this.config, robot: this.robot, ntpClient: this.ntpClient }); - this.networkAdvertisementManager = new NetworkAdvertisementManager({ - config: this.config, - robot: this.robot - }); this.setupDebuggingFeatures(); this.setupMemoryManagement(); @@ -126,14 +129,16 @@ class Valetudo { //@ts-ignore if (typeof global.gc === "function") { const heapLimit = v8.getHeapStatistics().heap_size_limit; - const overLimit = heapLimit + (10*1024*1024); //10mb of buffers and other stuff sounds somewhat reasonable + const overHeapLimit = heapLimit + (10*1024*1024); //10mb of buffers and other stuff sounds somewhat reasonable + const rssLimit = os.totalmem()*(1/3); + let lastForcedGc = new Date(0); this.gcInterval = setInterval(() => { //@ts-ignore const rss = process.memoryUsage.rss(); - if (rss > overLimit) { + if (rss > overHeapLimit) { const now = new Date(); //It doesn't make sense to GC every 250ms repeatedly. Therefore, we rate-limit this if (now.getTime() - 2500 > lastForcedGc.getTime()) { @@ -143,7 +148,6 @@ class Valetudo { //eslint-disable-next-line no-undef global.gc(); - //@ts-ignore const rssAfter = process.memoryUsage.rss(); const rssDiff = rss - rssAfter; @@ -155,7 +159,7 @@ class Valetudo { } } - if (rss > os.totalmem()*(1/3) && this.config.get("embedded") === true) { + if (rss > rssLimit && this.config.get("embedded") === true) { Logger.error( "Valetudo is currently taking up " + rss + " bytes which is more than 1/3 of available system memory. " + @@ -214,8 +218,8 @@ class Valetudo { await this.networkAdvertisementManager.shutdown(); await this.scheduler.shutdown(); - if (this.mqttClient) { - await this.mqttClient.shutdown(); + if (this.mqttController) { + await this.mqttController.shutdown(); } await this.webserver.shutdown(); diff --git a/backend/lib/core/RobotFirmwareError.js b/backend/lib/core/RobotFirmwareError.js new file mode 100644 index 00000000..ea1141bc --- /dev/null +++ b/backend/lib/core/RobotFirmwareError.js @@ -0,0 +1,12 @@ +/** + * A RobotFirmwareError is an error that was sent to us by the robots' firmware. + * e.g. "segment 17 doesn't exist and therefore cannot be cleaned" + */ +class RobotFirmwareError extends Error { + constructor(message) { + super(message); + this.name = "RobotFirmwareError"; + } +} + +module.exports = RobotFirmwareError; diff --git a/backend/lib/core/ValetudoRobot.js b/backend/lib/core/ValetudoRobot.js index 0ac4b04d..445eb427 100644 --- a/backend/lib/core/ValetudoRobot.js +++ b/backend/lib/core/ValetudoRobot.js @@ -79,7 +79,7 @@ class ValetudoRobot { } /** - * @private + * @protected */ initInternalSubscriptions() { this.state.subscribe( @@ -112,7 +112,8 @@ class ValetudoRobot { ) ) { this.valetudoEventStore.raise(new ErrorStateValetudoEvent({ - message: status?.metaData?.error_description ?? "Unknown Error" + //@ts-ignore + message: status.error?.message ?? "Unknown Error" })); } }), @@ -120,6 +121,16 @@ class ValetudoRobot { ); } + /** + * This function allows us to inject custom routes into the main webserver + * Usually, this should never be used unless there are _very_ important reasons to do so + * + * @param {any} app The expressjs app instance + */ + initModelSpecificWebserverRoutes(app) { + //intentional + } + async shutdown() { //intentional @@ -133,11 +144,27 @@ class ValetudoRobot { return "ValetudoRobot"; } + /** + * @typedef {object} ModelDetails + * @property {Array} supportedAttachments + */ + + /** + * This method may be overridden to return model-specific details + * such as which types of attachments to expect in the state + * + * @returns {ModelDetails} + */ + getModelDetails() { + return { + supportedAttachments: [] + }; + } + /** * This method may be overridden to return robot-specific well-known properties * such as the firmware version * - * @abstract * @returns {object} */ getProperties() { @@ -220,7 +247,7 @@ ValetudoRobot.EVENTS = { ValetudoRobot.DEFAULT_MAP = require("../res/default_map"); ValetudoRobot.WELL_KNOWN_PROPERTIES = { - FIRMWARE_VERSION: "firmware_version" + FIRMWARE_VERSION: "firmwareVersion" }; module.exports = ValetudoRobot; diff --git a/backend/lib/core/capabilities/MopDockCleanManualTriggerCapability.js b/backend/lib/core/capabilities/MopDockCleanManualTriggerCapability.js new file mode 100644 index 00000000..97fa05fa --- /dev/null +++ b/backend/lib/core/capabilities/MopDockCleanManualTriggerCapability.js @@ -0,0 +1,33 @@ +const Capability = require("./Capability"); +const NotImplementedError = require("../NotImplementedError"); + +/** + * + * @template {import("../ValetudoRobot")} T + * @extends Capability + */ +class MopDockCleanManualTriggerCapability extends Capability { + /** + * @abstract + * @returns {Promise} + */ + async startCleaning() { + throw new NotImplementedError(); + } + + /** + * @abstract + * @returns {Promise} + */ + async stopCleaning() { + throw new NotImplementedError(); + } + + getType() { + return MopDockCleanManualTriggerCapability.TYPE; + } +} + +MopDockCleanManualTriggerCapability.TYPE = "MopDockCleanManualTriggerCapability"; + +module.exports = MopDockCleanManualTriggerCapability; diff --git a/backend/lib/core/capabilities/MopDockDryManualTriggerCapability.js b/backend/lib/core/capabilities/MopDockDryManualTriggerCapability.js new file mode 100644 index 00000000..0d0f6939 --- /dev/null +++ b/backend/lib/core/capabilities/MopDockDryManualTriggerCapability.js @@ -0,0 +1,33 @@ +const Capability = require("./Capability"); +const NotImplementedError = require("../NotImplementedError"); + +/** + * + * @template {import("../ValetudoRobot")} T + * @extends Capability + */ +class MopDockDryManualTriggerCapability extends Capability { + /** + * @abstract + * @returns {Promise} + */ + async startDrying() { + throw new NotImplementedError(); + } + + /** + * @abstract + * @returns {Promise} + */ + async stopDrying() { + throw new NotImplementedError(); + } + + getType() { + return MopDockDryManualTriggerCapability.TYPE; + } +} + +MopDockDryManualTriggerCapability.TYPE = "MopDockDryManualTriggerCapability"; + +module.exports = MopDockDryManualTriggerCapability; diff --git a/backend/lib/core/capabilities/OperationModeControlCapability.js b/backend/lib/core/capabilities/OperationModeControlCapability.js new file mode 100644 index 00000000..8fd6ba47 --- /dev/null +++ b/backend/lib/core/capabilities/OperationModeControlCapability.js @@ -0,0 +1,28 @@ +const NotImplementedError = require("../NotImplementedError"); +const PresetSelectionCapability = require("./PresetSelectionCapability"); + +/** + * @template {import("../ValetudoRobot")} T + * @extends PresetSelectionCapability + */ +class OperationModeControlCapability extends PresetSelectionCapability { + /** + * @abstract + * @param {string} preset + * @returns {Promise} + */ + async selectPreset(preset) { + throw new NotImplementedError(); + } + + /** + * @returns {string} + */ + getType() { + return OperationModeControlCapability.TYPE; + } +} + +OperationModeControlCapability.TYPE = "OperationModeControlCapability"; + +module.exports = OperationModeControlCapability; diff --git a/backend/lib/core/capabilities/RestrictedZoneCapability.js b/backend/lib/core/capabilities/RestrictedZoneCapability.js deleted file mode 100644 index 289e78dc..00000000 --- a/backend/lib/core/capabilities/RestrictedZoneCapability.js +++ /dev/null @@ -1,33 +0,0 @@ -const Capability = require("./Capability"); -const NotImplementedError = require("../NotImplementedError"); - -/** - * @template {import("../ValetudoRobot")} T - * @extends Capability - */ -class RestrictedZoneCapability extends Capability { - /** - * @abstract - * @returns {Promise>} - */ - async getRestrictedZones() { - throw new NotImplementedError(); - } - - /** - * - * @param {Array} restrictedZones - * @returns {Promise} - */ - async setRestrictedZones(restrictedZones) { - throw new NotImplementedError(); - } - - getType() { - return RestrictedZoneCapability.TYPE; - } -} - -RestrictedZoneCapability.TYPE = "RestrictedZoneCapability"; - -module.exports = RestrictedZoneCapability; diff --git a/backend/lib/core/capabilities/SensorCalibrationCapability.js b/backend/lib/core/capabilities/SensorCalibrationCapability.js deleted file mode 100644 index cc834574..00000000 --- a/backend/lib/core/capabilities/SensorCalibrationCapability.js +++ /dev/null @@ -1,39 +0,0 @@ -const Capability = require("./Capability"); -const NotImplementedError = require("../NotImplementedError"); - -/** - * @template {import("../ValetudoRobot")} T - * @extends Capability - */ -class SensorCalibrationCapability extends Capability { - /** - * This function returns the sensors that can be calibrated - * - * @abstract - * @returns {Promise>} - */ - async getSensors() { - throw new NotImplementedError(); - } - - /** - * This function calibrates one of the sensors available for calibration - * - * @abstract - * @param {string} type - * @param {string} [subType] - * @returns {Promise} - */ - async calibrateSensor(type, subType) { - throw new NotImplementedError(); - } - - - getType() { - return SensorCalibrationCapability.TYPE; - } -} - -SensorCalibrationCapability.TYPE = "SensorCalibrationCapability"; - -module.exports = SensorCalibrationCapability; diff --git a/backend/lib/core/capabilities/VirtualWallCapability.js b/backend/lib/core/capabilities/VirtualWallCapability.js deleted file mode 100644 index 4e0f4866..00000000 --- a/backend/lib/core/capabilities/VirtualWallCapability.js +++ /dev/null @@ -1,34 +0,0 @@ -const Capability = require("./Capability"); -const NotImplementedError = require("../NotImplementedError"); - -/** - * @template {import("../ValetudoRobot")} T - * @extends Capability - */ -class VirtualWallCapability extends Capability { - /** - * @abstract - * @returns {Promise>} - */ - async getVirtualWalls() { - throw new NotImplementedError(); - } - - /** - * This will get ugly if theres a robot with named walls or something like that - * - * @param {Array} virtualWalls - * @returns {Promise} - */ - async setVirtualWalls(virtualWalls) { - throw new NotImplementedError(); - } - - getType() { - return VirtualWallCapability.TYPE; - } -} - -VirtualWallCapability.TYPE = "VirtualWallCapability"; - -module.exports = VirtualWallCapability; diff --git a/backend/lib/core/capabilities/WifiConfigurationCapability.js b/backend/lib/core/capabilities/WifiConfigurationCapability.js index 7ecb89fe..2b1d7caa 100644 --- a/backend/lib/core/capabilities/WifiConfigurationCapability.js +++ b/backend/lib/core/capabilities/WifiConfigurationCapability.js @@ -26,6 +26,15 @@ class WifiConfigurationCapability extends Capability { getType() { return WifiConfigurationCapability.TYPE; } + + /** + * @return {{provisionedReconfigurationSupported: boolean}} + */ + getProperties() { + return { + provisionedReconfigurationSupported: false + }; + } } WifiConfigurationCapability.TYPE = "WifiConfigurationCapability"; diff --git a/backend/lib/core/capabilities/index.js b/backend/lib/core/capabilities/index.js index 95948de2..91c31482 100644 --- a/backend/lib/core/capabilities/index.js +++ b/backend/lib/core/capabilities/index.js @@ -18,11 +18,13 @@ module.exports = { MapSegmentationCapability: require("./MapSegmentationCapability"), MapSnapshotCapability: require("./MapSnapshotCapability"), MappingPassCapability: require("./MappingPassCapability"), + MopDockCleanManualTriggerCapability: require("./MopDockCleanManualTriggerCapability"), + MopDockDryManualTriggerCapability: require("./MopDockDryManualTriggerCapability"), + OperationModeControlCapability: require("./OperationModeControlCapability"), PendingMapChangeHandlingCapability: require("./PendingMapChangeHandlingCapability"), PersistentMapControlCapability: require("./PersistentMapControlCapability"), PresetSelectionCapability: require("./PresetSelectionCapability"), QuirksCapability: require("./QuirksCapability"), - SensorCalibrationCapability: require("./SensorCalibrationCapability"), SpeakerTestCapability: require("./SpeakerTestCapability"), SpeakerVolumeControlCapability: require("./SpeakerVolumeControlCapability"), TotalStatisticsCapability: require("./TotalStatisticsCapability"), diff --git a/backend/lib/doc/Configuration.openapi.json b/backend/lib/doc/Configuration.openapi.json index b7c574b4..9bb004c5 100644 --- a/backend/lib/doc/Configuration.openapi.json +++ b/backend/lib/doc/Configuration.openapi.json @@ -44,12 +44,6 @@ } } }, - "zonePresets": { - "type": "object" - }, - "goToLocationPresets": { - "type": "object" - }, "mqtt": { "$ref": "#/components/schemas/MqttConfigDTO" }, @@ -246,6 +240,15 @@ } } } + }, + "optionalExposedCapabilities": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "SpeakerVolumeControlCapability" + ] + } } } }, @@ -387,9 +390,7 @@ "type": "string", "enum": [ "full_cleanup", - "zone_cleanup", - "segment_cleanup", - "goto_location" + "segment_cleanup" ] }, "params": { diff --git a/backend/lib/entities/Attribute.js b/backend/lib/entities/Attribute.js index a9605b63..9d33482f 100644 --- a/backend/lib/entities/Attribute.js +++ b/backend/lib/entities/Attribute.js @@ -13,15 +13,6 @@ class Attribute extends SerializableEntity { this.type = undefined; this.subType = undefined; } - - /** - * - * @param {Attribute} otherAttribute - * @return {boolean} - */ - equals (otherAttribute) { - return false; - } } module.exports = Attribute; diff --git a/backend/lib/entities/ContainerEntity.js b/backend/lib/entities/ContainerEntity.js index 5d82acca..c39fed01 100644 --- a/backend/lib/entities/ContainerEntity.js +++ b/backend/lib/entities/ContainerEntity.js @@ -117,26 +117,20 @@ class ContainerEntity extends SerializableEntity { */ unsubscribeFromListedMetas(subscriber, metas) { const toDelete = []; - if (metas.length > 0) { - for (const meta of metas) { - let index = -1; - do { - index = meta.subscribers.indexOf(subscriber); - if (index >= 0) { - meta.subscribers.splice(index, 1); - if (meta.subscribers.length === 0) { - toDelete.push(meta); - } - } - } while (index >= 0); + for (const meta of metas) { + meta.subscribers = meta.subscribers.filter(registeredSubscriber => { + return registeredSubscriber !== subscriber; + }); + + if (meta.subscribers.length === 0) { + toDelete.push(meta); } } - while (toDelete.length > 0) { - const emptyMeta = toDelete.pop(); - const index = this.subscribers.indexOf(emptyMeta); - this.subscribers.splice(index, 1); - } + + this.subscribers = this.subscribers.filter(subscriber => { + return !toDelete.includes(subscriber); + }); } /** diff --git a/backend/lib/entities/core/ValetudoGoToLocation.js b/backend/lib/entities/core/ValetudoGoToLocation.js index 79dc74ff..2ae74a1e 100644 --- a/backend/lib/entities/core/ValetudoGoToLocation.js +++ b/backend/lib/entities/core/ValetudoGoToLocation.js @@ -1,29 +1,34 @@ const SerializableEntity = require("../SerializableEntity"); -const uuid = require("uuid"); -// noinspection JSCheckFunctionSignatures class ValetudoGoToLocation extends SerializableEntity { /** * * @param {object} options - * @param {string} options.name * @param {object} options.coordinates * @param {number} options.coordinates.x * @param {number} options.coordinates.y - * @param {string} [options.id] * @param {object} [options.metaData] * @class */ constructor(options) { super(options); - this.name = options.name; this.coordinates = { x: options.coordinates.x, y: options.coordinates.y }; - this.id = options.id ?? uuid.v4(); + + if ( + !( + this.coordinates && + typeof this.coordinates.x === "number" && + typeof this.coordinates.y === "number" + ) + ) { + throw new Error("Invalid coordinates"); + } + } } diff --git a/backend/lib/entities/core/ValetudoRobotError.js b/backend/lib/entities/core/ValetudoRobotError.js new file mode 100644 index 00000000..0a5ca640 --- /dev/null +++ b/backend/lib/entities/core/ValetudoRobotError.js @@ -0,0 +1,78 @@ +const SerializableEntity = require("../SerializableEntity"); + +class ValetudoRobotError extends SerializableEntity { + /** + * @param {object} options + * @param {object} [options.metaData] + * + * @param {object} options.severity + * @param {ValetudoRobotErrorSeverityKind} options.severity.kind + * @param {ValetudoRobotErrorSeverityLevel} options.severity.level + * @param {ValetudoRobotErrorSubsystem} options.subsystem + * + * @param {string} options.message + * @param {string} options.vendorErrorCode + */ + constructor(options) { + super(options); + + this.severity = options.severity; + this.subsystem = options.subsystem; + + this.message = options.message; + this.vendorErrorCode = options.vendorErrorCode; + } +} + +/** + * @typedef {string} ValetudoRobotErrorSeverityKind + * @enum {string} + * + */ +ValetudoRobotError.SEVERITY_KIND = Object.freeze({ + TRANSIENT: "transient", + PERMANENT: "permanent", + + UNKNOWN: "unknown", + + NONE: "none" +}); + +/** + * @typedef {string} ValetudoRobotErrorSeverityLevel + * @enum {string} + * + */ +ValetudoRobotError.SEVERITY_LEVEL = Object.freeze({ + INFO: "info", + WARNING: "warning", + ERROR: "error", + CATASTROPHIC: "catastrophic", + + UNKNOWN: "unknown", + + NONE: "none" +}); + +/** + * @typedef {string} ValetudoRobotErrorSubsystem + * @enum {string} + * + */ +ValetudoRobotError.SUBSYSTEM = Object.freeze({ + CORE: "core", + POWER: "power", + SENSORS: "sensors", + MOTORS: "motors", + NAVIGATION: "navigation", + ATTACHMENTS: "attachments", + DOCK: "dock", + + UNKNOWN: "unknown", + + NONE: "none" +}); + + + +module.exports = ValetudoRobotError; diff --git a/backend/lib/entities/core/ValetudoTimer.js b/backend/lib/entities/core/ValetudoTimer.js index ca868be7..766dc07e 100644 --- a/backend/lib/entities/core/ValetudoTimer.js +++ b/backend/lib/entities/core/ValetudoTimer.js @@ -15,9 +15,7 @@ class ValetudoTimer extends SerializableEntity { * @param {object} options.action * @param {ValetudoTimerActionType} options.action.type * @param {object} options.action.params - * @param {string} [options.action.params.zone_id] * @param {Array} [options.action.params.segment_ids] - * @param {string} [options.action.params.goto_id] * @param {number} [options.action.params.iterations] * @param {boolean} [options.action.params.custom_order] * @param {object} [options.metaData] @@ -28,7 +26,9 @@ class ValetudoTimer extends SerializableEntity { this.id = options.id ?? uuid.v4(); this.enabled = options.enabled; - this.dow = options.dow; + this.dow = [...options.dow].sort((a,b) => { + return a - b; + }); this.hour = options.hour; this.minute = options.minute; this.action = options.action; @@ -42,9 +42,7 @@ class ValetudoTimer extends SerializableEntity { */ ValetudoTimer.ACTION_TYPE = Object.freeze({ FULL_CLEANUP: "full_cleanup", - ZONE_CLEANUP: "zone_cleanup", - SEGMENT_CLEANUP: "segment_cleanup", - GOTO_LOCATION: "goto_location" + SEGMENT_CLEANUP: "segment_cleanup" }); diff --git a/backend/lib/entities/core/ValetudoZone.js b/backend/lib/entities/core/ValetudoZone.js index 6691b2c6..f201c3eb 100644 --- a/backend/lib/entities/core/ValetudoZone.js +++ b/backend/lib/entities/core/ValetudoZone.js @@ -32,6 +32,22 @@ class ValetudoZone extends SerializableEntity { this.points = options.points; this.iterations = options.iterations ? options.iterations : 1; + + if ( + !( + this.points && + typeof this.points.pA?.x === "number" && + typeof this.points.pA?.y === "number" && + typeof this.points.pB?.x === "number" && + typeof this.points.pB?.y === "number" && + typeof this.points.pC?.x === "number" && + typeof this.points.pC?.y === "number" && + typeof this.points.pD?.x === "number" && + typeof this.points.pD?.y === "number" + ) + ) { + throw new Error("Invalid Zone points data"); + } } } diff --git a/backend/lib/entities/core/ValetudoZonePreset.js b/backend/lib/entities/core/ValetudoZonePreset.js deleted file mode 100644 index a162167c..00000000 --- a/backend/lib/entities/core/ValetudoZonePreset.js +++ /dev/null @@ -1,26 +0,0 @@ -const SerializableEntity = require("../SerializableEntity"); -const uuid = require("uuid"); - - -// noinspection JSCheckFunctionSignatures -class ValetudoZonePreset extends SerializableEntity { - /** - * This is a named container which contains ValetudoZones - * - * @param {object} options - * @param {string} options.name - * @param {Array} options.zones - * @param {string} [options.id] - * @param {object} [options.metaData] - * @class - */ - constructor(options) { - super(options); - - this.name = options.name; - this.zones = options.zones; - this.id = options.id ?? uuid.v4(); - } -} - -module.exports = ValetudoZonePreset; diff --git a/backend/lib/entities/core/doc/ValetudoZonePreset.openapi.json b/backend/lib/entities/core/doc/ValetudoZonePreset.openapi.json deleted file mode 100644 index ab7321b7..00000000 --- a/backend/lib/entities/core/doc/ValetudoZonePreset.openapi.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "components": { - "schemas": { - "ValetudoZonePreset": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metaData": { - "type": "object" - }, - "zones": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ValetudoZone" - } - } - } - } - } - } -} diff --git a/backend/lib/entities/core/index.js b/backend/lib/entities/core/index.js index 5293949d..9a7fd845 100644 --- a/backend/lib/entities/core/index.js +++ b/backend/lib/entities/core/index.js @@ -1,10 +1,10 @@ module.exports = { ValetudoDNDConfiguration: require("./ValetudoDNDConfiguration"), ValetudoDataPoint: require("./ValetudoDataPoint"), - ValetudoGoToLocation: require("./ValetudoGoToLocation"), ValetudoMapSegment: require("./ValetudoMapSegment"), ValetudoMapSnapshot: require("./ValetudoMapSnapshot"), ValetudoRestrictedZone: require("./ValetudoRestrictedZone"), + ValetudoRobotError: require("./ValetudoRobotError"), ValetudoSelectionPreset: require("./ValetudoSelectionPreset"), ValetudoSensor: require("./ValetudoSensor"), ValetudoTimer: require("./ValetudoTimer"), @@ -15,6 +15,5 @@ module.exports = { ValetudoWifiNetwork: require("./ValetudoWifiNetwork"), ValetudoWifiStatus: require("./ValetudoWifiStatus"), ValetudoZone: require("./ValetudoZone"), - ValetudoZonePreset: require("./ValetudoZonePreset"), ntpClient: require("./ntpClient") }; diff --git a/backend/lib/entities/core/updater/ValetudoUpdaterErrorState.js b/backend/lib/entities/core/updater/ValetudoUpdaterErrorState.js index e1e8598c..481bd024 100644 --- a/backend/lib/entities/core/updater/ValetudoUpdaterErrorState.js +++ b/backend/lib/entities/core/updater/ValetudoUpdaterErrorState.js @@ -5,7 +5,7 @@ class ValetudoUpdaterErrorState extends ValetudoUpdaterState { * The update process aborted with type, message at timestamp * * @param {object} options - * @param {ValetudoUpdaterErrorType} options.type + * @param {import("../../../updater/lib/ValetudoUpdaterError").ValetudoUpdaterErrorType} options.type * @param {string} options.message * @param {object} [options.metaData] * @class @@ -18,21 +18,5 @@ class ValetudoUpdaterErrorState extends ValetudoUpdaterState { } } -/** - * @typedef {string} ValetudoUpdaterErrorType - * @enum {string} - * - */ -ValetudoUpdaterErrorState.ERROR_TYPE = Object.freeze({ - UNKNOWN: "unknown", - NOT_EMBEDDED: "not_embedded", - NOT_DOCKED: "not_docked", - NOT_WRITABLE: "not_writable", - NOT_ENOUGH_SPACE: "not_enough_space", - DOWNLOAD_FAILED: "download_failed", - NO_RELEASE: "no_release", - NO_MATCHING_BINARY: "no_matching_binary", - INVALID_CHECKSUM: "invalid_checksum", -}); module.exports = ValetudoUpdaterErrorState; diff --git a/backend/lib/entities/map/MapLayer.js b/backend/lib/entities/map/MapLayer.js index 9f9fbe4d..a6bbd77a 100644 --- a/backend/lib/entities/map/MapLayer.js +++ b/backend/lib/entities/map/MapLayer.js @@ -14,6 +14,7 @@ const SerializableEntity = require("../SerializableEntity"); * All of them are required to use the same coordinate space as well as pixel size. * * Any viewport pixel shifting has to be done beforehand + * Pixel coordinates must be integers */ class MapLayer extends SerializableEntity { /** @@ -25,14 +26,9 @@ class MapLayer extends SerializableEntity { */ constructor(options) { super(options); - if (options.pixels.length === 0 || options.pixels.length % 2 !== 0) { - throw new Error("Invalid pixels array"); - } - if (!options.pixels.every(e => { - return Number.isInteger(e); - })) { - throw new Error("Only integer coordinates are allowed"); + if (options.pixels.length === 0 || options.pixels.length % 2 !== 0) { + throw new Error(`Invalid pixels array. Pixel count: ${options.pixels.length}`); } this.type = options.type; @@ -48,76 +44,71 @@ class MapLayer extends SerializableEntity { * @private */ calculateDimensions(pixels) { - if (pixels.length > 0) { - const sums = { - x: 0, - y: 0 - }; - - this.dimensions = { - x: { - min: Infinity, - max: -Infinity, - mid: undefined, - avg: undefined - }, - y: { - min: Infinity, - max: -Infinity, - mid: undefined, - avg: undefined - }, - pixelCount: pixels.length / 2 - }; - - for (let i = 0; i < pixels.length; i = i + 2) { - sums.x += pixels[i]; - sums.y += pixels[i+1]; - - if (pixels[i] < this.dimensions.x.min) { - this.dimensions.x.min = pixels[i]; - } - - if (pixels[i] > this.dimensions.x.max) { - this.dimensions.x.max = pixels[i]; - } - - if (pixels[i+1] < this.dimensions.y.min) { - this.dimensions.y.min = pixels[i+1]; - } - - if (pixels[i+1] > this.dimensions.y.max) { - this.dimensions.y.max = pixels[i+1]; - } + const sums = { + x: 0, + y: 0 + }; + + this.dimensions = { + x: { + min: Infinity, + max: -Infinity, + mid: undefined, + avg: undefined + }, + y: { + min: Infinity, + max: -Infinity, + mid: undefined, + avg: undefined + }, + pixelCount: pixels.length / 2 + }; + + for (let i = 0; i < pixels.length; i = i + 2) { + sums.x += pixels[i]; + sums.y += pixels[i+1]; + + if (pixels[i] < this.dimensions.x.min) { + this.dimensions.x.min = pixels[i]; + } + + if (pixels[i] > this.dimensions.x.max) { + this.dimensions.x.max = pixels[i]; } - this.dimensions.x.mid = Math.round(( - this.dimensions.x.max + - this.dimensions.x.min - ) / 2); - - this.dimensions.y.mid = Math.round(( - this.dimensions.y.max + - this.dimensions.y.min - ) / 2); - - this.dimensions.x.avg = Math.round(sums.x / (pixels.length/2)); - this.dimensions.y.avg = Math.round(sums.y / (pixels.length/2)); - } else { - this.dimensions = { - x: { - min: 0, - max: 0, - mid: 0 - }, - y: { - min: 0, - max: 0, - mid: 0 - }, - pixelCount: 0 - }; + if (pixels[i+1] < this.dimensions.y.min) { + this.dimensions.y.min = pixels[i+1]; + } + + if (pixels[i+1] > this.dimensions.y.max) { + this.dimensions.y.max = pixels[i+1]; + } } + + /* + By only checking these two sums instead of all individual coordinates, we can save a lot of cpu cycles + + The downside of this approach is that we might miss invalid (containing non-integer coordinate) pixels arrays, + because the sums added up to an integer. That's an acceptable trade-off though + */ + if (!(Number.isInteger(sums.x) && Number.isInteger(sums.y))) { + throw new Error("Only integer coordinates are allowed"); + } + + + this.dimensions.x.mid = Math.round(( + this.dimensions.x.max + + this.dimensions.x.min + ) / 2); + + this.dimensions.y.mid = Math.round(( + this.dimensions.y.max + + this.dimensions.y.min + ) / 2); + + this.dimensions.x.avg = Math.round(sums.x / (pixels.length/2)); + this.dimensions.y.avg = Math.round(sums.y / (pixels.length/2)); } /** diff --git a/backend/lib/entities/map/ValetudoMap.js b/backend/lib/entities/map/ValetudoMap.js index 2aa26e4c..c14f0e26 100644 --- a/backend/lib/entities/map/ValetudoMap.js +++ b/backend/lib/entities/map/ValetudoMap.js @@ -10,7 +10,7 @@ const ValetudoMapSegment = require("../core/ValetudoMapSegment"); * * Everything is int. Coordinates and size are in cm * - * The origin is found on the top-left corner + * The origin is found in the top-left corner * */ class ValetudoMap extends SerializableEntity { //TODO: Current, Historic, Etc. @@ -108,10 +108,6 @@ class ValetudoMap extends SerializableEntity { //TODO: Current, Historic, Etc. }); }); } - - getIntersectingLayers(point) { - //TODO - } } module.exports = ValetudoMap; diff --git a/backend/lib/entities/state/attributes/AttachmentStateAttribute.js b/backend/lib/entities/state/attributes/AttachmentStateAttribute.js index fc6c6247..f634ca0c 100644 --- a/backend/lib/entities/state/attributes/AttachmentStateAttribute.js +++ b/backend/lib/entities/state/attributes/AttachmentStateAttribute.js @@ -1,7 +1,7 @@ const StateAttribute = require("./StateAttribute"); /** - * This may at some point also provide it's current capacity/fill level + * This may at some point also provide its current capacity/fill level */ class AttachmentStateAttribute extends StateAttribute { @@ -17,18 +17,6 @@ class AttachmentStateAttribute extends StateAttribute { this.type = options.type; this.attached = options.attached; } - - /** - * - * @param {AttachmentStateAttribute} otherAttribute - * @return {boolean} - */ - equals(otherAttribute) { - return this.__class === otherAttribute.__class && - this.type === otherAttribute.type && - this.subType === otherAttribute.subType && - this.attached === otherAttribute.attached; - } } /** diff --git a/backend/lib/entities/state/attributes/BatteryStateAttribute.js b/backend/lib/entities/state/attributes/BatteryStateAttribute.js index f8333bbf..547a93bc 100644 --- a/backend/lib/entities/state/attributes/BatteryStateAttribute.js +++ b/backend/lib/entities/state/attributes/BatteryStateAttribute.js @@ -13,19 +13,6 @@ class BatteryStateAttribute extends StateAttribute { this.level = options.level; this.flag = options.flag ?? BatteryStateAttribute.FLAG.NONE; } - - /** - * - * @param {BatteryStateAttribute} otherAttribute - * @return {boolean} - */ - equals(otherAttribute) { - return this.__class === otherAttribute.__class && - this.type === otherAttribute.type && - this.subType === otherAttribute.subType && - this.level === otherAttribute.level && - this.flag === otherAttribute.flag; - } } /** diff --git a/backend/lib/entities/state/attributes/ConsumableStateAttribute.js b/backend/lib/entities/state/attributes/ConsumableStateAttribute.js index 22d86f50..6e3ba359 100644 --- a/backend/lib/entities/state/attributes/ConsumableStateAttribute.js +++ b/backend/lib/entities/state/attributes/ConsumableStateAttribute.js @@ -18,19 +18,6 @@ class ConsumableStateAttribute extends StateAttribute { this.remaining = options.remaining; } - - /** - * - * @param {ConsumableStateAttribute} otherAttribute - * @return {boolean} - */ - equals(otherAttribute) { - return this.__class === otherAttribute.__class && - this.type === otherAttribute.type && - this.subType === otherAttribute.subType && - this.remaining.value === otherAttribute.remaining.value && - this.remaining.unit === otherAttribute.remaining.unit; - } } /** @@ -42,7 +29,8 @@ ConsumableStateAttribute.TYPE = Object.freeze({ FILTER: "filter", BRUSH: "brush", SENSOR: "sensor", - MOP: "mop" + MOP: "mop", + DETERGENT: "detergent", }); /** @@ -54,6 +42,7 @@ ConsumableStateAttribute.SUB_TYPE = Object.freeze({ NONE: "none", ALL: "all", MAIN: "main", + SECONDARY: "secondary", SIDE_LEFT: "side_left", SIDE_RIGHT: "side_right" }); diff --git a/backend/lib/entities/state/attributes/DockStatusStateAttribute.js b/backend/lib/entities/state/attributes/DockStatusStateAttribute.js new file mode 100644 index 00000000..506dc4cc --- /dev/null +++ b/backend/lib/entities/state/attributes/DockStatusStateAttribute.js @@ -0,0 +1,31 @@ +const StateAttribute = require("./StateAttribute"); + +class DockStatusStateAttribute extends StateAttribute { + /** + * @param {object} options + * @param {DockStatusStateAttributeValue} options.value + * @param {object} [options.metaData] + */ + constructor(options) { + super(options); + + this.value = options.value; + } +} + +/** + * @typedef {string} DockStatusStateAttributeValue + * @enum {string} + * + */ +DockStatusStateAttribute.VALUE = Object.freeze({ + ERROR: "error", + IDLE: "idle", + PAUSE: "pause", + EMPTYING: "emptying", + CLEANING: "cleaning", + DRYING: "drying" +}); + + +module.exports = DockStatusStateAttribute; diff --git a/backend/lib/entities/state/attributes/PresetSelectionStateAttribute.js b/backend/lib/entities/state/attributes/PresetSelectionStateAttribute.js index 69ed51c7..7333cf2a 100644 --- a/backend/lib/entities/state/attributes/PresetSelectionStateAttribute.js +++ b/backend/lib/entities/state/attributes/PresetSelectionStateAttribute.js @@ -25,18 +25,6 @@ class PresetSelectionStateAttribute extends StateAttribute { } } - /** - * - * @param {PresetSelectionStateAttribute} otherAttribute - * @return {boolean} - */ - equals(otherAttribute) { - return this.__class === otherAttribute.__class && - this.type === otherAttribute.type && - this.subType === otherAttribute.subType && - this.value === otherAttribute.value && - this.customValue === otherAttribute.customValue; - } } /** @@ -47,6 +35,7 @@ class PresetSelectionStateAttribute extends StateAttribute { PresetSelectionStateAttribute.TYPE = Object.freeze({ FAN_SPEED: "fan_speed", WATER_GRADE: "water_grade", + OPERATION_MODE: "operation_mode", }); /** @@ -64,5 +53,15 @@ PresetSelectionStateAttribute.INTENSITY = Object.freeze({ CUSTOM: "custom", }); +/** + * @enum {string} + * + */ +PresetSelectionStateAttribute.MODE = Object.freeze({ + VACUUM: "vacuum", + MOP: "mop", + VACUUM_AND_MOP: "vacuum_and_mop", +}); + module.exports = PresetSelectionStateAttribute; diff --git a/backend/lib/entities/state/attributes/StatusStateAttribute.js b/backend/lib/entities/state/attributes/StatusStateAttribute.js index 81df49f4..5b709617 100644 --- a/backend/lib/entities/state/attributes/StatusStateAttribute.js +++ b/backend/lib/entities/state/attributes/StatusStateAttribute.js @@ -5,6 +5,7 @@ class StatusStateAttribute extends StateAttribute { * @param {object} options * @param {StatusStateAttributeValue} options.value * @param {StatusStateAttributeFlag} [options.flag] + * @param {import("../../core/ValetudoRobotError")} [options.error] * @param {object} [options.metaData] */ constructor(options) { @@ -12,6 +13,8 @@ class StatusStateAttribute extends StateAttribute { this.value = options.value; this.flag = options.flag ?? StatusStateAttribute.FLAG.NONE; + + this.error = this.value === StatusStateAttribute.VALUE.ERROR ? options.error : undefined; } get isActiveState() { @@ -22,20 +25,6 @@ class StatusStateAttribute extends StateAttribute { StatusStateAttribute.VALUE.MOVING ].includes(this.value); } - - /** - * - * @param {StatusStateAttribute} otherAttribute - * @return {boolean} - */ - equals(otherAttribute) { - return this.__class === otherAttribute.__class && - this.type === otherAttribute.type && - this.subType === otherAttribute.subType && - this.value === otherAttribute.value && - this.flag === otherAttribute.flag && - JSON.stringify(this.metaData) === JSON.stringify(otherAttribute.metaData); //todo: ugly - } } /** diff --git a/backend/lib/entities/state/attributes/doc/AttachmentStateAttribute.openapi.json b/backend/lib/entities/state/attributes/doc/AttachmentStateAttribute.openapi.json index c3dfc0bc..956bc81f 100644 --- a/backend/lib/entities/state/attributes/doc/AttachmentStateAttribute.openapi.json +++ b/backend/lib/entities/state/attributes/doc/AttachmentStateAttribute.openapi.json @@ -10,12 +10,7 @@ "type": "object", "properties": { "type": { - "type": "string", - "enum": [ - "dustbin", - "watertank", - "mop" - ] + "$ref": "#/components/schemas/AttachmentStateAttributeType" }, "attached": { "type": "boolean" @@ -23,6 +18,14 @@ } } ] + }, + "AttachmentStateAttributeType": { + "type": "string", + "enum": [ + "dustbin", + "watertank", + "mop" + ] } } } diff --git a/backend/lib/entities/state/attributes/doc/PresetSelectionStateAttribute.openapi.json b/backend/lib/entities/state/attributes/doc/PresetSelectionStateAttribute.openapi.json index 8e42b241..faca716d 100644 --- a/backend/lib/entities/state/attributes/doc/PresetSelectionStateAttribute.openapi.json +++ b/backend/lib/entities/state/attributes/doc/PresetSelectionStateAttribute.openapi.json @@ -13,7 +13,8 @@ "type": "string", "enum": [ "fan_speed", - "water_grade" + "water_grade", + "operation_mode" ] }, "value": { @@ -26,7 +27,11 @@ "high", "max", "turbo", - "custom" + "custom", + + "vacuum", + "mop", + "vacuum_and_mop" ] }, "customValue": { diff --git a/backend/lib/entities/state/attributes/index.js b/backend/lib/entities/state/attributes/index.js index 84b11387..74c3862e 100644 --- a/backend/lib/entities/state/attributes/index.js +++ b/backend/lib/entities/state/attributes/index.js @@ -2,6 +2,7 @@ module.exports = { AttachmentStateAttribute: require("./AttachmentStateAttribute"), BatteryStateAttribute: require("./BatteryStateAttribute"), ConsumableStateAttribute: require("./ConsumableStateAttribute"), + DockStatusStateAttribute: require("./DockStatusStateAttribute"), OperationModeStateAttribute: require("./OperationModeStateAttribute"), PresetSelectionStateAttribute: require("./PresetSelectionStateAttribute"), StatusStateAttribute: require("./StatusStateAttribute") diff --git a/backend/lib/miio/Codec.js b/backend/lib/miio/Codec.js index 1a189d3b..7783aa36 100644 --- a/backend/lib/miio/Codec.js +++ b/backend/lib/miio/Codec.js @@ -1,7 +1,9 @@ -const createMiioHeader = require("./MiioHeader"); - const crypto = require("crypto"); + +const createMiioHeader = require("./MiioHeader"); +const DecodedMiioPacket = require("./DecodedMiioPacket"); const Logger = require("../Logger"); +const Stamp = require("./Stamp"); class Codec { /** @@ -10,6 +12,8 @@ class Codec { */ constructor(options) { this.setToken(options.token); + + this.stamp = new Stamp({}); } /** @@ -17,99 +21,137 @@ class Codec { */ setToken(token) { this.token = token; + this.tokenKey = crypto.createHash("md5").update(this.token).digest(); this.tokenIV = crypto.createHash("md5").update(this.tokenKey).update(this.token).digest(); } + updateStamp(val) { + this.stamp = new Stamp({val: val}).orNew(); + } + /** - * @param {Buffer} response + * @param {Buffer} rawPacket + * @returns {DecodedMiioPacket} */ - handleResponse(response) { + decodeIncomingMiioPacket(rawPacket) { + /* + See: https://github.com/OpenMiHome/mihome-binary-protocol/blob/master/doc/PROTOCOL.md + + 2 byte Magic Number + 2 byte Packet Length + 4 byte Unknown1 + 4 byte Device ID + 4 byte Stamp + 16 byte md5 checksum or token + */ const header = Buffer.alloc(2 + 2 + 4 + 4 + 4 + 16); - response.copy(header, 0,0,32); + rawPacket.copy(header, 0,0,32); - const encrypted = response.slice(32); + const encryptedPayload = rawPacket.slice(32); const stamp = header.readUInt32BE(12); - const digest = crypto.createHash("md5") + const calculatedChecksum = crypto.createHash("md5") .update(header.slice(0, 16)) .update(this.token) - .update(encrypted) + .update(encryptedPayload) .digest(); - const checksum = header.slice(16); + const checksumFromHeader = header.slice(16); let token = null; let msg = null; - if (!checksum.equals(digest)) { - if (encrypted.length > 0) { - Logger.error("Invalid checksum:", {checksum, expected: digest, packet: response, token: this.token}); - } else { - // If we receive an empty packet with a wrong checksum, assume that we're getting - // a new token. - token = Buffer.from(header.slice(16)); - } - } else if (encrypted.length > 0) { - const decipher = crypto.createDecipheriv("aes-128-cbc", this.tokenKey, this.tokenIV); - let decrypted = null; - try { - decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]); - // eslint-disable-next-line no-control-regex - let jsonString = decrypted.toString().replace(/[\u0000-\u0019]+/g, ""); + + if (checksumFromHeader.equals(calculatedChecksum)) { + if (encryptedPayload.length > 0) { + const decipher = crypto.createDecipheriv("aes-128-cbc", this.tokenKey, this.tokenIV); + let decryptedPayload = null; + try { - msg = JSON.parse(jsonString); - } catch (e) { - // Sometimes remote sends invalid json objects with trailing characters. - // Try again with shorter strings. - while (jsonString.length) { - try { - msg = JSON.parse(jsonString); - break; - } catch (e) { - jsonString = jsonString.substr(0, jsonString.length - 1); - } - } - if (msg === null) { - throw e; + decryptedPayload = Buffer.concat([decipher.update(encryptedPayload), decipher.final()]); + + // Apparently most if not all(?) miio messages are stringified json terminated with a \0 + if (decryptedPayload[decryptedPayload.length -1] === 0) { + decryptedPayload = decryptedPayload.slice(0, decryptedPayload.length -1); } + + msg = JSON.parse(decryptedPayload.toString()); + } catch (e) { + Logger.error("Error decrypting/parsing: ", e, msg, decryptedPayload); + } + } + } else { + if (encryptedPayload.length > 0) { + //This should never happen + Logger.error("Invalid checksum:", { + checksumFromHeader: checksumFromHeader, + calculatedChecksum: calculatedChecksum, + packet: rawPacket, + token: this.token + }); + } else { + // If we receive an empty packet with a wrong checksum, assume that we're instead being provided a new token. + token = Buffer.from(header.slice(16)); + + if ( + token.toString("hex") !== "ffffffffffffffffffffffffffffffff" && + token.toString("hex") !== "00000000000000000000000000000000" && + !(this.token.equals(token)) + ) { + Logger.info("Got token from handshake:", token.toString("hex")); + + this.setToken(token); } - } catch (e) { - Logger.error("Error decrypting/parsing: ", e, msg, decrypted); } } - return { + + return new DecodedMiioPacket({ stamp: stamp, deviceId: header.readUInt32BE(8), msg: msg, token: token - }; + }); } /** - * @param {Buffer?} msg - * @param {import("./Stamp")} stamp + * @param {any} payload * @param {number} deviceId + * @returns {Buffer} */ - encode(msg, stamp, deviceId) { - const cipher = crypto.createCipheriv("aes-128-cbc", this.tokenKey, this.tokenIV); - const encrypted = msg === null ? Buffer.alloc(0) : Buffer.concat([cipher.update(msg), cipher.final()]); + encodeOutgoingMiioPacket(payload, deviceId) { + const stamp = this.stamp.orNew(); + let encryptedPayload; + + if (payload !== null) { + const cipher = crypto.createCipheriv("aes-128-cbc", this.tokenKey, this.tokenIV); + const payloadBuf = Buffer.from(JSON.stringify(payload),"utf8"); + + encryptedPayload = Buffer.concat([ + cipher.update(payloadBuf), + cipher.final() + ]); + } else { + encryptedPayload = Buffer.alloc(0); + } + const secondsPassed = Math.max(0, Math.floor((Date.now() - stamp.time) / 1000)); const header = createMiioHeader({ timestamp: stamp.val + secondsPassed, deviceId: deviceId, - payloadLength: encrypted.length, + payloadLength: encryptedPayload.length, unknown: 0 }); - //checksum - const digest = crypto.createHash("md5") + + const calculatedChecksum = crypto.createHash("md5") .update(header.slice(0, 16)) .update(this.token) - .update(encrypted) + .update(encryptedPayload) .digest(); - digest.copy(header, 16); - return Buffer.concat([header, encrypted]); + calculatedChecksum.copy(header, 16); + + return Buffer.concat([header, encryptedPayload]); } } diff --git a/backend/lib/miio/DecodedMiioPacket.js b/backend/lib/miio/DecodedMiioPacket.js new file mode 100644 index 00000000..b0a22235 --- /dev/null +++ b/backend/lib/miio/DecodedMiioPacket.js @@ -0,0 +1,17 @@ +class DecodedMiioPacket { + /** + * @param {object} options + * @param {number} options.stamp + * @param {number} options.deviceId + * @param {any} options.msg + * @param {Buffer?} options.token + */ + constructor(options) { + this.stamp = options.stamp; + this.deviceId = options.deviceId; + this.msg = options.msg; + this.token = options.token; + } +} + +module.exports = DecodedMiioPacket; diff --git a/backend/lib/miio/Dummycloud.js b/backend/lib/miio/Dummycloud.js index a988ab62..c4ed0831 100644 --- a/backend/lib/miio/Dummycloud.js +++ b/backend/lib/miio/Dummycloud.js @@ -10,7 +10,7 @@ class Dummycloud { * @param {number} options.deviceId The unique Device-id of your robot * @param {string} options.bindIP "127.0.0.1" on the robot, "0.0.0.0" in development * @param {() => void} options.onConnected function to call after completing a handshake - * @param {(msg: any) => boolean} options.onMessage function to call for incoming messages + * @param {(msg: any) => boolean} options.onIncomingCloudMessage function to call for incoming messages */ constructor(options) { this.spoofedIP = options.spoofedIP; @@ -19,7 +19,7 @@ class Dummycloud { this.socket = dgram.createSocket("udp4"); this.socket.on("listening", () => { - Logger.info("Dummycloud is spoofing " + this.spoofedIP + ":8053 on " + this.bindIP + ":" + Dummycloud.PORT); + Logger.info(`Dummycloud is spoofing ${this.spoofedIP}:8053 on ${this.bindIP}:${Dummycloud.PORT}`); }); this.socket.on("error", (e) => { @@ -32,19 +32,19 @@ class Dummycloud { this.miioSocket = new MiioSocket({ socket: this.socket, token: options.cloudSecret, - onMessage: this.handleMessage.bind(this), + onIncomingRequestMessage: this.handleIncomingCloudMessage.bind(this), onConnected: options.onConnected, deviceId: options.deviceId, rinfo: undefined, timeout: 2000, name: "cloud", - isServerSocket: true + isCloudSocket: true }); - this.onMessage = options.onMessage; + this.onIncomingCloudMessage = options.onIncomingCloudMessage; } - handleMessage(msg) { + handleIncomingCloudMessage(msg) { // some default handling. switch (msg.method) { case "_otc.info": @@ -60,16 +60,24 @@ class Dummycloud { } }); return; + case "_async.stat": + case "_otc.ncinfo": + case "_otc.ncstat": + this.miioSocket.sendMessage({ + "id": msg.id, + "result": "ok" + }); + return; } - if (!this.onMessage(msg)) { + if (!this.onIncomingCloudMessage(msg)) { //TODO: figure out why we're receiving "{"result":["ok"]}" messages if (Array.isArray(msg.result) && msg.result[0] === "ok") { return; } - Logger.info("Unknown cloud message received:", JSON.stringify(msg)); + Logger.info("Unknown cloud message received:", msg); //TODO: send default cloud ack! } diff --git a/backend/lib/miio/MiioErrorResponseRobotFirmwareError.js b/backend/lib/miio/MiioErrorResponseRobotFirmwareError.js new file mode 100644 index 00000000..3b7a811f --- /dev/null +++ b/backend/lib/miio/MiioErrorResponseRobotFirmwareError.js @@ -0,0 +1,12 @@ +const RobotFirmwareError = require("../core/RobotFirmwareError"); + +class MiioErrorResponseRobotFirmwareError extends RobotFirmwareError { + constructor(msg, response) { + super(msg); + + this.name = "MiioErrorResponseRobotFirmwareError"; + this.response = response; + } +} + +module.exports = MiioErrorResponseRobotFirmwareError; diff --git a/backend/lib/miio/MiioInvalidStampError.js b/backend/lib/miio/MiioInvalidStampError.js deleted file mode 100644 index 30ba196a..00000000 --- a/backend/lib/miio/MiioInvalidStampError.js +++ /dev/null @@ -1,8 +0,0 @@ -class MiioInvalidStampError extends Error { - constructor() { - super("Invalid MiioSocket stamp"); - this.name = "MiioInvalidStampError"; - } -} - -module.exports = MiioInvalidStampError; diff --git a/backend/lib/miio/MiioSocket.js b/backend/lib/miio/MiioSocket.js index b2f6d14f..6efc7514 100644 --- a/backend/lib/miio/MiioSocket.js +++ b/backend/lib/miio/MiioSocket.js @@ -1,20 +1,8 @@ const Codec = require("./Codec"); const createMiioHeader = require("./MiioHeader"); const Logger = require("../Logger"); +const MiioErrorResponseRobotFirmwareError = require("./MiioErrorResponseRobotFirmwareError"); const MiioTimeoutError = require("./MiioTimeoutError"); -const Stamp = require("./Stamp"); - -/** Methods which are used frequently. Those will be logged with trace (instead of debug) verbosity. */ -const TRACE_METHODS = [ - "get_curpos", - "get_prop", - "prop.box_type", - "prop.err_state", - "prop.mop_type", - "prop.run_state", - "prop.suction_grade", - "set_uploadmap", -]; /* * A UDP socket connected to a miio_client. @@ -27,12 +15,12 @@ class MiioSocket { * @param {import("dgram").Socket} options.socket * @param {Buffer} options.token The crypto key for this connection. * @param {number=} options.deviceId The unique Device-id of your robot - * @param {{address: string, port: number}=} options.rinfo + * @param {{address: string, port: number}=} options.rinfo address and port of what we're talking to * @param {number=} options.timeout timeout in milliseconds to wait for a response - * @param {(msg: any) => void} options.onMessage - * @param {(() => void)=} options.onConnected function to call after completing a handshake + * @param {(msg: any) => void} [options.onIncomingRequestMessage] + * @param {(() => void)=} [options.onConnected] function to call after completing a handshake * @param {string} options.name Name used to disambiguate logging messages - * @param {boolean=} options.isServerSocket Whether this is a server socket (send pongs) + * @param {boolean=} options.isCloudSocket Cloud sockets send time sync replies */ constructor(options) { this.codec = new Codec({token: options.token}); @@ -41,131 +29,114 @@ class MiioSocket { this.rinfo = options.rinfo; this.timeout = options.timeout ?? 500; // default timeout: 0.5s this.name = options.name; - this.nextId = 1; - this.stamp = new Stamp({}); + this.nextId = 1; //Only used by cloud sockets + /** * @type {Object. void, + * onTimeoutCallback: () => void, * resolve: (result: any) => void, * reject: (err: any) => void, * method: string * }>} */ this.pendingRequests = {}; - this.onMessage = options.onMessage; + this.onIncomingRequestMessage = options.onIncomingRequestMessage; this.onConnected = options.onConnected; this.connected = false; - this.isServerSocket = options.isServerSocket; + this.isCloudSocket = options.isCloudSocket; + /** @type {null | ((msg: import("./DecodedMiioPacket")) => void)} */ this.onEmptyPacket = null; + this.socket.on("message", (incomingMsg, rinfo) => { this.rinfo = rinfo; - const decodedResponse = this.codec.handleResponse(incomingMsg); - const token = decodedResponse.token; - - if ( - token && - token.toString("hex") !== "ffffffffffffffffffffffffffffffff" && - token.toString("hex") !== "00000000000000000000000000000000" && - !(this.codec.token.equals(token)) - ) { - Logger.info("Got token from handshake:", decodedResponse.token.toString("hex")); - this.token = token; - this.codec.setToken(token); - } + const decodedIncomingPacket = this.codec.decodeIncomingMiioPacket(incomingMsg); - this.deviceId = decodedResponse.deviceId; - const msg = decodedResponse.msg; - const pending = msg && msg["id"] && this.pendingRequests[msg["id"]]; + this.deviceId = decodedIncomingPacket.deviceId; + const msg = decodedIncomingPacket.msg; - this.traceOrDebug( - (msg && msg["method"]) || (pending && pending.method), - "<<< " + this.name + (msg ? ":" : "*"), JSON.stringify(msg ?? {stamp: decodedResponse.stamp}) - ); + Logger.debug(`<<< ${this.name}${msg ? ":" : "*"}`, msg ?? {stamp: decodedIncomingPacket.stamp}); - if (msg === null) { - // Logger.debug("<<|" + this.name, incomingMsg); - // robot server sockets: stamp == 0xFFFFFFFF -> respond with current time - // else -> respond the same stamp - // cloud server sockets: always respond with current time - if (decodedResponse.stamp === 0) { // Initial TimeSync Packet - Logger.debug("^-- initial timesync packet"); - /* - Important note: This causes the miio_client to restart which is bad - if this is sent on each keep-alive packet + if (msg === null) { + if (this.isCloudSocket) { + if (decodedIncomingPacket.stamp === 0) { + //Important note: Responding with a time sync packet causes the miio_client to restart - Make sure to only send this on the initial packet - */ - if (this.isServerSocket) { - // Respond with current time const response = createMiioHeader({timestamp: new Date().getTime() / 1000}); - Logger.debug(">>> Responding to timesync request"); + Logger.debug(">>> Responding to time sync request"); + this.socket.send(response, 0, response.length, this.rinfo.port, this.rinfo.address); + + } else if ( + this.codec.stamp.val === undefined || + this.codec.stamp.val < decodedIncomingPacket.stamp + ) { + // Keep-alive packet. Update our stamp and respond with echo + this.codec.updateStamp(decodedIncomingPacket.stamp); + Logger.debug(">>> " + this.name + "*", {stamp: decodedIncomingPacket.stamp}); + + + this.socket.send(incomingMsg, 0, incomingMsg.length, this.rinfo.port, this.rinfo.address); } - } else if (this.stamp.val === decodedResponse.stamp) { - // pong packet. discard - Logger.debug(this.name +": Discarding pong"); - return; } else { - if (this.stamp.val === undefined || this.stamp.val <= decodedResponse.stamp) { - // keep-alive packet. respond with echo - Logger.debug(">>> " + this.name + "*", JSON.stringify({stamp: decodedResponse.stamp})); + this.codec.updateStamp(decodedIncomingPacket.stamp); - this.socket.send(incomingMsg, 0, incomingMsg.length, this.rinfo.port, this.rinfo.address); - } else { - /** - * Valetudo and the miio_client might enter a 100% cpu busy loop here by exchanging messages with alternating stamps - * e.g. 34->33->34->33 etc - * every 1ms - * - * This could either be some kind of race condition or us misinterpreting something in the miio packet - * In any case, ignoring keep-alives for older stamps seems to help against it - */ - Logger.warn(`MiioSocket ${this.name}: Received keep-alive packet with stamp ${decodedResponse.stamp} but we're at ${this.stamp.val}. Discarding.`); + /* + This exists so that the RetryWrapper can hook the message processing so that it + knows when a successful handshake happened + */ + if (typeof this.onEmptyPacket === "function") { + this.onEmptyPacket(decodedIncomingPacket); } } - } - - this.stamp = new Stamp({val: decodedResponse.stamp}).orNew(); + } else { + this.codec.updateStamp(decodedIncomingPacket.stamp); - if (msg !== null) { if (msg["id"] && (msg["result"] !== undefined || msg["error"] !== undefined)) { - if (pending) { - clearTimeout(pending.timeout_id); + const pendingRequestWithMatchingMsgId = this.pendingRequests[msg["id"]]; - if (msg["error"]) { - if (msg["error"].code === -9999 && msg["error"].message === "user ack timeout") { - //We're reducing the loglevel of these messages as they're not very helpful and - //can be problematic on e.g. viomi - Logger.trace("Miio error response", msg); - } else { + if (pendingRequestWithMatchingMsgId) { + clearTimeout(pendingRequestWithMatchingMsgId.timeout_id); + + if (msg["error"] !== undefined) { + /* + "user ack timeout" is sent by the miio_client if the robots business logic + fails to respond to a request from us in a timely fashion + */ + if (msg["error"].message !== "user ack timeout") { Logger.info("Miio error response", msg); + } else { + Logger.trace("Miio error response", msg); } - pending.reject(msg["error"]); + pendingRequestWithMatchingMsgId.reject( + new MiioErrorResponseRobotFirmwareError( + msg["error"].message, + msg["error"] + ) + ); } else { - pending.resolve(msg["result"]); + pendingRequestWithMatchingMsgId.resolve(msg["result"]); } delete this.pendingRequests[msg["id"]]; } else { - Logger.debug("<< " + this.name + ": ignoring response for non-pending request", JSON.stringify(msg)); + Logger.debug("<< " + this.name + ": ignoring response for non-pending request", msg); } } else if (msg["error"]) { Logger.warn("unhandled error response", msg); } else { - this.onMessage(msg); - } - } else { - if (typeof this.onEmptyPacket === "function") { - this.onEmptyPacket(decodedResponse); + if (typeof this.onIncomingRequestMessage === "function") { + this.onIncomingRequestMessage(msg); + } } } - if (!this.connected && this.onConnected) { + if (!this.connected && typeof this.onConnected === "function") { this.connected = true; + this.onConnected(); } }); @@ -176,30 +147,52 @@ class MiioSocket { * * @param {object?} msg JSON object to send to remote * @param {object} options - * @param {number=} options.timeout timeout in milliseconds, in case of timeout returns a failed - * promise with err = 'timeout' + * @param {number=} options.timeout timeout in milliseconds, in case of timeout returns a failed promise with err = 'timeout' * @returns {Promise} */ sendMessage(msg, options = {}) { return new Promise((resolve, reject) => { + + // If a message is a reply to a request from the robot, it will already have an ID if (msg !== null && msg !== undefined && !msg["id"]) { - if (this.nextId > 0x7fffffff) { // assuming it's a signed 32bit integer - this.nextId = 0; - } + /* + This behaves differently, because the local socket might have other connections exhausting + msgIds, which is why we need to find a way to stay on top. + + This problem should not exist with the cloud socket, allowing us to just count up + on each new message + */ + if (this.isCloudSocket) { + if (this.nextId > MAX_INT32) { + this.nextId = 1; + } - msg["id"] = this.nextId++; + msg["id"] = this.nextId++; + } else { + /* + Unexpectedly, it is not required for the next msgId to be larger than the previous one + It just needs to be different + */ + msg["id"] = MiioSocket.calculateMsgId(new Date()); + } } + /* + If a message has a result or error property, it is a response to a request from the robot, + meaning that we should not add it to our pending requests + */ if (msg !== null && msg !== undefined && !msg["result"] && !msg["error"]) { - this.pendingRequests[msg["id"]] = { + const msgId = msg["id"]; + + this.pendingRequests[msgId] = { resolve: resolve, reject: reject, method: msg["method"], - timeout: () => { - Logger.debug(this.name, "request", msg["id"], msg["method"], "timed out"); - delete this.pendingRequests[msg["id"]]; + onTimeoutCallback: () => { + Logger.debug(`${this.name} request ${msgId} ${msg["method"]} timed out`); + delete this.pendingRequests[msgId]; - if (this.isServerSocket && this.connected === true) { + if (this.isCloudSocket && this.connected === true) { Logger.info("Cloud message timed out. Assuming that we're not connected anymore"); this.connected = false; @@ -210,16 +203,17 @@ class MiioSocket { } }; - this.pendingRequests[msg["id"]].timeout_id = setTimeout( - this.pendingRequests[msg["id"]].timeout, - options.timeout || this.timeout + this.pendingRequests[msgId].timeout_id = setTimeout( + () => { + this.pendingRequests[msgId].onTimeoutCallback(); + }, + options.timeout ?? this.timeout ); } - const payload = msg === null ? null : Buffer.from(JSON.stringify(msg), "utf8"); - const packet = this.codec.encode(payload, this.stamp.orNew(), this.deviceId); + const packet = this.codec.encodeOutgoingMiioPacket(msg, this.deviceId); - this.traceOrDebug(msg && msg["method"], ">>> " + this.name + ":", JSON.stringify(msg)); + Logger.debug(">>> " + this.name + ":", msg); this.socket.send(packet, 0, packet.length, this.rinfo.port, this.rinfo.address); }); } @@ -230,15 +224,10 @@ class MiioSocket { } /** - * Logs a message, uses trace or debug verbosity based on the method name. - * This is to avoid creating too verbose logs in debug mode with frequently repeated messages. - * - * @param {string} method RPC method name - * @param {string} msg - * @param {any[]} args + * @param {(msg: import("./DecodedMiioPacket")) => void} fn */ - traceOrDebug(method, msg, ...args) { - (TRACE_METHODS.includes(method) ? Logger.trace(msg, ...args) : Logger.debug(msg, ...args)); + registerOnEmptyPacketHook(fn) { + this.onEmptyPacket = fn; } /** @@ -249,6 +238,7 @@ class MiioSocket { shutdown() { return new Promise((resolve, reject) => { Logger.debug(this.name, "socket shutdown in progress..."); + try { this.socket.disconnect(); } catch (err) { @@ -257,12 +247,57 @@ class MiioSocket { this.socket.close(() => { Logger.debug(this.name, "socket shutdown done"); + resolve(); }); }); } + + /** + * @private + * @param {Date} date + * @return {number} must be less than MAX_INT32 + */ + static calculateMsgId(date) { + const now = date.getTime(); + + if (now > FEB_1970_UNIXTIME_MS) { // If we're not in january 1970, assume that time is synced + /* + When time is synced, we shift our msgIds by one whole day in seconds so that even if our counter + wraps, there won't be any collisions caused by the time sync. + + This assumes that the robot will sync its time in less than a day. + If it takes longer, there will be a chance of msgId collisions. + This however is unlikely as all known robots today (2022-02-26) reboot daily + + This also won't be an issue if the time is never synced at all. + In that state, the amount of messages exchanged with the robot on the local interface will be limited to 1 per second, + but apart from that, everything should just work up until MAX_INT32 seconds have passed since boot + + During normal operation, all messages should be sent via the cloud interface anyway, meaning that + this limit should not have any effect at all + */ + const id = Math.round(now / 10); //With a synced time, we'll have 100 unique MsgIds per second + const offset = 24 * 60 * 60; // 1 day in seconds + + return offset + (id % (MAX_INT32 - offset)); // wrap if id + offset is larger than MAX_INT32 + } else { + /* + We're somewhere in january 1970 meaning that there's no synced time (yet) + + Therefore, we limit the amount of usable msgIds to one every second + so that there are more IDs available for the 100-per-second synced time state + without any risk of collisions right after the time sync + */ + + return Math.round(now / 1000); + } + } } +const FEB_1970_UNIXTIME_MS = new Date("1970-02-01T00:00:00.000Z").getTime(); +const MAX_INT32 = 0x7fffffff; + /** The default remote port. @const {int} */ MiioSocket.PORT = 54321; diff --git a/backend/lib/miio/RetryWrapper.js b/backend/lib/miio/RetryWrapper.js index 869d4be3..0e9f9cea 100644 --- a/backend/lib/miio/RetryWrapper.js +++ b/backend/lib/miio/RetryWrapper.js @@ -1,7 +1,8 @@ const createMiioHeader = require("./MiioHeader"); const Logger = require("../Logger"); -const MiioInvalidStampError = require("./MiioInvalidStampError"); const MiioTimeoutError = require("./MiioTimeoutError"); +const RetryWrapperSurrenderError = require("./RetryWrapperSurrenderError"); +const Semaphore = require("semaphore"); const STATES = Object.freeze({ HANDSHAKING: "handshaking", @@ -19,22 +20,28 @@ class RetryWrapper { */ constructor(socket, tokenProvider) { this.miioSocket = socket; - this.miioSocket.onEmptyPacket = this.checkHandshakeCompleted.bind(this); + this.miioSocket.registerOnEmptyPacketHook(this.checkHandshakeCompleted.bind(this)); this.tokenProvider = tokenProvider; + this.mutex = Semaphore(1); + this.handshake().then(() => { - Logger.trace("Initial handshake successful"); + Logger.trace(`Initial handshake successful. Stamp ${this.miioSocket.codec.stamp.val}`); }).catch((e) => { Logger.warn("Error in initial handshake", e); }); } + /** + * @param {import("./DecodedMiioPacket")} msg + * @returns {void} + */ checkHandshakeCompleted(msg) { //Because the miioSocket handles the stamp by itself, we just need to set our internal state if we see one - if (this.state === STATES.HANDSHAKING && msg.stamp) { + if (this.state === STATES.HANDSHAKING && msg.stamp > 0) { this.state = STATES.CONNECTED; - Logger.debug("<<= " + this.miioSocket.name + ": handshake complete"); + Logger.debug(`<<= ${this.miioSocket.name}: handshake complete. Stamp ${this.miioSocket.codec.stamp.val}`); } } @@ -62,7 +69,7 @@ class RetryWrapper { */ sendHandshake() { const packet = createMiioHeader(); - Logger.debug(">>> " + this.miioSocket.name + ": HandshakePacket()"); + Logger.debug(`>>> ${this.miioSocket.name}: HandshakePacket()`); this.miioSocket.socket.send(packet, 0, packet.length, this.miioSocket.rinfo.port, this.miioSocket.rinfo.address); } @@ -83,77 +90,123 @@ class RetryWrapper { } /** - * Sends a {'method': method, 'params': args} message on the MiioSocket. - * Performs retries on timeout, does a handshake if this wasn't yet done on the connection. + * Sends a message on the MiioSocket. + * Performs multiple retries on timeout and also does a handshake if this wasn't yet done on the connection. * - * @param {string} method - * @param {object|Array} args + * Will block and wait for an existing request to finish if there is one + * + * @param {object?} msg JSON object to send to remote * @param {object} options * @param {number=} options.retries * @param {number=} options.timeout custom timeout in milliseconds * @returns {Promise} */ - async sendMessage(method, args = [], options = {}) { - const msg = {method: method, params: args}; - - try { - if (!this.miioSocket.stamp.isValid()) { - // Trigger retry after performing new handshake - // noinspection ExceptionCaughtLocallyJS - throw new MiioInvalidStampError(); - } + sendMessage(msg, options = {}) { + return new Promise((resolve, reject) => { + this.mutex.take(() => { + this.sendMessageHelper(msg, options).then(response => { - return await this.miioSocket.sendMessage( - msg, - { - timeout: options.timeout - } - ); - } catch (e) { - if (!(e instanceof MiioTimeoutError) && !(e instanceof MiioInvalidStampError)) { - throw e; //Throw this further up if it's not expected - } + this.mutex.leave(); + resolve(response); + }).catch(err => { - options.retries = options.retries !== undefined ? options.retries : 0; + this.mutex.leave(); + reject(err); + }); + }); + }); + } - if (options.retries > 100) { - Logger.error("Unable to reach vacuum. Giving up after 100 tries"); + /** + * @param {object} msg JSON object to send to remote + * @param {object} options + * @param {number=} options.retries + * @param {number=} options.timeout custom timeout in milliseconds + * @return {Promise} + */ + sendMessageHelper(msg, options) { + return new Promise((resolve, reject) => { + /* + The alternative to this in-method function declaration would be some insanity like + RetryWrapper.sendMessageHelperHelper(msg, options, resolve, reject) + */ + const doRetry = () => { + this.retryHandshakeHelper(msg, options).then(() => { + this.sendMessageHelper(msg, options).then(response => { + resolve(response); + }).catch(err => { + reject(err); + }); + }).catch(err => { + reject(err); + }); + }; + + + //Make sure that we have a valid recent stamp. Without it, we don't even have to try sending something + if (this.miioSocket.codec.stamp.isValid()) { + this.miioSocket.sendMessage(msg, {timeout: options.timeout}).then(response => { + resolve(response); + }).catch(err => { + if (err instanceof MiioTimeoutError && !(err instanceof RetryWrapperSurrenderError)) { + doRetry(); + } else { + reject(err); //Throw this further up if it's not a timeout + } + }); + } else { + doRetry(); + } + }); + } - //Maybe resetting the ID helps? - this.miioSocket.nextId = 0; + /** + * + * This will either + * - handshake and resolve + * - increment the retry counter by modifying the options parameter and resolve + * - throw if retrying doesn't make sense anymore + * + * @private + * + * @param {object?} msg JSON object to send to remote + * @param {object} options + * @param {number=} options.retries + * @param {number=} options.timeout custom timeout in milliseconds + * @returns {Promise} + */ + async retryHandshakeHelper(msg, options = {}) { + if (options.retries > 100) { // undefined > 100 is false + Logger.warn("Unable to reach vacuum. Giving up after 100 tries"); - //Throw this further up instead of retrying - throw new MiioTimeoutError(msg); - } + throw new RetryWrapperSurrenderError(msg); + } - options.retries++; + // ++undefined is NaN and NaN is falsy. See: https://stackoverflow.com/a/13298258 + options.retries = ++options.retries || 0; - if (options.retries % 10 === 0 && options.retries >= 10) { - // We may want to refresh the token from fs just to be sure - let newToken = this.tokenProvider(); - if (!(this.miioSocket.codec.token.equals(newToken))) { - Logger.info("Got an expired token. Changing to new"); + if (options.retries % 10 === 0 && options.retries >= 10) { + // We may want to refresh the token from fs just to be sure + let newToken = this.tokenProvider(); - this.miioSocket.codec.setToken(newToken); - } else { - Logger.warn("Token is okay, however we're unable to reach the vacuum", { - retries: options.retries, - method: method, - args: args - }); - } + if (!(this.miioSocket.codec.token.equals(newToken))) { + Logger.info("Got an expired token. Changing to new"); - // Also do another handshake just to be sure our stamp is correct. - await this.handshake(true); + this.miioSocket.codec.setToken(newToken); + } else { + Logger.debug("Token is okay, however we're unable to reach the vacuum", { + retries: options.retries, + msg: msg + }); } - //Increment the MsgId by 1000 to catch up - this.miioSocket.nextId += 1000; - - //Try again - return this.sendMessage(method, args, options); + // Also do another handshake just to be sure our stamp is correct. + await this.handshake(true); } + + //remove all remains of a previous attempt + delete(msg["id"]); } async shutdown() { diff --git a/backend/lib/miio/RetryWrapperSurrenderError.js b/backend/lib/miio/RetryWrapperSurrenderError.js new file mode 100644 index 00000000..20677f88 --- /dev/null +++ b/backend/lib/miio/RetryWrapperSurrenderError.js @@ -0,0 +1,5 @@ +const MiioTimeoutError = require("./MiioTimeoutError"); + +class RetryWrapperSurrenderError extends MiioTimeoutError {} + +module.exports = RetryWrapperSurrenderError; diff --git a/backend/lib/mqtt/MqttController.js b/backend/lib/mqtt/MqttController.js index 6cdc2064..8d4b6700 100644 --- a/backend/lib/mqtt/MqttController.js +++ b/backend/lib/mqtt/MqttController.js @@ -2,12 +2,14 @@ const asyncMqtt = require("async-mqtt"); const HassAnchor = require("./homeassistant/HassAnchor"); const HassController = require("./homeassistant/HassController"); const HomieCommonAttributes = require("./homie/HomieCommonAttributes"); +const KeyValueDeduplicationCache = require("../utils/KeyValueDeduplicationCache"); const Logger = require("../Logger"); const mqtt = require("mqtt"); const MqttCommonAttributes = require("./MqttCommonAttributes"); const RobotMqttHandle = require("./handles/RobotMqttHandle"); const Semaphore = require("semaphore"); -const Tools = require("../Tools"); +const Tools = require("../utils/Tools"); +const { CAPABILITY_TYPE_TO_HANDLE_MAPPING } = require("./handles/HandleMappings"); /** * @typedef {object} DeconfigureOptions @@ -30,6 +32,8 @@ class MqttController { reconfigure: Semaphore(1) }; + this.messageDeduplicationCache = new KeyValueDeduplicationCache({}); + this.client = null; this.refreshInterval = 30 * 1000; this.refreshIntervalID = null; @@ -39,7 +43,36 @@ class MqttController { this.subscriptions = {}; - this.state = HomieCommonAttributes.STATE.INIT; + this.state = HomieCommonAttributes.STATE.DISCONNECTED; + this.stats = { + messages: { + count: { + received: 0, + sent: 0 + }, + bytes: { + received: 0, + sent: 0 + } + + }, + connection: { + connects: 0, + disconnects: 0, + reconnects: 0, + errors: 0 + } + }; + + this.configDefaults = { + identity: { + friendlyName: this.robot.getModelName() + " " + Tools.GET_HUMAN_READABLE_SYSTEM_ID(), + identifier: Tools.GET_HUMAN_READABLE_SYSTEM_ID() + }, + customizations: { + topicPrefix: "valetudo" + } + }; /** @public */ this.homieAddICBINVMapProperty = false; @@ -73,10 +106,13 @@ class MqttController { controller: this, baseTopic: this.currentConfig.customizations.topicPrefix, topicName: this.currentConfig.identity.identifier, - friendlyName: this.currentConfig.identity.friendlyName + friendlyName: this.currentConfig.identity.friendlyName, + optionalExposedCapabilities: this.currentConfig.optionalExposedCapabilities }); - this.connect().then(); + this.connect().catch(err => { + Logger.error("Error during MQTT connect", err); + }); } this.config.onUpdate(async (key) => { @@ -101,7 +137,8 @@ class MqttController { controller: this, baseTopic: this.currentConfig.customizations.topicPrefix, topicName: this.currentConfig.identity.identifier, - friendlyName: this.currentConfig.identity.friendlyName + friendlyName: this.currentConfig.identity.friendlyName, + optionalExposedCapabilities: this.currentConfig.optionalExposedCapabilities }); await this.connect(); @@ -113,6 +150,40 @@ class MqttController { }); } + /** + * @public + * @return {{stats: ({messages: {bytes: {received: number, sent: number}, count: {received: number, sent: number}}, connection: {reconnects: number, connects: number, disconnects: number, errors: number}}), state: string}} + */ + getStatus() { + return { + state: this.state, + stats: this.stats + }; + } + + /** + * @public + * @return {{identity: {identifier: string, friendlyName: string}, customizations: {topicPrefix: string}}} + */ + getConfigDefaults() { + return this.configDefaults; + } + + getOptionalExposableCapabilities() { + return Object.keys(this.robot.capabilities).map((type) => { + const handle = CAPABILITY_TYPE_TO_HANDLE_MAPPING[type]; + + if (handle && handle.OPTIONAL === true) { + return type; + } else { + return undefined; + } + + }).filter(e => { + return e !== undefined; + }); + } + /** * @private */ @@ -127,19 +198,20 @@ class MqttController { connection: mqttConfig.connection, identity: mqttConfig.identity, interfaces: mqttConfig.interfaces, - customizations: mqttConfig.customizations + customizations: mqttConfig.customizations, + optionalExposedCapabilities: mqttConfig.optionalExposedCapabilities }); if (!this.currentConfig.identity.identifier) { - this.currentConfig.identity.identifier = Tools.GET_HUMAN_READABLE_SYSTEM_ID(); + this.currentConfig.identity.identifier = this.configDefaults.identity.identifier; } if (!this.currentConfig.identity.friendlyName) { - this.currentConfig.identity.friendlyName = this.robot.getModelName() + " " + Tools.GET_HUMAN_READABLE_SYSTEM_ID(); + this.currentConfig.identity.friendlyName = this.configDefaults.identity.friendlyName; } if (!this.currentConfig.customizations.topicPrefix) { - this.currentConfig.customizations.topicPrefix = "valetudo"; + this.currentConfig.customizations.topicPrefix = this.configDefaults.customizations.topicPrefix; } this.currentConfig.stateTopic = this.currentConfig.customizations.topicPrefix + "/" + this.currentConfig.identity.identifier + "/$state"; @@ -227,6 +299,10 @@ class MqttController { this.client.on("connect", () => { Logger.info("Connected successfully to MQTT broker"); + + this.stats.connection.connects++; + this.messageDeduplicationCache.clear(); + this.reconfigure(async () => { await HassAnchor.getTopicReference(HassAnchor.REFERENCE.AVAILABILITY).post(this.currentConfig.stateTopic); @@ -245,7 +321,9 @@ class MqttController { Logger.info("MQTT configured"); }).then(() => { this.setState(HomieCommonAttributes.STATE.READY).then(() => { - this.robotHandle.refresh().then(); + this.robotHandle.refresh().catch(err => { + Logger.error("Error during MQTT handle refresh", err); + }); }); }).catch(e => { Logger.error("Error on MQTT reconfigure", e); @@ -253,6 +331,9 @@ class MqttController { }); this.client.on("message", (topic, message, packet) => { + this.stats.messages.count.received++; + this.stats.messages.bytes.received += packet.length; + if (!Object.prototype.hasOwnProperty.call(this.subscriptions, topic)) { return; } @@ -260,10 +341,10 @@ class MqttController { const msg = message.toString(); //@ts-ignore - if (packet?.retain === true) { + if (packet.retain === true) { Logger.warn( "Received a retained MQTT message. Most certainly you or the home automation software integration " + - "you are using are sending the MQTT command incorrectly. Please remove the \"retained\" flag to fix this issue. Discarding.", + "you are using is sending the MQTT command incorrectly. Please remove the \"retained\" flag to fix this issue. Discarding message.", { topic: topic, message: msg @@ -273,12 +354,16 @@ class MqttController { return; } - this.subscriptions[topic](msg).then(); + this.subscriptions[topic](msg).catch(err => { + Logger.error("Error during handling of incoming MQTT message", err); + }); }); this.client.on("error", (e) => { + this.stats.connection.errors++; + if (e && e.message === "Not supported") { - Logger.info("Connected to non standard compliant MQTT Broker."); + Logger.info("Connected to non-standard-compliant MQTT Broker."); } else { Logger.error("MQTT error:", e.toString()); @@ -297,6 +382,7 @@ class MqttController { }); this.client.on("reconnect", () => { + this.stats.connection.reconnects++; Logger.info("Attempting to reconnect to MQTT broker"); }); @@ -315,6 +401,8 @@ class MqttController { async handleUncleanDisconnect() { if (this.state === HomieCommonAttributes.STATE.READY) { Logger.info("Connection to MQTT broker closed"); + + this.messageDeduplicationCache.clear(); } this.stopAutorefreshService(); @@ -371,7 +459,11 @@ class MqttController { this.client = null; this.asyncClient = null; + + this.messageDeduplicationCache.clear(); + Logger.info("Successfully disconnected from the MQTT Broker"); + this.stats.connection.disconnects++; } /** @@ -524,8 +616,22 @@ class MqttController { try { - // @ts-ignore - await this.asyncClient.subscribe(Object.keys(topics), {qos: MqttCommonAttributes.QOS.AT_LEAST_ONCE}); + for (const topic of Object.keys(topics)) { + // @ts-ignore + await this.asyncClient.subscribe({ + [topic]: { + qos: MqttCommonAttributes.QOS.AT_LEAST_ONCE + }, + /* + The resubscribe option is undocumented and thus may break in the future (2022-08-21) + It works around this bug(?): https://github.com/mqttjs/MQTT.js/issues/895 + + According to https://github.com/mqttjs/MQTT.js/issues/749#issuecomment-1002481265, using MQTTv5 also fixes the issue + We should revisit this when MQTTv5 support is stable and well-established + */ + resubscribe: true + }); + } } catch (e) { if (e.message !== "client disconnecting" && e.message !== "connection closed") { throw e; @@ -729,22 +835,21 @@ class MqttController { * @param {object} [options] * @return {Promise} */ - publish(topic, message, options) { + async publish(topic, message, options) { //@ts-ignore - if (this.client?.stream?.writableLength > 1024*1024) { //Allow for 1MiB of buffered messages + if (this.client?.stream?.writableLength > 1024 * 1024) { //Allow for 1MiB of buffered messages Logger.warn(`Stale MQTT connection detected. Dropping message for ${topic}`); - - return new Promise(resolve => { - resolve(); - }); } else if (this.asyncClient) { - return this.asyncClient.publish(topic, message, options); + //This looks like an afterthought because it is one. :( + const hasChanged = this.messageDeduplicationCache.update(topic, message); + + if (hasChanged) { + this.stats.messages.count.sent++; + this.stats.messages.bytes.sent += message.length; + return this.asyncClient.publish(topic, message, options); + } } else { Logger.warn(`Aborting publish to ${topic} since we're currently not connected to any MQTT broker`); - - return new Promise(resolve => { - resolve(); - }); } } } diff --git a/backend/lib/mqtt/capabilities/AutoEmptyDockManualTriggerCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/AutoEmptyDockManualTriggerCapabilityMqttHandle.js index d61a6cff..3cff405e 100644 --- a/backend/lib/mqtt/capabilities/AutoEmptyDockManualTriggerCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/AutoEmptyDockManualTriggerCapabilityMqttHandle.js @@ -31,4 +31,6 @@ class AutoEmptyDockManualTriggerCapabilityMqttHandle extends CapabilityMqttHandl } } +AutoEmptyDockManualTriggerCapabilityMqttHandle.OPTIONAL = false; + module.exports = AutoEmptyDockManualTriggerCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/BasicControlCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/BasicControlCapabilityMqttHandle.js index 53e5fe57..ed08d844 100644 --- a/backend/lib/mqtt/capabilities/BasicControlCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/BasicControlCapabilityMqttHandle.js @@ -2,6 +2,7 @@ const CapabilityMqttHandle = require("./CapabilityMqttHandle"); const Commands = require("../common/Commands"); const DataType = require("../homie/DataType"); const HassAnchor = require("../homeassistant/HassAnchor"); +const Logger = require("../../Logger"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); class BasicControlCapabilityMqttHandle extends CapabilityMqttHandle { @@ -42,10 +43,13 @@ class BasicControlCapabilityMqttHandle extends CapabilityMqttHandle { } } }).also((prop) => { - HassAnchor.getTopicReference(HassAnchor.REFERENCE.BASIC_CONTROL_COMMAND).post(prop.getBaseTopic() + "/set").then(); + HassAnchor.getTopicReference(HassAnchor.REFERENCE.BASIC_CONTROL_COMMAND).post(prop.getBaseTopic() + "/set").catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); })); } } +BasicControlCapabilityMqttHandle.OPTIONAL = false; module.exports = BasicControlCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/CapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/CapabilityMqttHandle.js index 6016e2ff..01889bd2 100644 --- a/backend/lib/mqtt/capabilities/CapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/CapabilityMqttHandle.js @@ -24,4 +24,6 @@ class CapabilityMqttHandle extends RobotStateNodeMqttHandle { } } +CapabilityMqttHandle.OPTIONAL = false; + module.exports = CapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/ConsumableMonitoringCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/ConsumableMonitoringCapabilityMqttHandle.js index 005c2e8f..d238fba7 100644 --- a/backend/lib/mqtt/capabilities/ConsumableMonitoringCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/ConsumableMonitoringCapabilityMqttHandle.js @@ -1,11 +1,11 @@ const CapabilityMqttHandle = require("./CapabilityMqttHandle"); -const Commands = require("../common/Commands"); const ComponentType = require("../homeassistant/ComponentType"); const DataType = require("../homie/DataType"); const EntityCategory = require("../homeassistant/EntityCategory"); const HassAnchor = require("../homeassistant/HassAnchor"); const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); +const Logger = require("../../Logger"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); const stateAttrs = require("../../entities/state/attributes"); const Unit = require("../common/Unit"); @@ -29,23 +29,6 @@ class ConsumableMonitoringCapabilityMqttHandle extends CapabilityMqttHandle { })); this.capability = options.capability; - this.registerChild( - new PropertyMqttHandle({ - parent: this, - controller: this.controller, - topicName: "refresh", - friendlyName: "Refresh consumables", - datatype: DataType.ENUM, - format: Commands.BASIC.PERFORM, - setter: async (value) => { - await this.capability.getConsumables(); - }, - helpText: "If set to `" + Commands.BASIC.PERFORM + "`, it will attempt to refresh the consumables " + - "from the robot. Note that there's no need to do it manually, consumables are refreshed " + - "automatically every 30 seconds by default.", - }) - ); - this.capability.getProperties().availableConsumables.forEach(consumable => { this.addNewConsumable( this.genConsumableTopicId(consumable.type, consumable.subType), @@ -154,6 +137,17 @@ class ConsumableMonitoringCapabilityMqttHandle extends CapabilityMqttHandle { await super.refresh(); } + onStatusSubscriberEvent() { + /* + We need to override this method as otherwise, we'd end up in an endless loop + due to refresh() triggering a consumables poll triggering a statusAttribute update + triggering a refresh() triggering a consumables poll... + */ + super.refresh().then(() => { /* intentional */ }).catch(err => { + Logger.error("Error during MqttHandle refresh", err); + }); + } + getInterestingStatusAttributes() { return [{attributeClass: stateAttrs.ConsumableStateAttribute.name}]; } @@ -168,11 +162,13 @@ const TYPE_MAPPING = Object.freeze({ const SUBTYPE_MAPPING = Object.freeze({ "main": "Main", + "secondary": "Secondary", "side_right": "Right", "side_left": "Left", "all": "", "none": "" }); +ConsumableMonitoringCapabilityMqttHandle.OPTIONAL = false; module.exports = ConsumableMonitoringCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/CurrentStatisticsCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/CurrentStatisticsCapabilityMqttHandle.js index ec9bb248..2dea72d7 100644 --- a/backend/lib/mqtt/capabilities/CurrentStatisticsCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/CurrentStatisticsCapabilityMqttHandle.js @@ -129,4 +129,6 @@ class CurrentStatisticsCapabilityMqttHandle extends CapabilityMqttHandle { } } +CurrentStatisticsCapabilityMqttHandle.OPTIONAL = false; + module.exports = CurrentStatisticsCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/GoToLocationCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/GoToLocationCapabilityMqttHandle.js index 6b1cbc08..148642d8 100644 --- a/backend/lib/mqtt/capabilities/GoToLocationCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/GoToLocationCapabilityMqttHandle.js @@ -1,9 +1,7 @@ const CapabilityMqttHandle = require("./CapabilityMqttHandle"); -const ComponentType = require("../homeassistant/ComponentType"); const DataType = require("../homie/DataType"); -const HassAnchor = require("../homeassistant/HassAnchor"); -const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); +const ValetudoGoToLocation = require("../../entities/core/ValetudoGoToLocation"); class GoToLocationCapabilityMqttHandle extends CapabilityMqttHandle { /** @@ -19,71 +17,48 @@ class GoToLocationCapabilityMqttHandle extends CapabilityMqttHandle { })); this.capability = options.capability; - this.registerChild( - new PropertyMqttHandle({ - parent: this, - controller: this.controller, - topicName: "presets", - friendlyName: "Presets", - datatype: DataType.STRING, - format: "json", - getter: async () => { - const result = this.robot.config.get("goToLocationPresets") ?? {}; - await HassAnchor.getAnchor(HassAnchor.ANCHOR.GOTO_PRESETS_LEN).post(Object.keys(result).length); + this.registerChild(new PropertyMqttHandle({ + parent: this, + controller: this.controller, + topicName: "go", + friendlyName: "Go to location", + datatype: DataType.STRING, + format: "same json as the REST interface", + setter: async (value) => { + const reqGoToLocation = JSON.parse(value); - return result; - }, - helpText: "This handle provides a set of configured Go-to-location presets as a JSON object." - }).also((prop) => { - HassAnchor.getTopicReference(HassAnchor.REFERENCE.GOTO_PRESETS).post(prop.getBaseTopic()).then(); - }) - ); - - this.registerChild( - new PropertyMqttHandle({ - parent: this, - controller: this.controller, - topicName: "go", - friendlyName: "Go to location preset", - datatype: DataType.STRING, - setter: async (value) => { - const gotoPreset = this.robot.config.get("goToLocationPresets")[value]; - - if (gotoPreset === undefined) { - throw new Error("Invalid go to location preset ID found in go payload"); + if ( + reqGoToLocation && reqGoToLocation.coordinates && + typeof reqGoToLocation.coordinates.x === "number" && + typeof reqGoToLocation.coordinates.y === "number" + ) { + await this.capability.goTo(new ValetudoGoToLocation({ + coordinates: { + x: reqGoToLocation.coordinates.x, + y: reqGoToLocation.coordinates.y + } + })); + } else { + throw new Error("Invalid go to location payload"); + } + }, + helpText: "This handle accepts a JSON object identical to the one used by the REST API.\n\n" + + "Please refer to the \"General Help\" section in Valetudo for more information.\n\n" + + "Sample payload:\n\n" + + "```json\n" + + JSON.stringify({ + coordinates: { + x: 50, + y: 50 } - - await this.capability.goTo(gotoPreset); - }, - helpText: "Use this handle to make the robot go to a configured preset location. It accepts one " + - "single preset UUID as a regular string." - }) - ); - - this.controller.withHass((hass) => { - this.attachHomeAssistantComponent( - new InLineHassComponent({ - hass: hass, - robot: this.robot, - name: this.capability.getType(), - friendlyName: "GoTo Locations", - componentType: ComponentType.SENSOR, - baseTopicReference: HassAnchor.getTopicReference(HassAnchor.REFERENCE.HASS_GOTO_LOCATION_STATE), - autoconf: { - state_topic: HassAnchor.getTopicReference(HassAnchor.REFERENCE.HASS_GOTO_LOCATION_STATE), - icon: "mdi:map-marker-outline", - json_attributes_topic: HassAnchor.getTopicReference(HassAnchor.REFERENCE.GOTO_PRESETS), - json_attributes_template: "{{ value }}" - }, - topics: { - "": HassAnchor.getAnchor(HassAnchor.ANCHOR.GOTO_PRESETS_LEN) - } - }) - ); - }); + }, null, 2) + + "\n```" + })); } } +GoToLocationCapabilityMqttHandle.OPTIONAL = false; + module.exports = GoToLocationCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/LocateCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/LocateCapabilityMqttHandle.js index cdaa6e7e..95a4158d 100644 --- a/backend/lib/mqtt/capabilities/LocateCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/LocateCapabilityMqttHandle.js @@ -31,4 +31,6 @@ class LocateCapabilityMqttHandle extends CapabilityMqttHandle { } } +LocateCapabilityMqttHandle.OPTIONAL = false; + module.exports = LocateCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/MapSegmentationCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/MapSegmentationCapabilityMqttHandle.js index 95ba7647..7445bb27 100644 --- a/backend/lib/mqtt/capabilities/MapSegmentationCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/MapSegmentationCapabilityMqttHandle.js @@ -56,20 +56,23 @@ class MapSegmentationCapabilityMqttHandle extends CapabilityMqttHandle { } }, helpText: "This handle accepts a JSON object identical to the one used by the REST API.\n\n" + + "Please refer to the \"General Help\" section in Valetudo for more information.\n\n" + "Sample payload:\n\n" + "```json\n" + - "{\n" + - " \"segment_ids\": [\n" + - " \"20\",\n"+ - " \"18\",\n"+ - " \"16\"\n"+ - " ],\n"+ - " \"iterations\": 2,\n"+ - " \"customOrder\": true\n"+ - "}\n" + - "```" + JSON.stringify({ + segment_ids: [ + "20", + "18", + "16" + ], + iterations: 2, + customOrder: true + }, null, 2) + + "\n```" })); } } +MapSegmentationCapabilityMqttHandle.OPTIONAL = false; + module.exports = MapSegmentationCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/PresetSelectionCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/PresetSelectionCapabilityMqttHandle.js index 27cf1bfb..f320d709 100644 --- a/backend/lib/mqtt/capabilities/PresetSelectionCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/PresetSelectionCapabilityMqttHandle.js @@ -7,6 +7,7 @@ const DataType = require("../homie/DataType"); const EntityCategory = require("../homeassistant/EntityCategory"); const HassAnchor = require("../homeassistant/HassAnchor"); const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); +const Logger = require("../../Logger"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); const stateAttrs = require("../../entities/state/attributes"); @@ -71,8 +72,12 @@ class PresetSelectionCapabilityMqttHandle extends CapabilityMqttHandle { if (options.capability.getType() === capabilities.FanSpeedControlCapability.TYPE) { // Sent as a topic reference since this is used for the autoconfig - HassAnchor.getTopicReference(HassAnchor.REFERENCE.FAN_SPEED_PRESETS).post(this.capability.getPresets()).then(); - HassAnchor.getTopicReference(HassAnchor.REFERENCE.FAN_SPEED_SET).post(prop.getBaseTopic() + "/set").then(); + HassAnchor.getTopicReference(HassAnchor.REFERENCE.FAN_SPEED_PRESETS).post(this.capability.getPresets()).catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); + HassAnchor.getTopicReference(HassAnchor.REFERENCE.FAN_SPEED_SET).post(prop.getBaseTopic() + "/set").catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); } else if (options.capability.getType() === capabilities.WaterUsageControlCapability.TYPE) { this.controller.withHass((hass) => { @@ -83,7 +88,6 @@ class PresetSelectionCapabilityMqttHandle extends CapabilityMqttHandle { name: capabilities.WaterUsageControlCapability.TYPE, friendlyName: CAPABILITIES_TO_FRIENDLY_NAME_MAPPING[capabilities.WaterUsageControlCapability.TYPE], componentType: ComponentType.SELECT, - baseTopicReference: HassAnchor.getTopicReference(HassAnchor.REFERENCE.HASS_WATER_GRADE_PRESETS), autoconf: { state_topic: prop.getBaseTopic(), value_template: "{{ value }}", @@ -96,6 +100,27 @@ class PresetSelectionCapabilityMqttHandle extends CapabilityMqttHandle { ); }); + } else if (options.capability.getType() === capabilities.OperationModeControlCapability.TYPE) { + this.controller.withHass((hass) => { + prop.attachHomeAssistantComponent( + new InLineHassComponent({ + hass: hass, + robot: this.robot, + name: capabilities.OperationModeControlCapability.TYPE, + friendlyName: CAPABILITIES_TO_FRIENDLY_NAME_MAPPING[capabilities.OperationModeControlCapability.TYPE], + componentType: ComponentType.SELECT, + autoconf: { + state_topic: prop.getBaseTopic(), + value_template: "{{ value }}", + command_topic: prop.getBaseTopic() + "/set", + options: this.capability.getPresets(), + icon: "mdi:developer-board", + entity_category: EntityCategory.CONFIG, + } + }) + ); + }); + } }) ); @@ -109,6 +134,7 @@ class PresetSelectionCapabilityMqttHandle extends CapabilityMqttHandle { const CAPABILITIES_TO_FRIENDLY_NAME_MAPPING = { [capabilities.FanSpeedControlCapability.TYPE]: "Fan speed", [capabilities.WaterUsageControlCapability.TYPE]: "Water grade", + [capabilities.OperationModeControlCapability.TYPE]: "Operation mode", }; const CAPABILITIES_TO_STATE_ATTR_MAPPING = { @@ -120,6 +146,10 @@ const CAPABILITIES_TO_STATE_ATTR_MAPPING = { attributeClass: stateAttrs.PresetSelectionStateAttribute.name, attributeType: stateAttrs.PresetSelectionStateAttribute.TYPE.WATER_GRADE }, + [capabilities.OperationModeControlCapability.TYPE]: { + attributeClass: stateAttrs.PresetSelectionStateAttribute.name, + attributeType: stateAttrs.PresetSelectionStateAttribute.TYPE.OPERATION_MODE + }, }; module.exports = PresetSelectionCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/SpeakerVolumeControlCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/SpeakerVolumeControlCapabilityMqttHandle.js new file mode 100644 index 00000000..cc35e639 --- /dev/null +++ b/backend/lib/mqtt/capabilities/SpeakerVolumeControlCapabilityMqttHandle.js @@ -0,0 +1,76 @@ +const CapabilityMqttHandle = require("./CapabilityMqttHandle"); + +const capabilities = require("../../core/capabilities"); +const ComponentType = require("../homeassistant/ComponentType"); +const DataType = require("../homie/DataType"); +const EntityCategory = require("../homeassistant/EntityCategory"); +const HassAnchor = require("../homeassistant/HassAnchor"); +const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); +const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); + +class SpeakerVolumeControlCapabilityMqttHandle extends CapabilityMqttHandle { + /** + * @param {object} options + * @param {import("../handles/RobotMqttHandle")} options.parent + * @param {import("../MqttController")} options.controller MqttController instance + * @param {import("../../core/ValetudoRobot")} options.robot + * @param {import("../../core/capabilities/SpeakerVolumeControlCapability")} options.capability + */ + constructor(options) { + super(Object.assign(options, { + friendlyName: "Speaker volume control" + })); + this.capability = options.capability; + + this.registerChild( + new PropertyMqttHandle({ + parent: this, + controller: this.controller, + topicName: "value", + friendlyName: "Speaker volume", + datatype: DataType.INTEGER, + format: "0:100", + setter: async (value) => { + if (Number.isInteger(value) && value >= 0 && value <= 100) { + await this.capability.setVolume(value); + } else { + throw new Error("Invalid speaker volume"); + } + }, + getter: async () => { + return HassAnchor.getAnchor(HassAnchor.ANCHOR.SPEAKER_VOLUME).getValue(); + }, + helpText: "This handle returns the current speaker volume" + }).also((prop) => { + this.controller.withHass((hass) => { + prop.attachHomeAssistantComponent( + new InLineHassComponent({ + hass: hass, + robot: this.robot, + name: capabilities.SpeakerVolumeControlCapability.TYPE, + friendlyName: "Speaker volume", + componentType: ComponentType.NUMBER, + autoconf: { + state_topic: prop.getBaseTopic(), + command_topic: prop.getBaseTopic() + "/set", + icon: "mdi:volume-source", + entity_category: EntityCategory.CONFIG, + } + }) + ); + }); + }) + ); + } + + async refresh() { + const currentVolume = await this.capability.getVolume(); + await HassAnchor.getAnchor(HassAnchor.ANCHOR.SPEAKER_VOLUME).post(currentVolume); + + await super.refresh(); + } +} + +SpeakerVolumeControlCapabilityMqttHandle.OPTIONAL = true; + +module.exports = SpeakerVolumeControlCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/WifiConfigurationCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/WifiConfigurationCapabilityMqttHandle.js index 44201821..917a59b5 100644 --- a/backend/lib/mqtt/capabilities/WifiConfigurationCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/WifiConfigurationCapabilityMqttHandle.js @@ -134,4 +134,6 @@ class WifiConfigurationCapabilityMqttHandle extends CapabilityMqttHandle { } } +WifiConfigurationCapabilityMqttHandle.OPTIONAL = false; + module.exports = WifiConfigurationCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/ZoneCleaningCapabilityMqttHandle.js b/backend/lib/mqtt/capabilities/ZoneCleaningCapabilityMqttHandle.js index c74ae4fd..79f36c3e 100644 --- a/backend/lib/mqtt/capabilities/ZoneCleaningCapabilityMqttHandle.js +++ b/backend/lib/mqtt/capabilities/ZoneCleaningCapabilityMqttHandle.js @@ -1,9 +1,7 @@ const CapabilityMqttHandle = require("./CapabilityMqttHandle"); -const ComponentType = require("../homeassistant/ComponentType"); const DataType = require("../homie/DataType"); -const HassAnchor = require("../homeassistant/HassAnchor"); -const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); +const ValetudoZone = require("../../entities/core/ValetudoZone"); class ZoneCleaningCapabilityMqttHandle extends CapabilityMqttHandle { /** @@ -19,74 +17,84 @@ class ZoneCleaningCapabilityMqttHandle extends CapabilityMqttHandle { })); this.capability = options.capability; - this.registerChild( - new PropertyMqttHandle({ - parent: this, - controller: this.controller, - topicName: "presets", - friendlyName: "Presets", - datatype: DataType.STRING, - format: "json", - getter: async () => { - const result = this.robot.config.get("zonePresets") ?? {}; - await HassAnchor.getAnchor(HassAnchor.ANCHOR.ZONE_PRESETS_LEN).post(Object.keys(result).length); - return result; - }, - helpText: "This handles provides the list of configured zone presets as a JSON object." - }).also((prop) => { - HassAnchor.getTopicReference(HassAnchor.REFERENCE.ZONE_PRESETS).post(prop.getBaseTopic()).then(); - }) - ); + this.registerChild(new PropertyMqttHandle({ + parent: this, + controller: this.controller, + topicName: "start", + friendlyName: "Start zoned cleaning", + datatype: DataType.STRING, + format: "same json as the REST interface", + setter: async (value) => { + const req = JSON.parse(value); - this.registerChild( - new PropertyMqttHandle({ - parent: this, - controller: this.controller, - topicName: "start", - friendlyName: "Start zone preset", - datatype: DataType.STRING, - format: "json", - setter: async (value) => { - const loadedZone = this.robot.config.get("zonePresets")[value]; - if (!loadedZone) { - throw new Error("Error while starting zone cleanup. There is no zone preset with id " + value); - } - try { - await this.capability.start(loadedZone.zones); - } catch (e) { - throw new Error(`Error while starting zone cleaning for zone_id ${value}: ${e}`); - } - }, - helpText: "This handle accepts a zone preset **UUID** to start. You can retrieve them from the `/presets` handle.\n\n" + - "Sample value:\n" + - "`25f6b7fe-0a28-477d-a1af-937ad91b2df4`\n" - }) - ); + if (Array.isArray(req?.zones)) { + await this.capability.start(req.zones.map(z => { + if (!(z.points)) { + throw new Error("Invalid Zone"); + } - this.controller.withHass((hass) => { - this.attachHomeAssistantComponent( - new InLineHassComponent({ - hass: hass, - robot: this.robot, - name: this.capability.getType(), - friendlyName: "Zone Presets", - componentType: ComponentType.SENSOR, - baseTopicReference: HassAnchor.getTopicReference(HassAnchor.REFERENCE.HAZZ_ZONE_CLEANING_STATE), - autoconf: { - state_topic: HassAnchor.getTopicReference(HassAnchor.REFERENCE.HAZZ_ZONE_CLEANING_STATE), - icon: "mdi:square-outline", - json_attributes_topic: HassAnchor.getTopicReference(HassAnchor.REFERENCE.ZONE_PRESETS), - json_attributes_template: "{{ value }}" - }, - topics: { - "": HassAnchor.getAnchor(HassAnchor.ANCHOR.ZONE_PRESETS_LEN) - } - }) - ); - }); + return new ValetudoZone({ + points: { + pA: { + x: z.points.pA?.x, + y: z.points.pA?.y, + }, + pB: { + x: z.points.pB?.x, + y: z.points.pB?.y, + }, + pC: { + x: z.points.pC?.x, + y: z.points.pC?.y, + }, + pD: { + x: z.points.pD?.x, + y: z.points.pD?.y, + }, + }, + iterations: z.iterations + }); + })); + } else { + throw new Error("Invalid zone cleaning payload"); + } + }, + helpText: "This handle accepts a JSON object identical to the one used by the REST API.\n\n" + + "Please refer to the \"General Help\" section in Valetudo for more information.\n\n" + + "Sample payload:\n\n" + + "```json\n" + + JSON.stringify({ + zones: [ + { + iterations: 1, + points: { + pA: { + x: 50, + y: 50 + }, + pB: { + x: 100, + y: 50 + }, + pC: { + x: 100, + y: 100 + }, + pD: { + x: 50, + y: 100 + } + } + } + ] + }, null, 2) + + "\n```" + })); } } +ZoneCleaningCapabilityMqttHandle.OPTIONAL = false; + module.exports = ZoneCleaningCapabilityMqttHandle; diff --git a/backend/lib/mqtt/capabilities/index.js b/backend/lib/mqtt/capabilities/index.js index 8f348ce7..3e1128d8 100644 --- a/backend/lib/mqtt/capabilities/index.js +++ b/backend/lib/mqtt/capabilities/index.js @@ -8,6 +8,7 @@ module.exports = { LocateCapabilityMqttHandle: require("./LocateCapabilityMqttHandle"), MapSegmentationCapabilityMqttHandle: require("./MapSegmentationCapabilityMqttHandle"), PresetSelectionCapabilityMqttHandle: require("./PresetSelectionCapabilityMqttHandle"), + SpeakerVolumeControlCapabilityMqttHandle: require("./SpeakerVolumeControlCapabilityMqttHandle"), WifiConfigurationCapabilityMqttHandle: require("./WifiConfigurationCapabilityMqttHandle"), ZoneCleaningCapabilityMqttHandle: require("./ZoneCleaningCapabilityMqttHandle") }; diff --git a/backend/lib/mqtt/handles/HandleMappings.js b/backend/lib/mqtt/handles/HandleMappings.js index f3fd446b..5b356bae 100644 --- a/backend/lib/mqtt/handles/HandleMappings.js +++ b/backend/lib/mqtt/handles/HandleMappings.js @@ -11,10 +11,12 @@ const CAPABILITY_TYPE_TO_HANDLE_MAPPING = { [capabilities.LocateCapability.TYPE]: capabilityHandles.LocateCapabilityMqttHandle, [capabilities.MapSegmentationCapability.TYPE]: capabilityHandles.MapSegmentationCapabilityMqttHandle, [capabilities.WaterUsageControlCapability.TYPE]: capabilityHandles.PresetSelectionCapabilityMqttHandle, + [capabilities.OperationModeControlCapability.TYPE]: capabilityHandles.PresetSelectionCapabilityMqttHandle, [capabilities.WifiConfigurationCapability.TYPE]: capabilityHandles.WifiConfigurationCapabilityMqttHandle, [capabilities.ZoneCleaningCapability.TYPE]: capabilityHandles.ZoneCleaningCapabilityMqttHandle, [capabilities.AutoEmptyDockManualTriggerCapability.TYPE]: capabilityHandles.AutoEmptyDockManualTriggerCapabilityMqttHandle, - [capabilities.CurrentStatisticsCapability.TYPE]: capabilityHandles.CurrentStatisticsCapabilityMqttHandle + [capabilities.CurrentStatisticsCapability.TYPE]: capabilityHandles.CurrentStatisticsCapabilityMqttHandle, + [capabilities.SpeakerVolumeControlCapability.TYPE]: capabilityHandles.SpeakerVolumeControlCapabilityMqttHandle }; const STATUS_ATTR_TO_HANDLE_MAPPING = [ diff --git a/backend/lib/mqtt/handles/MapNodeMqttHandle.js b/backend/lib/mqtt/handles/MapNodeMqttHandle.js index 60bc762c..302dcbdf 100644 --- a/backend/lib/mqtt/handles/MapNodeMqttHandle.js +++ b/backend/lib/mqtt/handles/MapNodeMqttHandle.js @@ -118,14 +118,14 @@ class MapNodeMqttHandle extends NodeMqttHandle { new PropertyMqttHandle({ parent: this, controller: this.controller, - topicName: "map-data-hass-hack", - friendlyName: "Raw map data with Home Assistant hack", + topicName: "map-data-hass", + friendlyName: "Raw map data for Home Assistant", datatype: DataType.STRING, getter: async () => { return this.getMapData(true); }, helpText: "This handle is added automatically if Home Assistant autodiscovery is enabled. It " + - "provides a map embedded in a PNG image that recommends installing the Valetudo Lovelace card. " + "provides a map embedded in a PNG image that recommends installing the Valetudo Lovelace card." }).also((prop) => { prop.attachHomeAssistantComponent( new InLineHassComponent({ @@ -160,16 +160,18 @@ class MapNodeMqttHandle extends NodeMqttHandle { */ onMapUpdated() { if (this.controller.isInitialized()) { - this.refresh().then(); + this.refresh().catch(err => { + Logger.error("Error during MQTT handle refresh", err); + }); } } /** * @private - * @param {boolean} mapHack + * @param {boolean} wrapInPng * @return {Promise} */ - async getMapData(mapHack) { + async getMapData(wrapInPng) { if (this.robot.state.map === null || !(this.controller.currentConfig.customizations.provideMapData ?? true) || !this.controller.isInitialized()) { return null; } @@ -183,26 +185,26 @@ class MapNodeMqttHandle extends NodeMqttHandle { let payload; - if (mapHack) { + if (wrapInPng) { const length = Buffer.alloc(4); const checksum = Buffer.alloc(4); const textChunkData = Buffer.concat([ - HOMEASSISTANT_MAP_HACK.TEXT_CHUNK_TYPE, - HOMEASSISTANT_MAP_HACK.TEXT_CHUNK_METADATA, + PNG_WRAPPER.TEXT_CHUNK_TYPE, + PNG_WRAPPER.TEXT_CHUNK_METADATA, buf ]); - length.writeInt32BE(HOMEASSISTANT_MAP_HACK.TEXT_CHUNK_METADATA.length + buf.length, 0); + length.writeInt32BE(PNG_WRAPPER.TEXT_CHUNK_METADATA.length + buf.length, 0); checksum.writeUInt32BE(crc.crc32(textChunkData), 0); payload = Buffer.concat([ - HOMEASSISTANT_MAP_HACK.IMAGE_WITHOUT_END_CHUNK, + PNG_WRAPPER.IMAGE_WITHOUT_END_CHUNK, length, textChunkData, checksum, - HOMEASSISTANT_MAP_HACK.END_CHUNK + PNG_WRAPPER.END_CHUNK ]); } else { payload = buf; @@ -224,13 +226,13 @@ class MapNodeMqttHandle extends NodeMqttHandle { } -const HOMEASSISTANT_MAP_HACK = { +const PNG_WRAPPER = { TEXT_CHUNK_TYPE: Buffer.from("zTXt"), TEXT_CHUNK_METADATA: Buffer.from("ValetudoMap\0\0"), - IMAGE: fs.readFileSync(path.join(__dirname, "../../res/valetudo_home_assistant_mqtt_camera_hack.png")) + IMAGE: fs.readFileSync(path.join(__dirname, "../../res/valetudo_home_assistant_mqtt_wrapper.png")) }; -HOMEASSISTANT_MAP_HACK.IMAGE_WITHOUT_END_CHUNK = HOMEASSISTANT_MAP_HACK.IMAGE.slice(0, HOMEASSISTANT_MAP_HACK.IMAGE.length - 12); +PNG_WRAPPER.IMAGE_WITHOUT_END_CHUNK = PNG_WRAPPER.IMAGE.slice(0, PNG_WRAPPER.IMAGE.length - 12); //The PNG IEND chunk is always the last chunk and consists of a 4-byte length, the 4-byte chunk type, 0-byte chunk data and a 4-byte crc -HOMEASSISTANT_MAP_HACK.END_CHUNK = HOMEASSISTANT_MAP_HACK.IMAGE.slice(HOMEASSISTANT_MAP_HACK.IMAGE.length - 12); +PNG_WRAPPER.END_CHUNK = PNG_WRAPPER.IMAGE.slice(PNG_WRAPPER.IMAGE.length - 12); module.exports = MapNodeMqttHandle; diff --git a/backend/lib/mqtt/handles/MqttHandle.js b/backend/lib/mqtt/handles/MqttHandle.js index ceaa60b0..f75d0ab8 100644 --- a/backend/lib/mqtt/handles/MqttHandle.js +++ b/backend/lib/mqtt/handles/MqttHandle.js @@ -18,7 +18,7 @@ class MqttHandle { * @param {import("../MqttController")} options.controller MqttController instance * @param {boolean} [options.gettable] Whether this handle's root topic can be published, Default false * @param {boolean} [options.settable] Whether this handle's /set topic should be subscribed to. Default false - * @param {string} [options.datatype] Data type for this handle, if gettable/settable + * @param {DataType} [options.datatype] Data type for this handle, if gettable/settable * @param {string} [options.format] Restrictions or options based on the given datatype * @param {boolean} [options.retained] Whether to retain this property, default true * @param {string} [options.helpText] Optional help message to be included in the documentation diff --git a/backend/lib/mqtt/handles/RobotMqttHandle.js b/backend/lib/mqtt/handles/RobotMqttHandle.js index f66d9944..8301c892 100644 --- a/backend/lib/mqtt/handles/RobotMqttHandle.js +++ b/backend/lib/mqtt/handles/RobotMqttHandle.js @@ -18,6 +18,7 @@ class RobotMqttHandle extends MqttHandle { * @param {string} options.baseTopic Base topic for Valetudo * @param {string} options.topicName Topic identifier for this robot * @param {string} options.friendlyName Friendly name for this robot + * @param {Array} options.optionalExposedCapabilities */ constructor(options) { super(options); @@ -35,8 +36,10 @@ class RobotMqttHandle extends MqttHandle { // Attach all available capabilities to self for (const [type, capability] of Object.entries(this.robot.capabilities)) { - if (CAPABILITY_TYPE_TO_HANDLE_MAPPING[type] !== undefined) { - this.registerChild(new CAPABILITY_TYPE_TO_HANDLE_MAPPING[type]({ + const handle = CAPABILITY_TYPE_TO_HANDLE_MAPPING[type]; + + if (handle !== undefined && (handle.OPTIONAL !== true || options.optionalExposedCapabilities.includes(type))) { + this.registerChild(new handle({ parent: this, capability: capability, controller: this.controller, @@ -45,9 +48,11 @@ class RobotMqttHandle extends MqttHandle { } } - // Subscribe to all available status attributes. Once we receive an event we will attach the respective handle. + // Subscribe to all available status attributes. Once we receive an event, we will attach the respective handle. this.statusSubscriber = new CallbackAttributeSubscriber((eventType, attribute) => { - this.onStatusAttributeEvent(eventType, attribute).then(); + this.onStatusAttributeEvent(eventType, attribute).catch(err => { + Logger.error("Error in onStatusAttributeEvent", err); + }); }); for (const item of STATUS_ATTR_TO_HANDLE_MAPPING) { diff --git a/backend/lib/mqtt/handles/RobotStateNodeMqttHandle.js b/backend/lib/mqtt/handles/RobotStateNodeMqttHandle.js index 004d8945..5264df41 100644 --- a/backend/lib/mqtt/handles/RobotStateNodeMqttHandle.js +++ b/backend/lib/mqtt/handles/RobotStateNodeMqttHandle.js @@ -1,4 +1,5 @@ const CallbackAttributeSubscriber = require("../../entities/CallbackAttributeSubscriber"); +const Logger = require("../../Logger"); const NodeMqttHandle = require("./NodeMqttHandle"); /** @@ -48,20 +49,9 @@ class RobotStateNodeMqttHandle extends NodeMqttHandle { * @param {import("../../entities/Attribute")} [previousAttribute] */ onStatusSubscriberEvent(eventType, attribute, previousAttribute) { - if (this.refreshRequired(eventType, attribute, previousAttribute)) { - this.refresh().then(); - } - } - - /** - * - * @param {string} eventType - * @param {import("../../entities/Attribute")} attribute - * @param {import("../../entities/Attribute")} [previousAttribute] - * @return {boolean} - */ - refreshRequired(eventType, attribute, previousAttribute) { - return !(eventType === "change" && previousAttribute && attribute.equals(previousAttribute)); + this.refresh().then(() => { /* intentional */ }).catch(err => { + Logger.error("Error during MqttHandle refresh", err); + }); } /** diff --git a/backend/lib/mqtt/homeassistant/ComponentType.js b/backend/lib/mqtt/homeassistant/ComponentType.js index 1cace559..df272795 100644 --- a/backend/lib/mqtt/homeassistant/ComponentType.js +++ b/backend/lib/mqtt/homeassistant/ComponentType.js @@ -14,6 +14,7 @@ const ComponentType = Object.freeze({ HVAC: "climate", LIGHT: "light", LOCK: "lock", + NUMBER: "number", SCENE: "scene", SELECT: "select", SENSOR: "sensor", diff --git a/backend/lib/mqtt/homeassistant/HassAnchor.js b/backend/lib/mqtt/homeassistant/HassAnchor.js index a7b078f8..86adbead 100644 --- a/backend/lib/mqtt/homeassistant/HassAnchor.js +++ b/backend/lib/mqtt/homeassistant/HassAnchor.js @@ -209,14 +209,13 @@ HassAnchor.ANCHOR = Object.freeze({ CURRENT_STATISTICS_TIME: "current_statistics_time", CURRENT_STATISTICS_AREA: "current_statistics_area", FAN_SPEED: "fan_speed", - GOTO_PRESETS_LEN: "goto_presets_len", MAP_SEGMENTS_LEN: "map_segments_len", VACUUM_STATE: "vacuum_state", WIFI_IPS: "wifi_ips", WIFI_FREQUENCY: "wifi_freq", WIFI_SIGNAL: "wifi_signal", WIFI_SSID: "wifi_ssid", - ZONE_PRESETS_LEN: "zone_presets_len", + SPEAKER_VOLUME: "speaker_volume", }); HassAnchor.REFERENCE = Object.freeze({ @@ -224,14 +223,11 @@ HassAnchor.REFERENCE = Object.freeze({ BASIC_CONTROL_COMMAND: "basic_control_command", FAN_SPEED_SET: "fan_speed_set", FAN_SPEED_PRESETS: "fan_speed_presets", // Actually contains the presets, not a topic - GOTO_PRESETS: "goto_presets", - ZONE_PRESETS: "zone_presets", + ERROR_STATE_DESCRIPTION: "error_state_description", + VALETUDO_ROBOT_ERROR: "valetudo_robot_error", HASS_CONSUMABLE_STATE: "hass_consumable_state_", - HASS_GOTO_LOCATION_STATE: "hass_goto_location_state", HASS_MAP_SEGMENTS_STATE: "hass_map_segments_state", - HASS_WATER_GRADE_PRESETS: "hass_water_grade_presets", HASS_WIFI_CONFIG_ATTRS: "hass_wifi_config_attrs", - HAZZ_ZONE_CLEANING_STATE: "hass_zone_cleaning_state", }); module.exports = HassAnchor; diff --git a/backend/lib/mqtt/homeassistant/HassController.js b/backend/lib/mqtt/homeassistant/HassController.js index c49c1750..b83cf9cc 100644 --- a/backend/lib/mqtt/homeassistant/HassController.js +++ b/backend/lib/mqtt/homeassistant/HassController.js @@ -1,5 +1,5 @@ const MqttCommonAttributes = require("../MqttCommonAttributes"); -const Tools = require("../../Tools"); +const Tools = require("../../utils/Tools"); /** * This class is the main controller for all Hass components. Components are preferentially registered to the MQTT diff --git a/backend/lib/mqtt/homeassistant/components/InLineHassComponent.js b/backend/lib/mqtt/homeassistant/components/InLineHassComponent.js index 156e9f8f..71ac57e0 100644 --- a/backend/lib/mqtt/homeassistant/components/InLineHassComponent.js +++ b/backend/lib/mqtt/homeassistant/components/InLineHassComponent.js @@ -1,4 +1,5 @@ const HassComponent = require("./HassComponent"); +const Logger = require("../../../Logger"); class InLineHassComponent extends HassComponent { /** @@ -23,7 +24,9 @@ class InLineHassComponent extends HassComponent { this.topics = options.topics ?? null; if (options.baseTopicReference) { - options.baseTopicReference.post(this.getBaseTopic()).then(); + options.baseTopicReference.post(this.getBaseTopic()).catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); } } diff --git a/backend/lib/mqtt/status/AttachmentStateMqttHandle.js b/backend/lib/mqtt/status/AttachmentStateMqttHandle.js index 0d9fce8d..b8790cb1 100644 --- a/backend/lib/mqtt/status/AttachmentStateMqttHandle.js +++ b/backend/lib/mqtt/status/AttachmentStateMqttHandle.js @@ -1,4 +1,7 @@ +const ComponentType = require("../homeassistant/ComponentType"); const DataType = require("../homie/DataType"); +const EntityCategory = require("../homeassistant/EntityCategory"); +const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); const RobotStateNodeMqttHandle = require("../handles/RobotStateNodeMqttHandle"); const stateAttrs = require("../../entities/state/attributes"); @@ -17,7 +20,7 @@ class AttachmentStateMqttHandle extends RobotStateNodeMqttHandle { type: "Status" })); - for (const attachment of Object.values(stateAttrs.AttachmentStateAttribute.TYPE)) { + for (const attachment of options.robot.getModelDetails().supportedAttachments) { this.registerChild(new PropertyMqttHandle({ parent: this, controller: this.controller, @@ -27,9 +30,25 @@ class AttachmentStateMqttHandle extends RobotStateNodeMqttHandle { getter: async () => { return this.isAttached(attachment); }, - helpText: "This handle reports whether the " + ATTACHMENT_FRIENDLY_NAME[attachment].toLowerCase() + - " is installed. Attachments not compatible with your robot may be included (but set to `false`)" + - " and you can safely ignore them." + helpText: `This handle reports whether the ${ATTACHMENT_FRIENDLY_NAME[attachment].toLowerCase()} attachment is installed.` + }).also((prop) => { + this.controller.withHass((hass => { + prop.attachHomeAssistantComponent( + new InLineHassComponent({ + hass: hass, + robot: this.robot, + name: `${attachment}_attachment`, + friendlyName: `${ATTACHMENT_FRIENDLY_NAME[attachment]} attachment`, + componentType: ComponentType.BINARY_SENSOR, + autoconf: { + state_topic: prop.getBaseTopic(), + payload_off: "false", + payload_on: "true", + entity_category: EntityCategory.DIAGNOSTIC + } + }) + ); + })); })); } } diff --git a/backend/lib/mqtt/status/BatteryStateMqttHandle.js b/backend/lib/mqtt/status/BatteryStateMqttHandle.js index 306bfa0b..4c688a5c 100644 --- a/backend/lib/mqtt/status/BatteryStateMqttHandle.js +++ b/backend/lib/mqtt/status/BatteryStateMqttHandle.js @@ -1,5 +1,6 @@ const DataType = require("../homie/DataType"); const HassAnchor = require("../homeassistant/HassAnchor"); +const Logger = require("../../Logger"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); const RobotStateNodeMqttHandle = require("../handles/RobotStateNodeMqttHandle"); const stateAttrs = require("../../entities/state/attributes"); @@ -32,7 +33,9 @@ class BatteryStateMqttHandle extends RobotStateNodeMqttHandle { return null; } - HassAnchor.getAnchor(HassAnchor.ANCHOR.BATTERY_LEVEL).post(batteryState.level).then(); + HassAnchor.getAnchor(HassAnchor.ANCHOR.BATTERY_LEVEL).post(batteryState.level).catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); return batteryState.level; } diff --git a/backend/lib/mqtt/status/StatusStateMqttHandle.js b/backend/lib/mqtt/status/StatusStateMqttHandle.js index 32581733..fc7cca8b 100644 --- a/backend/lib/mqtt/status/StatusStateMqttHandle.js +++ b/backend/lib/mqtt/status/StatusStateMqttHandle.js @@ -3,9 +3,11 @@ const DataType = require("../homie/DataType"); const EntityCategory = require("../homeassistant/EntityCategory"); const HassAnchor = require("../homeassistant/HassAnchor"); const InLineHassComponent = require("../homeassistant/components/InLineHassComponent"); +const Logger = require("../../Logger"); const PropertyMqttHandle = require("../handles/PropertyMqttHandle"); const RobotStateNodeMqttHandle = require("../handles/RobotStateNodeMqttHandle"); const stateAttrs = require("../../entities/state/attributes"); +const ValetudoRobotError = require("../../entities/core/ValetudoRobotError"); class StatusStateMqttHandle extends RobotStateNodeMqttHandle { /** @@ -59,38 +61,84 @@ class StatusStateMqttHandle extends RobotStateNodeMqttHandle { this.registerChild(new PropertyMqttHandle({ parent: this, controller: this.controller, - topicName: "error", + topicName: "error_description", friendlyName: "Error description", datatype: DataType.STRING, getter: async () => { const statusState = this.robot.state.getFirstMatchingAttribute(this.getInterestingStatusAttributes()[0]); + if (statusState === null) { return null; - } - if (statusState.value !== stateAttrs.StatusStateAttribute.VALUE.ERROR) { + } else if (statusState.value !== stateAttrs.StatusStateAttribute.VALUE.ERROR) { return ""; // Clear error + } else { + return statusState.error?.message ?? null; } - return statusState.metaData.error_description ?? null; }, helpText: "The error description will only be populated when the robot reports an error. Errors in " + "Valetudo not reported by the robot won't be sent here." }).also((prop) => { - this.controller.withHass((hass => { - prop.attachHomeAssistantComponent( - new InLineHassComponent({ - hass: hass, - robot: this.robot, - name: "error", - friendlyName: "Error description", - componentType: ComponentType.SENSOR, - autoconf: { - state_topic: prop.getBaseTopic(), - icon: "mdi:alert", - entity_category: EntityCategory.DIAGNOSTIC - } - }) - ); - })); + HassAnchor.getTopicReference(HassAnchor.REFERENCE.ERROR_STATE_DESCRIPTION).post(prop.getBaseTopic()).catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); + })); + + this.registerChild( + new PropertyMqttHandle({ + parent: this, + controller: this.controller, + topicName: "error", + friendlyName: "Robot Error", + datatype: DataType.STRING, + format: "json", + getter: async () => { + const statusState = this.robot.state.getFirstMatchingAttribute(this.getInterestingStatusAttributes()[0]); + let value; + + if (statusState?.value === stateAttrs.StatusStateAttribute.VALUE.ERROR) { + value = statusState.error; + } else { + value = new ValetudoRobotError({ + severity: { + kind: ValetudoRobotError.SEVERITY_KIND.NONE, + level: ValetudoRobotError.SEVERITY_LEVEL.NONE + }, + subsystem: ValetudoRobotError.SUBSYSTEM.NONE, + message: "", + vendorErrorCode: "", + }); + } + + return { + severity: value.severity, + subsystem: value.subsystem, + message: value.message + }; + }, + helpText: "This property contains the current ValetudoRobotError (if any)" + }).also((prop) => { + HassAnchor.getTopicReference(HassAnchor.REFERENCE.VALETUDO_ROBOT_ERROR).post(prop.getBaseTopic()).catch(err => { + Logger.error("Error while posting value to HassAnchor", err); + }); + }) + ); + + this.controller.withHass((hass => { + this.attachHomeAssistantComponent( + new InLineHassComponent({ + hass: hass, + robot: this.robot, + name: "error", + friendlyName: "Error", + componentType: ComponentType.SENSOR, + autoconf: { + state_topic: HassAnchor.getTopicReference(HassAnchor.REFERENCE.ERROR_STATE_DESCRIPTION), + icon: "mdi:alert", + entity_category: EntityCategory.DIAGNOSTIC, + json_attributes_topic: HassAnchor.getTopicReference(HassAnchor.REFERENCE.VALETUDO_ROBOT_ERROR) + } + }) + ); })); } diff --git a/backend/lib/res/default_config.json b/backend/lib/res/default_config.json index 04bc05d4..186f1209 100644 --- a/backend/lib/res/default_config.json +++ b/backend/lib/res/default_config.json @@ -15,8 +15,6 @@ }, "blockExternalAccess": true }, - "zonePresets": {}, - "goToLocationPresets": {}, "mqtt": { "enabled": false, "connection": { @@ -57,7 +55,8 @@ "customizations": { "topicPrefix": "", "provideMapData": true - } + }, + "optionalExposedCapabilities": [] }, "ntpClient": { "enabled": true, @@ -71,7 +70,7 @@ "debug": { "systemStatInterval" : false, "debugHassAnchors": false, - "storeRawUploadedMaps": false + "storeRawFDSUploads": false }, "networkAdvertisement": { "enabled": true diff --git a/backend/lib/res/valetudo_home_assistant_mqtt_camera_hack.png b/backend/lib/res/valetudo_home_assistant_mqtt_camera_hack.png deleted file mode 100644 index 1b450f08..00000000 Binary files a/backend/lib/res/valetudo_home_assistant_mqtt_camera_hack.png and /dev/null differ diff --git a/backend/lib/res/valetudo_home_assistant_mqtt_wrapper.png b/backend/lib/res/valetudo_home_assistant_mqtt_wrapper.png new file mode 100644 index 00000000..f5fce84c Binary files /dev/null and b/backend/lib/res/valetudo_home_assistant_mqtt_wrapper.png differ diff --git a/backend/lib/robots/MiioValetudoRobot.js b/backend/lib/robots/MiioValetudoRobot.js index f0d8a690..75455575 100644 --- a/backend/lib/robots/MiioValetudoRobot.js +++ b/backend/lib/robots/MiioValetudoRobot.js @@ -5,15 +5,19 @@ const fs = require("fs"); const http = require("http"); const os = require("os"); const path = require("path"); +const Semaphore = require("semaphore"); const Dummycloud = require("../miio/Dummycloud"); const Logger = require("../Logger"); const MiioSocket = require("../miio/MiioSocket"); const NotImplementedError = require("../core/NotImplementedError"); const RetryWrapper = require("../miio/RetryWrapper"); -const Tools = require("../Tools"); +const Tools = require("../utils/Tools"); const ValetudoRobot = require("../core/ValetudoRobot"); +const entities = require("../entities"); +const stateAttrs = entities.state.attributes; + class MiioValetudoRobot extends ValetudoRobot { /** * @@ -43,13 +47,11 @@ class MiioValetudoRobot extends ValetudoRobot { return new MiioSocket({ socket: socket, token: this.localSecret, - onMessage: () => {/* intentional default that may be overridden */}, deviceId: undefined, rinfo: {address: this.ip, port: MiioSocket.PORT}, timeout: undefined, - onConnected: undefined, name: "local", - isServerSocket: false + isCloudSocket: false }); })(), () => { @@ -65,78 +67,110 @@ class MiioValetudoRobot extends ValetudoRobot { onConnected: () => { return this.onCloudConnected(); }, - onMessage: msg => { - return this.onMessage(msg); + onIncomingCloudMessage: msg => { + return this.onIncomingCloudMessage(msg); } }); - this.mapUploadInProgress = false; + this.fdsUploadSemaphore = Semaphore(2); this.mapPollingIntervals = { default: 60, - active: this.config.get("embedded") === true && Tools.IS_LOWMEM_HOST() ? 4 : 2 + active: this.config.get("embedded") === true && Tools.IS_LOWMEM_HOST() ? 4 : 2, + error: 30 }; + this.mapPollMutex = Semaphore(1); + this.mapPollTimeout = undefined; this.expressApp = express(); - this.mapUploadServer = http.createServer(this.expressApp); + this.fdsMockServer = http.createServer(this.expressApp); - this.expressApp.put("/api/miio/map_upload_handler/:filename?", (req, res) => { - Logger.debug("Map upload started with:", { + this.expressApp.put("/api/miio/fds_upload_handler/:filename?", (req, res) => { + Logger.debug("FDS upload started with:", { query: req.query, params: req.params }); - if (!this.mapUploadInProgress) { - this.mapUploadInProgress = true; - const uploadBuffer = Buffer.allocUnsafe(parseInt(req.header("content-length"))); - let offset = 0; + this.fdsUploadSemaphore.take(() => { + const expectedSize = parseInt(req.header("content-length")); + let finished = false; - req.on("data", chunk => { - for (let i = 0; i < chunk.length; i++) { - uploadBuffer[offset] = chunk[i]; - offset++; - } - }); + if (expectedSize < MAX_UPLOAD_FILESIZE) { + let uploadTimeout = setTimeout(() => { + finished = true; - req.on("end", () => { - if (this.config.get("debug").storeRawUploadedMaps === true) { - try { - const location = path.join(os.tmpdir(), "raw_map_" + new Date().getTime()); - fs.writeFileSync(location, uploadBuffer); + res.end(); + req.socket?.destroy(); - Logger.info("Wrote uploaded raw map to " + location); - } catch (e) { - Logger.warn("Failed to store raw uploaded map.", e); + Logger.warn("FDS upload timeout", { + query: req.query, + params: req.params + }); + this.fdsUploadSemaphore.leave(); + }, 3000); + + + const uploadBuffer = Buffer.allocUnsafe(expectedSize); + let offset = 0; + + req.on("data", chunk => { + /* + We don't need a range check here, because even if content-length is shorter than + what is actually uploaded, trying to write outside a buffer like we do here + just fails silently without any breakage. Thanks javascript + */ + for (let i = 0; i < chunk.length; i++) { + uploadBuffer[offset] = chunk[i]; + offset++; } - } + }); - this.handleUploadedMapData( - uploadBuffer, - req.query, - req.params - ).catch(err => { - Logger.warn("Error while handling uploaded map data", { - query: req.query, - params: req.params, - error: err + req.on("end", () => { + clearTimeout(uploadTimeout); + + if (this.config.get("debug").storeRawFDSUploads === true) { + try { + const location = path.join(os.tmpdir(), "raw_upload_" + new Date().getTime()); + fs.writeFileSync(location, uploadBuffer); + + Logger.info("Wrote uploaded raw file to " + location); + } catch (e) { + Logger.warn("Failed to store raw file.", e); + } + } + + this.handleUploadedFDSData( + uploadBuffer, + req.query, + req.params + ).catch(err => { + Logger.warn("Error while handling uploaded map data", { + query: req.query, + params: req.params, + error: err + }); + }).finally(() => { + if (finished !== true) { + res.sendStatus(200); + this.fdsUploadSemaphore.leave(); + } }); - }).finally(() => { - this.mapUploadInProgress = false; }); + } else { + Logger.warn(`Received FDSMock upload request with a content-length of ${expectedSize}. Aborting.`); - res.sendStatus(200); - }); - } else { - res.end(); - req.connection.destroy(); - } + res.end(); + req.socket?.destroy(); + this.fdsUploadSemaphore.leave(); + } + }); }); - this.mapUploadServer.on("error", (e) => { - Logger.error("MapUploadServer Error: ",e); + this.fdsMockServer.on("error", (e) => { + Logger.error("FDSMockServer Error: ",e); }); - this.mapUploadServer.listen(8079, this.dummycloudBindIp, function() { - Logger.info("Map Upload Server running on port " + 8079); + this.fdsMockServer.listen(8079, this.dummycloudBindIp, function() { + Logger.info("FDSMockServer running on port " + 8079); }); } @@ -198,7 +232,7 @@ class MiioValetudoRobot extends ValetudoRobot { } if (!cloudSecret && this.config.get("embedded") === true) { - cloudSecret = MiioValetudoRobot.READ_DEVICE_CONF(this.deviceConfPath)["key"]; + cloudSecret = this.getCloudSecretFromFS(); } if (cloudSecret && cloudSecret.length >= 32) { @@ -221,68 +255,73 @@ class MiioValetudoRobot extends ValetudoRobot { this.tokenFilePath = "/dev/null"; } - // clang-format off - /* - Handles http_dns load balancing requests. - - Example request and response (the latter is pretty-printed for readability). - - GET /gslb?tver=2&id=277962183&dm=ot.io.mi.com×tamp=1574455630&sign=nNevMcHtzuB90okJfG9zSyPTw87u8U8HQpVNXqpVt%2Bk%3D HTTP/1.1 - Host:110.43.0.83 - User-Agent:miio-client - - { - "info": { - "host_list": [{ - "ip": "120.92.65.244", - "port": 8053 - }, { - "ip": "120.92.142.94", - "port": 8053 - }, { - "ip": "58.83.177.237", - "port": 8053 - }, { - "ip": "58.83.177.239", - "port": 8053 - }, { - "ip": "58.83.177.236", - "port": 8053 - }, { - "ip": "120.92.65.242", - "port": 8053 - } - ], - "enable": 1 - }, - "sign": "NxPNmsa8eh2/Y6OdJKoEaEonR6Lvrw5CkV5+mnpZois=", - "timestamp": "1574455630" - } - */ - // clang-format on - handleHttpDnsRequest(req, res) { - // ot.io.mi.com asks for UDP host - // ott.io.mi.com asks for TCP hosts, which our dummycloud doesn’t (yet) support. - if (req.query["dm"] === "ott.io.mi.com") { - res.status(501).send("miio/tcp not implemented"); + initModelSpecificWebserverRoutes(app) { + super.initModelSpecificWebserverRoutes(app); + + /* + Handles http_dns load balancing requests. + To properly spoof the http_dns request, we need to have this route on port 80 instead of the + miio-implementation specific second webserver on 8079 + + Example request and response (the latter is pretty-printed for readability). + + GET /gslb?tver=2&id=277962183&dm=ot.io.mi.com×tamp=1574455630&sign=nNevMcHtzuB90okJfG9zSyPTw87u8U8HQpVNXqpVt%2Bk%3D HTTP/1.1 + Host:110.43.0.83 + User-Agent:miio-client + + { + "info": { + "host_list": [{ + "ip": "120.92.65.244", + "port": 8053 + }, { + "ip": "120.92.142.94", + "port": 8053 + }, { + "ip": "58.83.177.237", + "port": 8053 + }, { + "ip": "58.83.177.239", + "port": 8053 + }, { + "ip": "58.83.177.236", + "port": 8053 + }, { + "ip": "120.92.65.242", + "port": 8053 + } + ], + "enable": 1 + }, + "sign": "NxPNmsa8eh2/Y6OdJKoEaEonR6Lvrw5CkV5+mnpZois=", + "timestamp": "1574455630" } - const info = { - "host_list": [ - { - "ip": this.embeddedDummycloudIp, - "port": 8053 - } - ], - "enable": 1 - }; - const signature = crypto.createHmac("sha256", this.cloudSecret) - .update(JSON.stringify(info)) - .digest("base64"); - - res.status(200).send({ - "info": info, - "timestamp": req.query["timestamp"], - "sign": signature + */ + app.get("/gslb", (req, res) => { + // ot.io.mi.com asks for UDP host + // ott.io.mi.com asks for TCP hosts, which our dummycloud doesn’t (yet) support. + if (req.query["dm"] === "ott.io.mi.com") { + res.status(501).send("miio/tcp not implemented"); + return; + } + const info = { + "host_list": [ + { + "ip": this.embeddedDummycloudIp, + "port": 8053 + } + ], + "enable": 1 + }; + const signature = crypto.createHmac("sha256", this.cloudSecret) + .update(JSON.stringify(info)) + .digest("base64"); + + res.json({ + "info": info, + "timestamp": req.query["timestamp"], + "sign": signature + }); }); } @@ -317,32 +356,17 @@ class MiioValetudoRobot extends ValetudoRobot { * @param {object} options * @param {number=} options.retries * @param {number=} options.timeout custom timeout in milliseconds + * @param {boolean=} options.preferLocalInterface * @returns {Promise} */ sendCommand(method, args = [], options = {}) { - if (this.dummyCloud.miioSocket.connected) { + if (this.dummyCloud.miioSocket.connected && options.preferLocalInterface !== true) { return this.sendCloud({"method": method, "params": args}, options); } else { - return this.localSocket.sendMessage(method, args, options); + return this.localSocket.sendMessage({"method": method, "params": args}, options); } } - /** - * Sends a {'method': method, 'params': args} message to the robot. - * Only uses the local socket - * - * @public - * @param {string} method - * @param {object|Array} args - * @param {object} options - * @param {number=} options.retries - * @param {number=} options.timeout custom timeout in milliseconds - * @returns {Promise} - */ - sendLocal(method, args = [], options = {}) { - return this.localSocket.sendMessage(method, args, options); - } - /** * Sends a json object to cloud socket. * @@ -357,13 +381,12 @@ class MiioValetudoRobot extends ValetudoRobot { } /** - * Called when a message is received, either from cloud or local interface. * * @protected * @param {any} msg the json object sent by the remote device * @returns {boolean} True if the message was handled. */ - onMessage(msg) { + onIncomingCloudMessage(msg) { switch (msg.method) { case "_sync.gen_tmp_presigned_url": case "_sync.gen_presigned_url": @@ -374,8 +397,7 @@ class MiioValetudoRobot extends ValetudoRobot { let result = {ok: true}; const expires = Math.floor(new Date(new Date().getTime() + 15 * 60000).getTime() / 1000); //+15min; - let url = this.mapUploadUrlPrefix + "/api/miio/map_upload_handler?ts=" + - process.hrtime().toString().replace(/,/g, "") + "&suffix=" + key + "&Expires=" + expires; + let url = `${this.mapUploadUrlPrefix}/api/miio/fds_upload_handler?ts=${process.hrtime().toString().replace(/,/g, "")}&suffix=${key}&Expires=${expires}`; if (msg.method === "_sync.gen_tmp_presigned_url") { result[key] = indices.map(i => { @@ -417,7 +439,7 @@ class MiioValetudoRobot extends ValetudoRobot { * @protected */ onCloudConnected() { - Logger.info("Cloud connected"); + Logger.info("Dummycloud connected"); // start polling the map after a brief delay of 3.5s setTimeout(() => { return this.pollMap(); @@ -425,16 +447,63 @@ class MiioValetudoRobot extends ValetudoRobot { } /** - * Poll the map. + * @public + * @returns {void} + */ + pollMap() { + this.mapPollMutex.take(() => { + let repollSeconds = this.mapPollingIntervals.default; + + // Clear pending timeout, since we’re starting a new poll right now. + if (this.mapPollTimeout) { + clearTimeout(this.mapPollTimeout); + + this.mapPollTimeout = undefined; + } + + this.executeMapPoll().then((response) => { + repollSeconds = this.determineNextMapPollInterval(response); + }).catch(() => { + repollSeconds = this.mapPollingIntervals.error; + }).finally(() => { + this.mapPollTimeout = setTimeout(() => { + this.pollMap(); + }, repollSeconds * 1000); + + this.mapPollMutex.leave(); + }); + }); + } + + /** * * @protected * @abstract - * @returns {void} + * @returns {Promise} */ - pollMap() { + async executeMapPoll() { throw new NotImplementedError(); } + /** + * @protected + * @param {any} pollResponse Implementation specific + * @return {number} seconds + */ + determineNextMapPollInterval(pollResponse) { + let repollSeconds = this.mapPollingIntervals.default; + + let StatusStateAttribute = this.state.getFirstMatchingAttribute({ + attributeClass: stateAttrs.StatusStateAttribute.name + }); + + if (StatusStateAttribute && StatusStateAttribute.isActiveState) { + repollSeconds = this.mapPollingIntervals.active; + } + + return repollSeconds; + } + /** * Initial preprocessing (e.g. decompression) of the map data. * @@ -465,7 +534,8 @@ class MiioValetudoRobot extends ValetudoRobot { * @param {object} params implementation specific url parameters * @returns {Promise} */ - async handleUploadedMapData(data, query, params) { + async handleUploadedFDSData(data, query, params) { + // By-default we assume that everything uploaded will be a map this.preprocessMap(data).then(async (preprocessedData) => { const parsedMap = await this.parseMap(preprocessedData); @@ -489,6 +559,10 @@ class MiioValetudoRobot extends ValetudoRobot { await this.localSocket.shutdown(); } + getCloudSecretFromFS() { + return MiioValetudoRobot.READ_DEVICE_CONF(this.deviceConfPath)["key"]; + } + static READ_DEVICE_CONF(pathOnDisk) { let deviceConf; @@ -522,5 +596,6 @@ class MiioValetudoRobot extends ValetudoRobot { } const DEVICE_CONF_KEY_VALUE_REGEX = /^(?[A-Za-z\d:.]+)=(?[A-Za-z\d:.]+)$/; +const MAX_UPLOAD_FILESIZE = 4 * 1024 * 1024; // 4 MiB module.exports = MiioValetudoRobot; diff --git a/backend/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability.js b/backend/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability.js index 9432b73a..6b172f15 100644 --- a/backend/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability.js +++ b/backend/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability.js @@ -1,6 +1,6 @@ const NotImplementedError = require("../../../core/NotImplementedError"); const spawnSync = require("child_process").spawnSync; -const Tools = require("../../../Tools"); +const Tools = require("../../../utils/Tools"); const ValetudoWifiStatus = require("../../../entities/core/ValetudoWifiStatus"); const WifiConfigurationCapability = require("../../../core/capabilities/WifiConfigurationCapability"); diff --git a/backend/lib/robots/common/miioCapabilities/MiioWifiConfigurationCapability.js b/backend/lib/robots/common/miioCapabilities/MiioWifiConfigurationCapability.js index 506d80b3..e4cc64ca 100644 --- a/backend/lib/robots/common/miioCapabilities/MiioWifiConfigurationCapability.js +++ b/backend/lib/robots/common/miioCapabilities/MiioWifiConfigurationCapability.js @@ -47,14 +47,20 @@ class MiioWifiConfigurationCapability extends LinuxWifiConfigurationCapability { wifiConfig.credentials.typeSpecificSettings && wifiConfig.credentials.typeSpecificSettings.password ) { //This command will only work when received on the local interface! - await this.robot.sendLocal("miIO.config_router", { - "ssid": wifiConfig.ssid, - "passwd": wifiConfig.credentials.typeSpecificSettings.password, - "uid": 0, - "cc": "de", - "country_domain": "de", - "config_type": "app" - }, {}); + await this.robot.sendCommand( + "miIO.config_router", + { + "ssid": wifiConfig.ssid, + "passwd": wifiConfig.credentials.typeSpecificSettings.password, + "uid": 0, + "cc": "de", + "country_domain": "de", + "config_type": "app" + }, + { + preferLocalInterface: true + } + ); } else { throw new Error("Invalid wifiConfig"); } diff --git a/backend/lib/robots/dreame/Dreame1CValetudoRobot.js b/backend/lib/robots/dreame/Dreame1CValetudoRobot.js index 6e8d8b4b..f431d170 100644 --- a/backend/lib/robots/dreame/Dreame1CValetudoRobot.js +++ b/backend/lib/robots/dreame/Dreame1CValetudoRobot.js @@ -5,6 +5,7 @@ const DreameValetudoRobot = require("./DreameValetudoRobot"); const entities = require("../../entities"); const Logger = require("../../Logger"); const MiioValetudoRobot = require("../MiioValetudoRobot"); +const ValetudoRestrictedZone = require("../../entities/core/ValetudoRestrictedZone"); const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); const stateAttrs = entities.state.attributes; @@ -123,11 +124,15 @@ class Dreame1CValetudoRobot extends DreameValetudoRobot { }, segmentCleaningModeId: 18, iterationsSupported: 1, - customOrderSupported: false + customOrderSupported: true })); this.registerCapability(new capabilities.DreameCombinedVirtualRestrictionsCapability({ robot: this, + supportedRestrictedZoneTypes: [ + ValetudoRestrictedZone.TYPE.REGULAR, + ValetudoRestrictedZone.TYPE.MOP + ], miot_actions: { map_edit: { siid: MIOT_SERVICES.MAP.SIID, @@ -310,10 +315,28 @@ class Dreame1CValetudoRobot extends DreameValetudoRobot { } } })); + + this.registerCapability(new capabilities.DreamePendingMapChangeHandlingCapability({ + robot: this, + miot_actions: { + map_edit: { + siid: MIOT_SERVICES.MAP.SIID, + aiid: MIOT_SERVICES.MAP.ACTIONS.EDIT.AIID + } + }, + miot_properties: { + mapDetails: { + piid: MIOT_SERVICES.MAP.PROPERTIES.MAP_DETAILS.PIID + }, + actionResult: { + piid: MIOT_SERVICES.MAP.PROPERTIES.ACTION_RESULT.PIID + } + } + })); } - onMessage(msg) { - if (super.onMessage(msg) === true) { + onIncomingCloudMessage(msg) { + if (super.onIncomingCloudMessage(msg) === true) { return true; } @@ -510,6 +533,7 @@ class Dreame1CValetudoRobot extends DreameValetudoRobot { case 12: case 19: case 22: + case 27: //disable map uploads //ignored for now break; @@ -527,11 +551,12 @@ class Dreame1CValetudoRobot extends DreameValetudoRobot { break; case MIOT_SERVICES.BATTERY.PROPERTIES.CHARGING.PIID: /* - 1 = On Charger + 1 = On Charger and charging 2 = Not on Charger + 4 = On Charger and fully charged 5 = Returning to Charger */ - this.isCharging = elem.value === 1; + this.isCharging = elem.value === 4 || elem.value === 1; this.stateNeedsUpdate = true; break; } @@ -555,6 +580,7 @@ class Dreame1CValetudoRobot extends DreameValetudoRobot { let newState; let statusValue; let statusFlag; + let statusError; let statusMetaData = {}; if (this.errorCode === "0" || this.errorCode === "" || this.errorCode === 0 || this.errorCode === undefined) { @@ -573,14 +599,14 @@ class Dreame1CValetudoRobot extends DreameValetudoRobot { } else { statusValue = stateAttrs.StatusStateAttribute.VALUE.ERROR; - statusMetaData.error_code = this.errorCode; - statusMetaData.error_description = DreameValetudoRobot.GET_ERROR_CODE_DESCRIPTION(this.errorCode); + statusError = DreameValetudoRobot.MAP_ERROR_CODE(this.errorCode); } newState = new stateAttrs.StatusStateAttribute({ value: statusValue, flag: statusFlag, - metaData: statusMetaData + metaData: statusMetaData, + error: statusError }); this.state.upsertFirstMatchingAttribute(newState); diff --git a/backend/lib/robots/dreame/DreameD9ProPlusValetudoRobot.js b/backend/lib/robots/dreame/DreameD9ProPlusValetudoRobot.js new file mode 100644 index 00000000..66e2ee7b --- /dev/null +++ b/backend/lib/robots/dreame/DreameD9ProPlusValetudoRobot.js @@ -0,0 +1,34 @@ +const DreameD9ValetudoRobot = require("./DreameD9ValetudoRobot"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const fs = require("fs"); +const MiioValetudoRobot = require("../MiioValetudoRobot"); + +/** + * There is no such thing as a D9 Pro+ + * This implementation is used by D9 Pros that use a backported D9 firmware + */ +class DreameD9ProPlusValetudoRobot extends DreameD9ValetudoRobot { + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(options); + } + + getModelName() { + return "D9 Pro+"; + } + + static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { + const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(DreameValetudoRobot.DEVICE_CONF_PATH); + const isD9Pro = !!(deviceConf && deviceConf.model === "dreame.vacuum.p2187"); + + return isD9Pro && fs.existsSync("/etc/dustbuilder_backport"); + } +} + + +module.exports = DreameD9ProPlusValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameD9ProValetudoRobot.js b/backend/lib/robots/dreame/DreameD9ProValetudoRobot.js index 533b94b2..8c8864a2 100644 --- a/backend/lib/robots/dreame/DreameD9ProValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameD9ProValetudoRobot.js @@ -2,7 +2,10 @@ const capabilities = require("./capabilities"); const DreameGen2LidarValetudoRobot = require("./DreameGen2LidarValetudoRobot"); const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); const DreameValetudoRobot = require("./DreameValetudoRobot"); +const entities = require("../../entities"); +const fs = require("fs"); const MiioValetudoRobot = require("../MiioValetudoRobot"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); class DreameD9ProValetudoRobot extends DreameGen2LidarValetudoRobot { /** @@ -14,6 +17,21 @@ class DreameD9ProValetudoRobot extends DreameGen2LidarValetudoRobot { constructor(options) { super(options); + this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID + })); + + this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + })); + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ robot: this, miot_properties: { @@ -45,6 +63,11 @@ class DreameD9ProValetudoRobot extends DreameGen2LidarValetudoRobot { } }, })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + attached: false + })); } getModelName() { @@ -53,8 +76,9 @@ class DreameD9ProValetudoRobot extends DreameGen2LidarValetudoRobot { static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(DreameValetudoRobot.DEVICE_CONF_PATH); + const isD9Pro = !!(deviceConf && deviceConf.model === "dreame.vacuum.p2187"); - return !!(deviceConf && deviceConf.model === "dreame.vacuum.p2187"); + return isD9Pro && !fs.existsSync("/etc/dustbuilder_backport"); } } diff --git a/backend/lib/robots/dreame/DreameD9ValetudoRobot.js b/backend/lib/robots/dreame/DreameD9ValetudoRobot.js index 63eebed9..ee5d4cfb 100644 --- a/backend/lib/robots/dreame/DreameD9ValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameD9ValetudoRobot.js @@ -1,8 +1,12 @@ const capabilities = require("./capabilities"); const DreameGen2LidarValetudoRobot = require("./DreameGen2LidarValetudoRobot"); const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); +const DreameQuirkFactory = require("./DreameQuirkFactory"); const DreameValetudoRobot = require("./DreameValetudoRobot"); +const entities = require("../../entities"); const MiioValetudoRobot = require("../MiioValetudoRobot"); +const QuirksCapability = require("../../core/capabilities/QuirksCapability"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); class DreameD9ValetudoRobot extends DreameGen2LidarValetudoRobot { /** @@ -14,6 +18,25 @@ class DreameD9ValetudoRobot extends DreameGen2LidarValetudoRobot { constructor(options) { super(options); + const QuirkFactory = new DreameQuirkFactory({ + robot: this + }); + + this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID + })); + + this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + })); + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ robot: this, miot_properties: { @@ -28,6 +51,10 @@ class DreameD9ValetudoRobot extends DreameGen2LidarValetudoRobot { filter: { siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, piid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.PROPERTIES.TIME_LEFT.PIID + }, + sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.PROPERTIES.TIME_LEFT.PIID } }, miot_actions: { @@ -42,9 +69,27 @@ class DreameD9ValetudoRobot extends DreameGen2LidarValetudoRobot { reset_filter: { siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.ACTIONS.RESET.AIID - } + }, + reset_sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.ACTIONS.RESET.AIID + }, }, })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + attached: false + })); + + this.registerCapability(new QuirksCapability({ + robot: this, + quirks: [ + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN) + ] + })); + } getModelName() { diff --git a/backend/lib/robots/dreame/DreameF9ValetudoRobot.js b/backend/lib/robots/dreame/DreameF9ValetudoRobot.js index d7461d23..a9031960 100644 --- a/backend/lib/robots/dreame/DreameF9ValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameF9ValetudoRobot.js @@ -28,6 +28,10 @@ class DreameF9ValetudoRobot extends DreameGen2VSlamValetudoRobot { filter: { siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, piid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.PROPERTIES.TIME_LEFT.PIID + }, + sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.PROPERTIES.TIME_LEFT.PIID } }, miot_actions: { @@ -42,7 +46,11 @@ class DreameF9ValetudoRobot extends DreameGen2VSlamValetudoRobot { reset_filter: { siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.ACTIONS.RESET.AIID - } + }, + reset_sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.ACTIONS.RESET.AIID + }, }, })); } diff --git a/backend/lib/robots/dreame/DreameGen2LidarValetudoRobot.js b/backend/lib/robots/dreame/DreameGen2LidarValetudoRobot.js index adf2503b..698a474d 100644 --- a/backend/lib/robots/dreame/DreameGen2LidarValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameGen2LidarValetudoRobot.js @@ -1,8 +1,26 @@ const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); +const capabilities = require("./capabilities"); + class DreameGen2LidarValetudoRobot extends DreameGen2ValetudoRobot { constructor(options) { super(options); + + this.registerCapability(new capabilities.DreameMappingPassCapability({ + robot: this, + miot_actions: { + start: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.ACTIONS.START.AIID + } + }, + miot_properties: { + mode: { + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MODE.PIID + } + }, + mappingModeId: 21 + })); } } diff --git a/backend/lib/robots/dreame/DreameGen2VSlamValetudoRobot.js b/backend/lib/robots/dreame/DreameGen2VSlamValetudoRobot.js index 894aba1e..0407621a 100644 --- a/backend/lib/robots/dreame/DreameGen2VSlamValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameGen2VSlamValetudoRobot.js @@ -1,6 +1,10 @@ const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); const capabilities = require("./capabilities"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const entities = require("../../entities"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); + class DreameGen2VSlamValetudoRobot extends DreameGen2ValetudoRobot { constructor(options) { @@ -12,6 +16,26 @@ class DreameGen2VSlamValetudoRobot extends DreameGen2ValetudoRobot { siid: DreameGen2ValetudoRobot.MIOT_SERVICES.PERSISTENT_MAPS.SIID, piid: DreameGen2ValetudoRobot.MIOT_SERVICES.PERSISTENT_MAPS.PROPERTIES.ENABLED.PIID })); + + this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + })); + + this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID + })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + attached: false + })); } } diff --git a/backend/lib/robots/dreame/DreameGen2ValetudoRobot.js b/backend/lib/robots/dreame/DreameGen2ValetudoRobot.js index dda3ce20..b455cba6 100644 --- a/backend/lib/robots/dreame/DreameGen2ValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameGen2ValetudoRobot.js @@ -2,11 +2,12 @@ const capabilities = require("./capabilities"); const ConsumableMonitoringCapability = require("../../core/capabilities/ConsumableMonitoringCapability"); const DreameMiotServices = require("./DreameMiotServices"); +const DreameUtils = require("./DreameUtils"); const DreameValetudoRobot = require("./DreameValetudoRobot"); const entities = require("../../entities"); +const LinuxTools = require("../../utils/LinuxTools"); const Logger = require("../../Logger"); const MopAttachmentReminderValetudoEvent = require("../../valetudo_events/events/MopAttachmentReminderValetudoEvent"); -const Tools = require("../../Tools"); const ValetudoRestrictedZone = require("../../entities/core/ValetudoRestrictedZone"); const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); @@ -37,6 +38,15 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { ) ); + /** @type {Array<{siid: number, piid: number, did: number}>} */ + this.statePropertiesToPoll = this.getStatePropertiesToPoll().map(e => { + return { + siid: e.siid, + piid: e.piid, + did: this.deviceId + }; + }); + this.lastMapPoll = new Date(0); this.mode = 0; //Idle @@ -75,15 +85,6 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { piid: MIOT_SERVICES.VACUUM_2.PROPERTIES.FAN_SPEED.PIID })); - this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ - robot: this, - presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { - return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); - }), - siid: MIOT_SERVICES.VACUUM_2.SIID, - piid: MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID - })); - this.registerCapability(new capabilities.DreameLocateCapability({ robot: this, siid: MIOT_SERVICES.AUDIO.SIID, @@ -127,7 +128,7 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { }, segmentCleaningModeId: 18, iterationsSupported: 4, - customOrderSupported: false + customOrderSupported: true })); this.registerCapability(new capabilities.DreameMapSegmentEditCapability({ @@ -225,12 +226,6 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { install_voicepack_piid: MIOT_SERVICES.AUDIO.PROPERTIES.INSTALL_VOICEPACK.PIID })); - this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ - robot: this, - siid: MIOT_SERVICES.VACUUM_2.SIID, - piid: MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID - })); - this.registerCapability(new capabilities.DreamePendingMapChangeHandlingCapability({ robot: this, miot_actions: { @@ -249,22 +244,6 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { } })); - this.registerCapability(new capabilities.DreameMappingPassCapability({ - robot: this, - miot_actions: { - start: { - siid: MIOT_SERVICES.VACUUM_2.SIID, - aiid: MIOT_SERVICES.VACUUM_2.ACTIONS.START.AIID - } - }, - miot_properties: { - mode: { - piid: MIOT_SERVICES.VACUUM_2.PROPERTIES.MODE.PIID - } - }, - mappingModeId: 21 - })); - this.registerCapability(new capabilities.DreameManualControlCapability({ robot: this, miot_properties: { @@ -325,10 +304,6 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { } })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, @@ -336,8 +311,8 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { })); } - onMessage(msg) { - if (super.onMessage(msg) === true) { + onIncomingCloudMessage(msg) { + if (super.onIncomingCloudMessage(msg) === true) { return true; } @@ -348,7 +323,14 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { case MIOT_SERVICES.MAP.SIID: switch (e.piid) { case MIOT_SERVICES.MAP.PROPERTIES.MAP_DATA.PIID: - //intentional since these will only be P-Frames which are unsupported (yet?) + /* + Most of the time, these will be P-Frames, which Valetudo ignores, however + sometimes, they may be I-Frames as well. Usually that's right when a new map + is being created, as then the map data is small enough to fit into a miio msg + */ + this.preprocessAndParseMap(e.value).catch(err => { + Logger.warn("Error while trying to parse map update", err); + }); break; case MIOT_SERVICES.MAP.PROPERTIES.CLOUD_FILE_NAME.PIID: case MIOT_SERVICES.MAP.PROPERTIES.CLOUD_FILE_NAME_2.PIID: @@ -365,6 +347,9 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { case MIOT_SERVICES.SIDE_BRUSH.SIID: case MIOT_SERVICES.FILTER.SIID: case MIOT_SERVICES.SENSOR.SIID: + case MIOT_SERVICES.MOP.SIID: + case MIOT_SERVICES.SECONDARY_FILTER.SIID: + case MIOT_SERVICES.DETERGENT.SIID: this.parseAndUpdateState([e]); break; case MIOT_SERVICES.DEVICE.SIID: @@ -377,8 +362,20 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { //Intentionally ignored since we only poll that info when required and therefore don't care about updates break; case MIOT_SERVICES.AUTO_EMPTY_DOCK.SIID: + case MIOT_SERVICES.TIMERS.SIID: //Intentionally left blank (for now?) break; + case MIOT_SERVICES.SILVER_ION.SIID: + //Intentionally ignored for now, because I have no idea what that should be or where it could be located + //TODO: figure out + break; + case 10001: + /* + Seems to have something to do with the AI camera + Sample value: {"operType":"properties_changed","operation":"monitor","result":0,"status":0} + */ + //Intentionally ignored + break; default: Logger.warn("Unhandled property change ", e); } @@ -406,8 +403,13 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { return false; } - async pollState() { - const response = await this.sendCommand("get_properties", [ + /** + * May be extended by children + * + * @return {Array<{piid: number, siid: number}>} + */ + getStatePropertiesToPoll() { + return [ { siid: MIOT_SERVICES.VACUUM_2.SIID, piid: MIOT_SERVICES.VACUUM_2.PROPERTIES.MODE.PIID @@ -440,11 +442,14 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { siid: MIOT_SERVICES.BATTERY.SIID, piid: MIOT_SERVICES.BATTERY.PROPERTIES.CHARGING.PIID } - ].map(e => { - e.did = this.deviceId; + ]; + } - return e; - })); + async pollState() { + const response = await this.sendCommand( + "get_properties", + this.statePropertiesToPoll + ); if (response) { this.parseAndUpdateState(response); @@ -517,14 +522,41 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { break; } case MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_TANK_ATTACHMENT.PIID: { - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: elem.value === 1 + const supportedAttachments = this.getModelDetails().supportedAttachments; + + if (supportedAttachments.includes(stateAttrs.AttachmentStateAttribute.TYPE.WATERTANK)) { + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + attached: elem.value === 1 + })); + } + + if (supportedAttachments.includes(stateAttrs.AttachmentStateAttribute.TYPE.MOP)) { + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, + attached: elem.value === 1 + })); + } + + break; + } + case MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_STATUS.PIID: { + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.DockStatusStateAttribute({ + value: DreameValetudoRobot.MOP_DOCK_STATUS_MAP[elem.value] })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: elem.value === 1 + break; + } + case MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID: { + const deserializedValue = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(elem.value); + + let matchingOperationMode = Object.keys(DreameValetudoRobot.OPERATION_MODES).find(key => { + return DreameValetudoRobot.OPERATION_MODES[key] === deserializedValue.operationMode; + }); + + this.state.upsertFirstMatchingAttribute(new stateAttrs.PresetSelectionStateAttribute({ + type: stateAttrs.PresetSelectionStateAttribute.TYPE.OPERATION_MODE, + value: matchingOperationMode })); break; } @@ -536,8 +568,13 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { case MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID: case MIOT_SERVICES.VACUUM_2.PROPERTIES.KEY_LOCK.PIID: case MIOT_SERVICES.VACUUM_2.PROPERTIES.OBSTACLE_AVOIDANCE.PIID: + case MIOT_SERVICES.VACUUM_2.PROPERTIES.POST_CHARGE_CONTINUE.PIID: //ignored for now break; + case 38: + //No idea what this does + //TODO: figure out + break; default: Logger.warn("Unhandled VACUUM_2 property", elem); @@ -568,6 +605,9 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { case MIOT_SERVICES.SIDE_BRUSH.SIID: case MIOT_SERVICES.FILTER.SIID: case MIOT_SERVICES.SENSOR.SIID: + case MIOT_SERVICES.MOP.SIID: + case MIOT_SERVICES.SECONDARY_FILTER.SIID: + case MIOT_SERVICES.DETERGENT.SIID: if (this.capabilities[ConsumableMonitoringCapability.TYPE]) { this.capabilities[ConsumableMonitoringCapability.TYPE].parseConsumablesMessage(elem); } @@ -582,11 +622,12 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { let newState; let statusValue; let statusFlag; + let statusError; let statusMetaData = {}; if (this.errorCode === "0" || this.errorCode === "") { - statusValue = DreameValetudoRobot.STATUS_MAP[this.mode].value; - statusFlag = DreameValetudoRobot.STATUS_MAP[this.mode].flag; + statusValue = DreameValetudoRobot.STATUS_MAP[this.mode]?.value ?? stateAttrs.StatusStateAttribute.VALUE.IDLE; + statusFlag = DreameValetudoRobot.STATUS_MAP[this.mode]?.flag; if (statusValue === stateAttrs.StatusStateAttribute.VALUE.DOCKED && this.taskStatus !== 0) { // Robot has a pending task but is charging due to low battery and will resume when battery >= 80% @@ -598,11 +639,12 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { if (this.errorCode === "68") { //Docked with mop still attached. For some reason, dreame decided to have this as an error statusValue = stateAttrs.StatusStateAttribute.VALUE.DOCKED; this.valetudoEventStore.raise(new MopAttachmentReminderValetudoEvent({})); + } else if (this.errorCode === "114") { //Reminder message to regularly clean the mop dock + statusValue = stateAttrs.StatusStateAttribute.VALUE.DOCKED; } else { statusValue = stateAttrs.StatusStateAttribute.VALUE.ERROR; - statusMetaData.error_code = this.errorCode; - statusMetaData.error_description = DreameValetudoRobot.GET_ERROR_CODE_DESCRIPTION(this.errorCode); + statusError = DreameValetudoRobot.MAP_ERROR_CODE(this.errorCode); } } @@ -610,7 +652,8 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { newState = new stateAttrs.StatusStateAttribute({ value: statusValue, flag: statusFlag, - metaData: statusMetaData + metaData: statusMetaData, + error: statusError }); this.state.upsertFirstMatchingAttribute(newState); @@ -632,13 +675,13 @@ class DreameGen2ValetudoRobot extends DreameValetudoRobot { if (this.config.get("embedded") === true) { try { - const {partitions, rootPartition} = Tools.PARSE_PROC_CMDLINE(); + const parsedCmdline = LinuxTools.READ_PROC_CMDLINE(); - if (partitions[rootPartition]) { - Logger.info(`Current rootfs: ${partitions[rootPartition]} (${rootPartition})`); + if (parsedCmdline.partitions[parsedCmdline.root]) { + Logger.info(`Current rootfs: ${parsedCmdline.partitions[parsedCmdline.root]} (${parsedCmdline.root})`); } } catch (e) { - Logger.warn("Unable to parse /proc/cmdline", e); + Logger.warn("Unable to read /proc/cmdline", e); } } } diff --git a/backend/lib/robots/dreame/DreameL10ProValetudoRobot.js b/backend/lib/robots/dreame/DreameL10ProValetudoRobot.js index 6030b0ec..48ec9470 100644 --- a/backend/lib/robots/dreame/DreameL10ProValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameL10ProValetudoRobot.js @@ -3,8 +3,10 @@ const DreameGen2LidarValetudoRobot = require("./DreameGen2LidarValetudoRobot"); const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); const DreameQuirkFactory = require("./DreameQuirkFactory"); const DreameValetudoRobot = require("./DreameValetudoRobot"); +const entities = require("../../entities"); const MiioValetudoRobot = require("../MiioValetudoRobot"); const QuirksCapability = require("../../core/capabilities/QuirksCapability"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); class DreameL10ProValetudoRobot extends DreameGen2LidarValetudoRobot { /** @@ -20,6 +22,21 @@ class DreameL10ProValetudoRobot extends DreameGen2LidarValetudoRobot { robot: this }); + this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID + })); + + this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + })); + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ robot: this, miot_properties: { @@ -66,6 +83,15 @@ class DreameL10ProValetudoRobot extends DreameGen2LidarValetudoRobot { piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.KEY_LOCK.PIID })); + this.registerCapability(new capabilities.DreameOperationModeControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.OPERATION_MODES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.OPERATION_MODES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + })); + this.registerCapability(new QuirksCapability({ robot: this, quirks: [ @@ -74,8 +100,24 @@ class DreameL10ProValetudoRobot extends DreameGen2LidarValetudoRobot { QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.OBSTACLE_AVOIDANCE) ] })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + attached: false + })); } + getStatePropertiesToPoll() { + const superProps = super.getStatePropertiesToPoll(); + + return [ + ...superProps, + { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + } + ]; + } getModelName() { return "L10 Pro"; diff --git a/backend/lib/robots/dreame/DreameL10SUltraValetudoRobot.js b/backend/lib/robots/dreame/DreameL10SUltraValetudoRobot.js new file mode 100644 index 00000000..0aa62d92 --- /dev/null +++ b/backend/lib/robots/dreame/DreameL10SUltraValetudoRobot.js @@ -0,0 +1,235 @@ +const capabilities = require("./capabilities"); +const DreameGen2LidarValetudoRobot = require("./DreameGen2LidarValetudoRobot"); +const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); +const DreameQuirkFactory = require("./DreameQuirkFactory"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const entities = require("../../entities"); +const fs = require("fs"); +const MiioValetudoRobot = require("../MiioValetudoRobot"); +const QuirksCapability = require("../../core/capabilities/QuirksCapability"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); + +const stateAttrs = entities.state.attributes; + +class DreameL10SUltraValetudoRobot extends DreameGen2LidarValetudoRobot { + + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(options); + + const QuirkFactory = new DreameQuirkFactory({ + robot: this + }); + + this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID + })); + + this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + })); + + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ + robot: this, + miot_properties: { + main_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.PROPERTIES.TIME_LEFT.PIID + }, + side_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.PROPERTIES.TIME_LEFT.PIID + }, + filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.PROPERTIES.TIME_LEFT.PIID + }, + sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.PROPERTIES.TIME_LEFT.PIID + }, + mop: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.PROPERTIES.TIME_LEFT.PIID + }, + detergent: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.DETERGENT.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.DETERGENT.PROPERTIES.PERCENT_LEFT.PIID + } + }, + miot_actions: { + reset_main_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.ACTIONS.RESET.AIID + }, + reset_side_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.ACTIONS.RESET.AIID + }, + reset_filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.ACTIONS.RESET.AIID + }, + reset_sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.ACTIONS.RESET.AIID + }, + reset_mop: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.ACTIONS.RESET.AIID + }, + reset_detergent: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.DETERGENT.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.DETERGENT.ACTIONS.RESET.AIID + } + }, + })); + + this.registerCapability(new capabilities.DreameKeyLockCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.KEY_LOCK.PIID + })); + + this.registerCapability(new capabilities.DreameAutoEmptyDockAutoEmptyControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.AUTO_EMPTY_DOCK.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.AUTO_EMPTY_DOCK.PROPERTIES.AUTO_EMPTY_ENABLED.PIID + })); + + this.registerCapability(new capabilities.DreameAutoEmptyDockManualTriggerCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.AUTO_EMPTY_DOCK.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.AUTO_EMPTY_DOCK.ACTIONS.EMPTY_DUSTBIN.AIID + })); + + this.registerCapability(new capabilities.DreameAICameraGoToLocationCapability({ + robot: this, + miot_actions: { + start: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.ACTIONS.START.AIID + } + }, + miot_properties: { + mode: { + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MODE.PIID + }, + additionalCleanupParameters: { + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.ADDITIONAL_CLEANUP_PROPERTIES.PIID + } + }, + goToModeId: 23 + })); + + this.registerCapability(new capabilities.DreameMopDockCleanManualTriggerCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.ACTIONS.MOP_DOCK_INTERACT.AIID, + + additionalCleanupParametersPiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.ADDITIONAL_CLEANUP_PROPERTIES.PIID + })); + + this.registerCapability(new capabilities.DreameMopDockDryManualTriggerCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.ACTIONS.MOP_DOCK_INTERACT.AIID, + + additionalCleanupParametersPiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.ADDITIONAL_CLEANUP_PROPERTIES.PIID + })); + + this.registerCapability(new capabilities.DreameOperationModeControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.OPERATION_MODES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.OPERATION_MODES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + })); + + this.registerCapability(new QuirksCapability({ + robot: this, + quirks: [ + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_MODE_SENSITIVITY), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.TIGHT_MOP_PATTERN), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.AUTO_EMPTY_INTERVAL), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.OBSTACLE_AVOIDANCE), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_DETECTION_SENSOR), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_LIFT_CARPET_BEHAVIOUR), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DRYING_TIME), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.BASIC_AI_CAMERA_SETTINGS), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_DETERGENT), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_WET_DRY_SWITCH), + ] + })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.DockStatusStateAttribute({ + value: entities.state.attributes.DockStatusStateAttribute.VALUE.IDLE + })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, + attached: false + })); + } + + getStatePropertiesToPoll() { + const superProps = super.getStatePropertiesToPoll(); + + return [ + ...superProps, + { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_STATUS.PIID + }, + { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + } + ]; + } + + + getModelName() { + return "L10S Ultra"; + } + + getCloudSecretFromFS() { + return fs.readFileSync("/mnt/private/ULI/factory/key.txt"); + } + + getModelDetails() { + return Object.assign( + {}, + super.getModelDetails(), + { + supportedAttachments: [ + stateAttrs.AttachmentStateAttribute.TYPE.MOP, + ] + } + ); + } + + + static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { + const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(DreameValetudoRobot.DEVICE_CONF_PATH); + + return !!(deviceConf && deviceConf.model === "dreame.vacuum.r2228o"); + } +} + + +module.exports = DreameL10SUltraValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameMapParser.js b/backend/lib/robots/dreame/DreameMapParser.js index 392e81bb..620f837a 100644 --- a/backend/lib/robots/dreame/DreameMapParser.js +++ b/backend/lib/robots/dreame/DreameMapParser.js @@ -17,9 +17,9 @@ class DreameMapParser { * * @param {Buffer} buf * @param {MapDataType} [type] - * @returns {null|import("../../entities/map/ValetudoMap")} + * @returns {Promise} */ - static PARSE(buf, type) { + static async PARSE(buf, type) { //Maps are always at least 27 bytes in size if (!buf || buf.length < HEADER_SIZE) { return null; @@ -90,7 +90,7 @@ class DreameMapParser { if (additionalData.sa && Array.isArray(additionalData.sa)) { additionalData.sa.forEach(sa => { - activeSegmentIds.push(sa[0]); + activeSegmentIds.push(sa[0].toString()); }); } @@ -111,7 +111,7 @@ class DreameMapParser { * after the robot complains about being unable to use the map */ if (additionalData.rism && additionalData.ris === 2) { - const rismResult = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(additionalData.rism), MAP_DATA_TYPES.RISM); + const rismResult = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(additionalData.rism), MAP_DATA_TYPES.RISM); if (rismResult instanceof Map.ValetudoMap) { rismResult.entities.forEach(e => { @@ -136,7 +136,7 @@ class DreameMapParser { rismResult.layers.forEach(l => { if (l.metaData.segmentId !== undefined) { - if (activeSegmentIds.includes(parseInt(l.metaData.segmentId))) { //required for the 1C + if (activeSegmentIds.includes(l.metaData.segmentId)) { //required for the 1C l.metaData.active = true; } @@ -228,6 +228,27 @@ class DreameMapParser { } } + /* + TODO RESEARCH + + There can be an spoint object. No idea what that does + There can also be multiple tpoint points. No idea when or why that happens or what it does either + */ + if (additionalData.pointinfo && Array.isArray(additionalData.pointinfo.tpoint) && additionalData.pointinfo.tpoint.length === 1) { + const goToPoint = DreameMapParser.CONVERT_TO_VALETUDO_COORDINATES( + additionalData.pointinfo.tpoint[0][0], + additionalData.pointinfo.tpoint[0][1], + ); + + entities.push(new Map.PointMapEntity({ + points: [ + goToPoint.x, + goToPoint.y, + ], + type: Map.PointMapEntity.TYPE.GO_TO_TARGET + })); + } + if (additionalData.suw > 0) { /* 6 = New Map in Single-map @@ -242,6 +263,11 @@ class DreameMapParser { return null; } + // While the map is technically valid at this point, we still ignore it as we don't need a map with 0 pixels + if (layers.length === 0) { + return null; + } + return new Map.ValetudoMap({ metaData: metaData, size: { @@ -353,14 +379,19 @@ class DreameMapParser { } else if (type === MAP_DATA_TYPES.RISM) { /** * A rism Pixel is one byte consisting of - * 1 0000000 - * isWall flag The Segment ID + * 1 1 000000 + * isWall flag isCarpet flag The Segment ID */ const px = buf[(i * parsedHeader.width) + j]; - const segmentId = px & 0b01111111; + const segmentId = px & 0b00111111; const wallFlag = px >> 7; + /* + TODO: figure out what to do with the carpet information + px >> 6 & 0b00000001 + */ + if (wallFlag) { wallPixels.push(coords); } else if (segmentId > 0) { @@ -394,8 +425,8 @@ class DreameMapParser { Object.keys(segments).forEach(segmentId => { const metaData = { - segmentId: parseInt(segmentId), - active: activeSegmentIds.includes(parseInt(segmentId)), + segmentId: segmentId, + active: activeSegmentIds.includes(segmentId), source: type }; @@ -428,7 +459,11 @@ class DreameMapParser { let match; while ((match = PATH_REGEX.exec(traceString)) !== null) { - if (match.groups.operator === PATH_OPERATORS.START) { + if ( + match.groups.operator === PATH_OPERATORS.START || + match.groups.operator === PATH_OPERATORS.MOP_START || + match.groups.operator === PATH_OPERATORS.DUAL_START + ) { currentUnprocessedPath = []; unprocessedPaths.push(currentUnprocessedPath); @@ -517,15 +552,26 @@ class DreameMapParser { * * https://tools.ietf.org/html/rfc4648#section-5 * + * * - * @param {any} data - * @returns {Buffer|null} + * @param {Buffer|string} data + * @returns {Promise} */ - static PREPROCESS(data) { + static async PREPROCESS(data) { + // As string.toString() is a no-op, we don't need to check the type beforehand const base64String = data.toString().replace(/_/g, "/").replace(/-/g, "+"); try { - return zlib.inflateSync(Buffer.from(base64String, "base64")); + // intentional return await + return await new Promise((resolve, reject) => { + zlib.inflate(Buffer.from(base64String, "base64"), (err, result) => { + if (!err) { + resolve(result); + } else { + reject(err); + } + }); + }); } catch (e) { Logger.error("Error while preprocessing map", e); @@ -545,9 +591,11 @@ const FRAME_TYPES = Object.freeze({ P: 80 }); -const PATH_REGEX = /(?[SL])(?-?\d+),(?-?\d+)/g; +const PATH_REGEX = /(?[SMWL])(?-?\d+),(?-?\d+)/g; const PATH_OPERATORS = { START: "S", + MOP_START: "M", + DUAL_START: "W", RELATIVE_LINE: "L" }; diff --git a/backend/lib/robots/dreame/DreameMiotHelper.js b/backend/lib/robots/dreame/DreameMiotHelper.js index 7b38338b..b02bd711 100644 --- a/backend/lib/robots/dreame/DreameMiotHelper.js +++ b/backend/lib/robots/dreame/DreameMiotHelper.js @@ -1,3 +1,4 @@ +const RobotFirmwareError = require("../../core/RobotFirmwareError"); class DreameMiotHelper { /** @@ -26,7 +27,7 @@ class DreameMiotHelper { if (res[0].code === 0) { return res[0].value; } else { - throw new Error("Error code " + res[0].code); + throw new RobotFirmwareError("Error code " + res[0].code); } } else { @@ -53,7 +54,7 @@ class DreameMiotHelper { if (res?.length === 1) { if (res[0].code !== 0) { - throw new Error("Error code " + res[0].code); + throw new RobotFirmwareError("Error code " + res[0].code); } } else { throw new Error("Received invalid response"); @@ -76,7 +77,7 @@ class DreameMiotHelper { }); if (res.code !== 0) { - throw new Error("Error code " + res.code); + throw new RobotFirmwareError("Error code " + res.code); } } } diff --git a/backend/lib/robots/dreame/DreameMiotServices.js b/backend/lib/robots/dreame/DreameMiotServices.js index 9170ba7b..ce0b1dc1 100644 --- a/backend/lib/robots/dreame/DreameMiotServices.js +++ b/backend/lib/robots/dreame/DreameMiotServices.js @@ -211,7 +211,7 @@ module.exports = { }, ACTION_RESULT: { - PIID: 6 //TODO: validate + PIID: 6 } }, ACTIONS: { @@ -288,6 +288,9 @@ module.exports = { ADDITIONAL_CLEANUP_PROPERTIES: { PIID: 10 }, + POST_CHARGE_CONTINUE: { + PIID: 11 + }, CARPET_MODE: { PIID: 12 }, @@ -310,6 +313,15 @@ module.exports = { OBSTACLE_AVOIDANCE: { PIID: 21 }, + AI_CAMERA_SETTINGS: { + PIID: 22 + }, + MOP_DOCK_SETTINGS: { + PIID: 23 + }, + MOP_DOCK_STATUS: { + PIID: 25 + }, KEY_LOCK: { PIID: 27 }, @@ -318,6 +330,24 @@ module.exports = { }, TIGHT_MOP_PATTERN: { PIID: 29 + }, + MOP_DOCK_UV_TREATMENT: { + PIID: 32 + }, + CARPET_DETECTION_SENSOR: { + PIID: 33 + }, + MOP_DOCK_WET_DRY_SWITCH: { + PIID: 34 + }, + MOP_LIFT_CARPET_BEHAVIOUR: { + PIID: 36 + }, + MOP_DOCK_DETERGENT: { + PIID: 37 + }, + MOP_DRYING_TIME: { + PIID: 40 } }, ACTIONS: { @@ -326,6 +356,9 @@ module.exports = { }, STOP: { AIID: 2 + }, + MOP_DOCK_INTERACT: { + AIID: 4 } } }, @@ -448,6 +481,70 @@ module.exports = { } } }, + SECONDARY_FILTER: { + SIID: 17, + PROPERTIES: { + TIME_LEFT: { //Hours + PIID: 2 + }, + PERCENT_LEFT: { + PIID: 1 + } + }, + ACTIONS: { + RESET: { + AIID: 1 + } + } + }, + MOP: { + SIID: 18, + PROPERTIES: { + TIME_LEFT: { //Hours + PIID: 2 + }, + PERCENT_LEFT: { + PIID: 1 + } + }, + ACTIONS: { + RESET: { + AIID: 1 + } + } + }, + SILVER_ION: { + SIID: 19, + PROPERTIES: { + TIME_LEFT: { //Hours + PIID: 2 + }, + PERCENT_LEFT: { + PIID: 1 + } + }, + ACTIONS: { + RESET: { + AIID: 1 + } + } + }, + DETERGENT: { + SIID: 20, + PROPERTIES: { + TIME_LEFT: { //Hours + PIID: 2 + }, + PERCENT_LEFT: { + PIID: 1 + } + }, + ACTIONS: { + RESET: { + AIID: 1 + } + } + }, MAP: { SIID: 6, PROPERTIES: { @@ -524,6 +621,9 @@ module.exports = { AIID: 1 } } + }, + TIMERS: { + SIID: 8 } }) }; diff --git a/backend/lib/robots/dreame/DreameMopValetudoRobot.js b/backend/lib/robots/dreame/DreameMopValetudoRobot.js new file mode 100644 index 00000000..9056cd2a --- /dev/null +++ b/backend/lib/robots/dreame/DreameMopValetudoRobot.js @@ -0,0 +1,202 @@ +const capabilities = require("./capabilities"); +const DreameGen2LidarValetudoRobot = require("./DreameGen2LidarValetudoRobot"); +const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); + +const DreameUtils = require("./DreameUtils"); +const entities = require("../../entities"); +const Logger = require("../../Logger"); +const stateAttrs = entities.state.attributes; + +const WATER_GRADES = { + [stateAttrs.PresetSelectionStateAttribute.INTENSITY.LOW]: 1, + [stateAttrs.PresetSelectionStateAttribute.INTENSITY.MEDIUM]: 2, + [stateAttrs.PresetSelectionStateAttribute.INTENSITY.HIGH]: 3, +}; + +class DreameMopValetudoRobot extends DreameGen2LidarValetudoRobot { + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(options); + + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ + robot: this, + miot_properties: { + main_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.PROPERTIES.TIME_LEFT.PIID + }, + side_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.PROPERTIES.TIME_LEFT.PIID + }, + filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.PROPERTIES.TIME_LEFT.PIID + }, + sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.PROPERTIES.TIME_LEFT.PIID + }, + mop: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.PROPERTIES.TIME_LEFT.PIID + } + }, + miot_actions: { + reset_main_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.ACTIONS.RESET.AIID + }, + reset_side_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.ACTIONS.RESET.AIID + }, + reset_filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.ACTIONS.RESET.AIID + }, + reset_sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.ACTIONS.RESET.AIID + }, + reset_mop: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.MOP.ACTIONS.RESET.AIID + } + }, + })); + + this.registerCapability(new capabilities.DreameKeyLockCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.KEY_LOCK.PIID + })); + + this.registerCapability(new capabilities.DreameMopDockWaterUsageControlCapability({ + robot: this, + presets: Object.keys(WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + })); + + this.registerCapability(new capabilities.DreameMopDockCleanManualTriggerCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.ACTIONS.MOP_DOCK_INTERACT.AIID, + + additionalCleanupParametersPiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.ADDITIONAL_CLEANUP_PROPERTIES.PIID + })); + + this.registerCapability(new capabilities.DreameMopDockDryManualTriggerCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.ACTIONS.MOP_DOCK_INTERACT.AIID, + + additionalCleanupParametersPiid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.ADDITIONAL_CLEANUP_PROPERTIES.PIID + })); + + this.registerCapability(new capabilities.DreameOperationModeControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.OPERATION_MODES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.OPERATION_MODES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + })); + + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.DockStatusStateAttribute({ + value: entities.state.attributes.DockStatusStateAttribute.VALUE.IDLE + })); + } + + getStatePropertiesToPoll() { + const superProps = super.getStatePropertiesToPoll(); + + return [ + // We don't have to poll the water usage piid as it doesn't control anything on this robot + ...superProps.filter(e => { + return !( + e.siid === DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID && + e.piid === DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + ); + }), + + { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + }, + { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_STATUS.PIID + } + ]; + } + + parseAndUpdateState(data) { + if (!Array.isArray(data)) { + Logger.error("Received non-array state", data); + return; + } + + data.forEach(elem => { + switch (elem.siid) { + case DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID: { + switch (elem.piid) { + case DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID: { + const deserializedValue = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(elem.value); + + let matchingWaterGrade = Object.keys(WATER_GRADES).find(key => { + return WATER_GRADES[key] === deserializedValue.waterGrade; + }); + + this.state.upsertFirstMatchingAttribute(new stateAttrs.PresetSelectionStateAttribute({ + metaData: { + rawValue: elem.value + }, + type: stateAttrs.PresetSelectionStateAttribute.TYPE.WATER_GRADE, + value: matchingWaterGrade + })); + break; + } + } + break; + } + } + }); + + // Filter out everything that might confuse the regular state parsing + return super.parseAndUpdateState(data.filter(e => { + return ( + !( + e.siid === DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID && + e.piid === DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + ) + ); + })); + } + + getModelDetails() { + return Object.assign( + {}, + super.getModelDetails(), + { + supportedAttachments: [ + stateAttrs.AttachmentStateAttribute.TYPE.MOP, + ] + } + ); + } +} + + +module.exports = DreameMopValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameP2148ValetudoRobot.js b/backend/lib/robots/dreame/DreameP2148ValetudoRobot.js new file mode 100644 index 00000000..af207623 --- /dev/null +++ b/backend/lib/robots/dreame/DreameP2148ValetudoRobot.js @@ -0,0 +1,78 @@ +const capabilities = require("./capabilities"); +const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); +const DreameGen2VSlamValetudoRobot = require("./DreameGen2VSlamValetudoRobot"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const MiioValetudoRobot = require("../MiioValetudoRobot"); + +class DreameP2148ValetudoRobot extends DreameGen2VSlamValetudoRobot { + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(options); + + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ + robot: this, + miot_properties: { + main_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.PROPERTIES.TIME_LEFT.PIID + }, + side_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.PROPERTIES.TIME_LEFT.PIID + }, + filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.PROPERTIES.TIME_LEFT.PIID + }, + sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.PROPERTIES.TIME_LEFT.PIID + }, + secondary_filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SECONDARY_FILTER.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.SECONDARY_FILTER.PROPERTIES.TIME_LEFT.PIID + } + }, + miot_actions: { + reset_main_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.MAIN_BRUSH.ACTIONS.RESET.AIID + }, + reset_side_brush: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SIDE_BRUSH.ACTIONS.RESET.AIID + }, + reset_filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.FILTER.ACTIONS.RESET.AIID + }, + reset_sensor: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SENSOR.ACTIONS.RESET.AIID + }, + reset_secondary_filter: { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.SECONDARY_FILTER.SIID, + aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.SECONDARY_FILTER.ACTIONS.RESET.AIID + } + }, + })); + } + + getModelName() { + return "P2148"; + } + + static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { + const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(DreameValetudoRobot.DEVICE_CONF_PATH); + + return !!(deviceConf && deviceConf.model === "dreame.vacuum.p2148o"); + } +} + + +module.exports = DreameP2148ValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameP2149ValetudoRobot.js b/backend/lib/robots/dreame/DreameP2149ValetudoRobot.js new file mode 100644 index 00000000..b2a45e7a --- /dev/null +++ b/backend/lib/robots/dreame/DreameP2149ValetudoRobot.js @@ -0,0 +1,42 @@ +const DreameMopValetudoRobot = require("./DreameMopValetudoRobot"); +const DreameQuirkFactory = require("./DreameQuirkFactory"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const MiioValetudoRobot = require("../MiioValetudoRobot"); +const QuirksCapability = require("../../core/capabilities/QuirksCapability"); + +class DreameP2149ValetudoRobot extends DreameMopValetudoRobot { + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(options); + + const QuirkFactory = new DreameQuirkFactory({ + robot: this + }); + + this.registerCapability(new QuirksCapability({ + robot: this, + quirks: [ + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_UV_TREATMENT) + ] + })); + } + + getModelName() { + return "P2149"; + } + + static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { + const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(DreameValetudoRobot.DEVICE_CONF_PATH); + + return !!(deviceConf && deviceConf.model === "dreame.vacuum.p2149o"); + } +} + + +module.exports = DreameP2149ValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameQuirkFactory.js b/backend/lib/robots/dreame/DreameQuirkFactory.js index e44d9d70..dd8dfa7f 100644 --- a/backend/lib/robots/dreame/DreameQuirkFactory.js +++ b/backend/lib/robots/dreame/DreameQuirkFactory.js @@ -1,5 +1,6 @@ const DreameMiotHelper = require("./DreameMiotHelper"); const DreameMiotServices = require("./DreameMiotServices"); +const DreameUtils = require("./DreameUtils"); const Quirk = require("../../core/Quirk"); class DreameQuirkFactory { @@ -198,6 +199,390 @@ class DreameQuirkFactory { ); } }); + case DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY: + return new Quirk({ + id: id, + title: "Mop Cleaning Frequency", + description: "Determine how often the robot should clean and re-wet its mopping pads during a cleanup.", + options: ["every_segment", "every_5_m2", "every_10_m2", "every_15_m2", "every_20_m2", "every_25_m2"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + ); + + const deserializedResponse = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(res); + + switch (deserializedResponse.padCleaningFrequency) { + case 0: + return "every_segment"; + case 5: + return "every_5_m2"; + case 10: + return "every_10_m2"; + case 15: + return "every_15_m2"; + case 20: + return "every_20_m2"; + case 25: + return "every_25_m2"; + default: + throw new Error(`Received invalid value ${deserializedResponse.operationMode}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "every_segment": + val = 0; + break; + case "every_5_m2": + val = 5; + break; + case "every_10_m2": + val = 10; + break; + case "every_15_m2": + val = 15; + break; + case "every_20_m2": + val = 20; + break; + case "every_25_m2": + val = 25; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + ); + const deserializedResponse = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(res); + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID, + DreameUtils.SERIALIZE_MOP_DOCK_SETTINGS({ + waterGrade: deserializedResponse.waterGrade, + padCleaningFrequency: val, + operationMode: deserializedResponse.operationMode + }) + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_UV_TREATMENT: + return new Quirk({ + id: id, + title: "Wastewater UV Treatment", + description: "Disinfect the waste water tank after each successful cleanup using the in-built UV-C light.", + options: ["on", "off"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_UV_TREATMENT.PIID + ); + + switch (res) { + case 1: + return "on"; + case 0: + return "off"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "on": + val = 1; + break; + case "off": + val = 0; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_UV_TREATMENT.PIID, + val + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.CARPET_DETECTION_SENSOR: + return new Quirk({ + id: id, + title: "Carpet detection sensor", + description: "Detect carpets using a dedicated sensor", + options: ["on", "off"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.CARPET_DETECTION_SENSOR.PIID + ); + + switch (res) { + case 1: + return "on"; + case 0: + return "off"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "on": + val = 1; + break; + case "off": + val = 0; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.CARPET_DETECTION_SENSOR.PIID, + val + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.MOP_LIFT_CARPET_BEHAVIOUR: + return new Quirk({ + id: id, + title: "Carpet Behaviour", + description: "Define how the robot should handle carpets when the mop is attached", + options: ["Lift Mop", "Avoid Carpet"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_LIFT_CARPET_BEHAVIOUR.PIID + ); + + switch (res) { + case 2: + return "Lift Mop"; + case 1: + return "Avoid Carpet"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "Lift Mop": + val = 2; + break; + case "Avoid Carpet": + val = 1; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_LIFT_CARPET_BEHAVIOUR.PIID, + val + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.MOP_DRYING_TIME: + return new Quirk({ + id: id, + title: "Mop Drying Time", + description: "Define how long the mop should be dried after a cleanup", + options: ["2h", "3h", "4h"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DRYING_TIME.PIID + ); + + switch (res) { + case 2: + return "2h"; + case 3: + return "3h"; + case 4: + return "4h"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "2h": + val = 2; + break; + case "3h": + val = 3; + break; + case "4h": + val = 3; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DRYING_TIME.PIID, + val + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.BASIC_AI_CAMERA_SETTINGS: + /* + The AI_CAMERA_SETTINGS PIID actually contains a list of flags each as one bit + I haven't figured out what all of those mean just yet. + + Therefore, for now this quirk will work with 0b01111 and 0b11111 as hardcoded values + 0b01111 is the default after a factory reset + */ + return new Quirk({ + id: id, + title: "Basic AI Camera Settings", + description: "Select if the AI Model should look for Pet waste", + options: ["No Pets", "Pets"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.AI_CAMERA_SETTINGS.PIID + ); + + switch (res) { + case 0b01111: + return "No Pets"; + case 0b11111: + return "Pets"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "No Pets": + val = 0b01111; + break; + case "Pets": + val = 0b11111; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.AI_CAMERA_SETTINGS.PIID, + val + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_DETERGENT: + return new Quirk({ + id: id, + title: "Detergent", + description: "Select if the Dock should automatically add detergent to the water", + options: ["on", "off", "Missing detergent cartridge"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_DETERGENT.PIID + ); + + switch (res) { + case 0: + return "off"; + case 1: + return "on"; + case 2: + return "Missing detergent cartridge"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "off": + val = 0; + break; + case "on": + val = 1; + break; + case "Missing detergent cartridge": + throw new Error("This informational message is not a user-selectable option"); + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_DETERGENT.PIID, + val + ); + } + }); + case DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_WET_DRY_SWITCH: + return new Quirk({ + id: id, + title: "Mopping Mode", + description: "Select \"dry\" if you don't want the dock to wet the mops before cleaning. This can be useful if there's a spill that you want to mop up.", + options: ["Wet", "Dry"], + getter: async () => { + const res = await this.helper.readProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_WET_DRY_SWITCH.PIID + ); + + switch (res) { + case 1: + return "Wet"; + case 0: + return "Dry"; + default: + throw new Error(`Received invalid value ${res}`); + } + }, + setter: async (value) => { + let val; + + switch (value) { + case "Wet": + val = 1; + break; + case "Dry": + val = 0; + break; + default: + throw new Error(`Received invalid value ${value}`); + } + + return this.helper.writeProperty( + DreameMiotServices["GEN2"].VACUUM_2.SIID, + DreameMiotServices["GEN2"].VACUUM_2.PROPERTIES.MOP_DOCK_WET_DRY_SWITCH.PIID, + val + ); + } + }); default: throw new Error(`There's no quirk with id ${id}`); } @@ -208,7 +593,15 @@ DreameQuirkFactory.KNOWN_QUIRKS = { CARPET_MODE_SENSITIVITY: "f8cb91ab-a47a-445f-b300-0aac0d4937c0", TIGHT_MOP_PATTERN: "8471c118-f1e1-4866-ad2e-3c11865a5ba8", AUTO_EMPTY_INTERVAL: "d38118f2-fb5d-4ed9-b668-262db15e5269", - OBSTACLE_AVOIDANCE: "4e386a76-b5f9-4f12-b04e-b8539a507163" + OBSTACLE_AVOIDANCE: "4e386a76-b5f9-4f12-b04e-b8539a507163", + MOP_DOCK_MOP_CLEANING_FREQUENCY: "a6709b18-57af-4e11-8b4c-8ae33147ab34", + MOP_DOCK_UV_TREATMENT: "7f97b603-967f-44f0-9dfb-35bcdc21f433", + CARPET_DETECTION_SENSOR: "38362a9d-6c8f-430a-aaaa-fd454e93e816", + MOP_LIFT_CARPET_BEHAVIOUR: "33ea65f7-f9a2-4462-a696-36019340a3e1", + MOP_DRYING_TIME: "516a1025-9c56-46e0-ac9b-a5007088d24a", + BASIC_AI_CAMERA_SETTINGS: "6305a7bc-cc10-4251-99e1-1bf567fee74c", + MOP_DOCK_DETERGENT: "a2a03d42-c710-45e5-b53a-4bc62778589f", + MOP_DOCK_WET_DRY_SWITCH: "66adac0f-0a16-4049-b6ac-080ef702bb39", }; module.exports = DreameQuirkFactory; diff --git a/backend/lib/robots/dreame/DreameUtils.js b/backend/lib/robots/dreame/DreameUtils.js new file mode 100644 index 00000000..6defd094 --- /dev/null +++ b/backend/lib/robots/dreame/DreameUtils.js @@ -0,0 +1,51 @@ +const UINT8_MASK = 0b00000000000000000000000011111111; + +/** + * Dreame stores all three configurables of their mop docks in a single PIID as one int + * This int consists of three ints like so (represented here as an 32 bit int because js bitwise operations use those): + * + * XXXXXXXXWWWWWWWWPPPPPPPPOOOOOOOO + * + * where + * - X is nothing + * - W is the water grade (wetness of the mop pads) + * - P is the pad cleaning frequency (apparently in m² plus 0 for "after each segment") + * - O is the operation mode (mop, vacuum & mop, vacuum) + * + */ + +class DreameUtils { + /** + * + * @param {number} input + * @return {{padCleaningFrequency: number, operationMode: number, waterGrade: number}} + */ + static DESERIALIZE_MOP_DOCK_SETTINGS(input) { + return { + operationMode: input >>> 0 & UINT8_MASK, + padCleaningFrequency: input >>> 8 & UINT8_MASK, + waterGrade: input >>> 16 & UINT8_MASK + }; + } + + /** + * + * @param {{padCleaningFrequency: number, operationMode: number, waterGrade: number}} settings + * @return {number} + */ + static SERIALIZE_MOP_DOCK_SETTINGS(settings) { + let result = 0 >>> 0; + + result |= (settings.waterGrade & UINT8_MASK); + result <<= 8; + + result |= (settings.padCleaningFrequency & UINT8_MASK); + result <<= 8; + + result |= (settings.operationMode & UINT8_MASK); + + return result; + } +} + +module.exports = DreameUtils; diff --git a/backend/lib/robots/dreame/DreameValetudoRobot.js b/backend/lib/robots/dreame/DreameValetudoRobot.js index a6249160..73988021 100644 --- a/backend/lib/robots/dreame/DreameValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameValetudoRobot.js @@ -6,11 +6,16 @@ const miioCapabilities = require("../common/miioCapabilities"); const DreameMapParser = require("./DreameMapParser"); +const AttachmentStateAttribute = require("../../entities/state/attributes/AttachmentStateAttribute"); +const AttributeSubscriber = require("../../entities/AttributeSubscriber"); +const CallbackAttributeSubscriber = require("../../entities/CallbackAttributeSubscriber"); const entities = require("../../entities"); +const MiioErrorResponseRobotFirmwareError = require("../../miio/MiioErrorResponseRobotFirmwareError"); const MiioValetudoRobot = require("../MiioValetudoRobot"); const PendingMapChangeValetudoEvent = require("../../valetudo_events/events/PendingMapChangeValetudoEvent"); const ValetudoMap = require("../../entities/map/ValetudoMap"); const ValetudoRobot = require("../../core/ValetudoRobot"); +const ValetudoRobotError = require("../../entities/core/ValetudoRobotError"); const stateAttrs = entities.state.attributes; @@ -26,11 +31,13 @@ class DreameValetudoRobot extends MiioValetudoRobot { * @param {object} options.miotServices.MAP.ACTIONS * @param {object} options.miotServices.MAP.ACTIONS.POLL * @param {number} options.miotServices.MAP.ACTIONS.POLL.AIID + * @param {object} options.miotServices.MAP.PROPERTIES + * @param {object} options.miotServices.MAP.PROPERTIES.MAP_DATA + * @param {number} options.miotServices.MAP.PROPERTIES.MAP_DATA.PIID */ constructor(options) { super(options); - this.lastMapPoll = new Date(0); this.miotServices = options.miotServices; @@ -45,11 +52,6 @@ class DreameValetudoRobot extends MiioValetudoRobot { networkInterface: "wlan0" })); } - - this.state.upsertFirstMatchingAttribute(new stateAttrs.AttachmentStateAttribute({ - type: stateAttrs.AttachmentStateAttribute.TYPE.DUSTBIN, - attached: true - })); } setEmbeddedParameters() { @@ -57,52 +59,47 @@ class DreameValetudoRobot extends MiioValetudoRobot { this.tokenFilePath = DreameValetudoRobot.TOKEN_FILE_PATH; } - pollMap() { - // Guard against multiple concurrent polls. - if (this.pollingMap) { - return; - } - - const now = new Date(); - if (now.getTime() - 600 > this.lastMapPoll.getTime()) { - this.pollingMap = true; - this.lastMapPoll = now; - - // Clear pending timeout, since we’re starting a new poll right now. - if (this.pollMapTimeout) { - clearTimeout(this.pollMapTimeout); - } - - this.sendCommand("action", + async executeMapPoll() { + let mapPollResult; + try { + mapPollResult = await this.sendCommand("action", { did: this.deviceId, siid: this.miotServices.MAP.SIID, aiid: this.miotServices.MAP.ACTIONS.POLL.AIID, in: [{ piid: 2, - value: "{\"frame_type\":\"I\"}" + value: "{\"frame_type\":\"I\", \"force_type\": 1, \"req_type\": 1}" }] - } - ).then(res => { - let repollSeconds = this.mapPollingIntervals.default; - - let StatusStateAttribute = this.state.getFirstMatchingAttribute({ - attributeClass: stateAttrs.StatusStateAttribute.name - }); + }, + {timeout: 7000} // user ack timeout seems to appear after ~6s on the p2028 1156 + ); + } catch (e) { + if (e instanceof MiioErrorResponseRobotFirmwareError && e.response?.message === "user ack timeout") { + /* + Since we're polling IFrames much faster than the regular dreame map, occasionally, the dreame + firmware isn't quick enough to respond to our requests. + + As this is expected, we just ignore that error + */ + } else { + Logger.warn("Error while polling map", e); + } - if (StatusStateAttribute && StatusStateAttribute.isActiveState) { - repollSeconds = this.mapPollingIntervals.active; - } + return; + } - this.pollMapTimeout = setTimeout(() => { - return this.pollMap(); - }, repollSeconds * 1000); - }, err => { - // ¯\_(ツ)_/¯ - }).finally(() => { - this.pollingMap = false; - }); + if (mapPollResult.code === 0 && Array.isArray(mapPollResult.out)) { + for (let prop of mapPollResult.out) { + if (prop.piid === this.miotServices.MAP.PROPERTIES.MAP_DATA.PIID && prop.value?.length > 15) { + try { + await this.preprocessAndParseMap(prop.value); + } catch (e) { + Logger.warn("Error while trying to parse map from miio", e); + } + } + } } } @@ -112,24 +109,18 @@ class DreameValetudoRobot extends MiioValetudoRobot { * @param {any} data * @returns {Promise} */ - preprocessMap(data) { - return new Promise((resolve, reject) => { - try { - const preprocessedData = DreameMapParser.PREPROCESS(data); - - if (preprocessedData) { - resolve(preprocessedData); - } else { - reject(new Error("Invalid map data")); - } - } catch (e) { - reject(e); - } - }); + async preprocessMap(data) { + const preprocessedData = await DreameMapParser.PREPROCESS(data); + + if (preprocessedData) { + return preprocessedData; + } else { + throw new Error("Invalid map data"); + } } async parseMap(data) { - const parsedMap = DreameMapParser.PARSE(data); + const parsedMap = await DreameMapParser.PARSE(data); if (parsedMap instanceof ValetudoMap) { if ( @@ -154,31 +145,40 @@ class DreameValetudoRobot extends MiioValetudoRobot { * @param {object} params implementation specific url parameters * @returns {Promise} */ - async handleUploadedMapData(data, query, params) { + async handleUploadedFDSData(data, query, params) { if ( - !( - Buffer.isBuffer(data) && - ( - data[0] === 0x7b || data[0] === 0x5b // 0x7b = "{" 0x5b = "[" - ) - ) && - !( - typeof query?.suffix === "string" && query.suffix.endsWith(".tbz2") + Buffer.isBuffer(data) && + ( + data[0] === 0x7b || data[0] === 0x5b // 0x7b = "{" 0x5b = "[" ) ) { - const preprocessedMap = await this.preprocessMap(data); - const parsedMap = await this.parseMap(preprocessedMap); - - if (!parsedMap) { - Logger.warn("Failed to parse uploaded map"); - } - } else { //We've received a multi-map JSON but we only want live maps - Logger.trace("Received unhandled multi-map map", { + Logger.trace("Received unhandled multi-map json", { query: query, params: params, data: data.toString() }); + } else if (typeof query?.suffix === "string" && query.suffix.endsWith(".tbz2")) { + Logger.trace("Received unhandled map backup", { + query: query, + params: params + }); + } else { + await this.preprocessAndParseMap(data); + } + } + + /** + * @protected + * @param {Buffer| string} data + * @returns {Promise} + */ + async preprocessAndParseMap(data) { + const preprocessedMap = await this.preprocessMap(data); + const parsedMap = await this.parseMap(preprocessedMap); + + if (!parsedMap) { + Logger.warn("Failed to parse uploaded map"); } } @@ -194,19 +194,39 @@ class DreameValetudoRobot extends MiioValetudoRobot { if (firmwareVersion.valid) { Logger.info("Firmware Version: " + firmwareVersion.arm); - Logger.info("MCU Version: " + firmwareVersion.mcu); } } } + initInternalSubscriptions() { + super.initInternalSubscriptions(); + + this.state.subscribe( + new CallbackAttributeSubscriber((eventType,attachment, prevStatus) => { + if ( + eventType === AttributeSubscriber.EVENT_TYPE.CHANGE && + attachment.type === AttachmentStateAttribute.TYPE.MOP && + //@ts-ignore + attachment.attached === false + ) { + try { + this.valetudoEventStore.setProcessed("mop_attachment_reminder"); + } catch (e) { + //intentional + } + } + }), + {attributeClass: AttachmentStateAttribute.name} + ); + } + /** * @private - * @returns {{arm: string, mcu: string, valid: boolean}} + * @returns {{arm: string, valid: boolean}} */ getFirmwareVersion() { const firmwareVersion = { arm: "???", - mcu: "???", valid: false }; @@ -214,11 +234,10 @@ class DreameValetudoRobot extends MiioValetudoRobot { const os_release = fs.readFileSync("/etc/os-release").toString(); const parsedFile = JSON.parse(os_release); - if (parsedFile && parsedFile.fw_arm_ver && parsedFile.fw_mcu_ota_ver) { + if (parsedFile && parsedFile.fw_arm_ver) { firmwareVersion.valid = true; firmwareVersion.arm = parsedFile.fw_arm_ver.split("_")?.[1]; - firmwareVersion.mcu = parsedFile.fw_mcu_ota_ver; } } catch (e) { Logger.warn("Unable to determine the Firmware Version", e); @@ -227,6 +246,19 @@ class DreameValetudoRobot extends MiioValetudoRobot { return firmwareVersion; } + getModelDetails() { + return Object.assign( + {}, + super.getModelDetails(), + { + supportedAttachments: [ + stateAttrs.AttachmentStateAttribute.TYPE.WATERTANK, + stateAttrs.AttachmentStateAttribute.TYPE.MOP, + ] + } + ); + } + /** * @return {object} */ @@ -278,7 +310,7 @@ DreameValetudoRobot.STATUS_MAP = Object.freeze({ flag: stateAttrs.StatusStateAttribute.FLAG.SEGMENT }, 5: { - value: stateAttrs.StatusStateAttribute.VALUE.CLEANING //TODO: is this correct? + value: stateAttrs.StatusStateAttribute.VALUE.CLEANING }, 6: { value: stateAttrs.StatusStateAttribute.VALUE.DOCKED @@ -307,7 +339,7 @@ DreameValetudoRobot.STATUS_MAP = Object.freeze({ 14: { //Powersave value: stateAttrs.StatusStateAttribute.VALUE.IDLE }, - 15: { + 15: { //SelfTest/AutoRepair of the W10 dock? value: stateAttrs.StatusStateAttribute.VALUE.IDLE }, 16: { @@ -331,6 +363,11 @@ DreameValetudoRobot.STATUS_MAP = Object.freeze({ 21: { value: stateAttrs.StatusStateAttribute.VALUE.MOVING, flag: stateAttrs.StatusStateAttribute.FLAG.MAPPING + }, + // 22? + 23: { + value: stateAttrs.StatusStateAttribute.VALUE.MOVING, + flag: stateAttrs.StatusStateAttribute.FLAG.TARGET } }); @@ -347,95 +384,568 @@ DreameValetudoRobot.WATER_GRADES = Object.freeze({ [stateAttrs.PresetSelectionStateAttribute.INTENSITY.HIGH]: 3, }); -//TODO: Refactor to something like ValetudoErrorCodes -DreameValetudoRobot.ERROR_CODES = { - "0": "No error", - "1": "Wheel lost floor contact. Robot is on the verge of falling", - "2": "Cliff sensor dirty", - "3": "Stuck front bumper", - "4": "Tilted robot", - "5": "Stuck front bumper", - "6": "Wheel lost floor contact. Robot is on the verge of falling", - "7": "Internal error", - "8": "Dustbin missing", - "9": "Water tank missing", - "10": "Water tank empty", - "11": "Dustbin full", - "12": "Main brush jammed", - "13": "Side brush jammed", - "14": "Filter jammed", - "15": "Robot stuck or trapped", - "16": "Robot stuck or trapped", - "17": "Robot stuck or trapped", - "18": "Robot stuck or trapped", - "19": "Charging station without power", - "20": "Low battery", - "21": "Charging error", - //22 - "23": "Internal error 23", - "24": "Camera dirty", - "25": "Internal error 25", - "26": "Camera dirty", - "27": "Sensor dirty", - "28": "Charging station without power", - "29": "Battery temperature out of operating range", - "30": "Internal error 30", - "31": "Robot stuck or trapped", - "32": "Robot stuck or trapped", - "33": "Internal error 33", - "34": "Internal error 34", - "35": "Internal error 35", - "36": "Internal error 36", - "37": "Internal error 37", - "38": "Internal error 38", - "39": "Internal error 39", - "40": "Internal error 40", - "41": "Magnetic interference", - "42": "Internal error 42", - "43": "Internal error 43", - "44": "Internal Error 44", - "45": "Internal Error 45", - "46": "Internal Error 46", - "47": "Cannot reach target", - "48": "LDS jammed", - "49": "LDS bumper jammed", - "50": "Internal error 50", - "51": "Filter jammed", - "52": "Internal error 52", - "53": "Internal error 53", - "54": "Wall sensor dirty", - "55": "Internal Error 55", - "56": "Internal Error 56", - "57": "Internal Error 57", - "58": "Internal Error 58", - "59": "Robot trapped by virtual restrictions", - "60": "Internal Error 60", - "61": "Cannot reach target", - "62": "Cannot reach target", - "63": "Cannot reach target", - "64": "Cannot reach target", - "65": "Cannot reach target", - "66": "Cannot reach target", - "67": "Cannot reach target", - "68": "Docked but mop is still attached. Please remove the mop", - - "-2": "Stuck inside restricted area", - - - - "101": "Auto-Empty Dock dust bag full or dust duct clogged", - "102": "Auto-Empty Dock cover open or missing dust bag", - "103": "Auto-Empty Dock cover open or missing dust bag", - "104": "Auto-Empty Dock dust bag full or dust duct clogged" -}; +DreameValetudoRobot.OPERATION_MODES = Object.freeze({ + [stateAttrs.PresetSelectionStateAttribute.MODE.VACUUM_AND_MOP]: 0, + [stateAttrs.PresetSelectionStateAttribute.MODE.MOP]: 1, + [stateAttrs.PresetSelectionStateAttribute.MODE.VACUUM]: 2, +}); + +DreameValetudoRobot.MOP_DOCK_STATUS_MAP = Object.freeze({ + 0: stateAttrs.DockStatusStateAttribute.VALUE.IDLE, + 1: stateAttrs.DockStatusStateAttribute.VALUE.CLEANING, + 2: stateAttrs.DockStatusStateAttribute.VALUE.DRYING, + 3: stateAttrs.DockStatusStateAttribute.VALUE.CLEANING, //TODO: idle instead? + 4: stateAttrs.DockStatusStateAttribute.VALUE.PAUSE, + 5: stateAttrs.DockStatusStateAttribute.VALUE.CLEANING, + 6: stateAttrs.DockStatusStateAttribute.VALUE.CLEANING, +}); -DreameValetudoRobot.GET_ERROR_CODE_DESCRIPTION = (errorCodeId) => { - if (DreameValetudoRobot.ERROR_CODES[errorCodeId] !== undefined) { - return DreameValetudoRobot.ERROR_CODES[errorCodeId]; - } else { - return "UNKNOWN ERROR CODE " + errorCodeId; + +/** + * + * @param {string} vendorErrorCode + * + * @returns {ValetudoRobotError} + */ +DreameValetudoRobot.MAP_ERROR_CODE = (vendorErrorCode) => { + const parameters = { + severity: { + kind: ValetudoRobotError.SEVERITY_KIND.UNKNOWN, + level: ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN, + }, + subsystem: ValetudoRobotError.SUBSYSTEM.UNKNOWN, + message: `Unknown error ${vendorErrorCode}`, + vendorErrorCode: vendorErrorCode + }; + + switch (vendorErrorCode) { + case "0": + parameters.message = "No error"; + break; + case "1": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "Wheel lost floor contact"; + break; + case "2": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Cliff sensor dirty or robot on the verge of falling"; + break; + case "3": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Stuck front bumper"; + break; + case "4": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Tilted robot"; + break; + case "5": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Stuck front bumper"; + break; + case "6": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "Wheel lost floor contact"; + break; + case "7": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "8": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Dustbin missing"; + break; + case "9": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Water tank missing"; + break; + case "10": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Water tank empty"; + break; + case "11": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Dustbin full"; + break; + case "12": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Main brush jammed"; + break; + case "13": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Side brush jammed"; + break; + case "14": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Filter jammed"; + break; + case "15": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case "16": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case "17": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case "18": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case "19": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging station without power"; + break; + case "20": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.INFO; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Low battery"; + break; + case "21": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging error"; + break; + //22 + case "23": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; //"AVA_HEALTH_STATUS_TYPE_HEART" //TODO What does the dreame error string mean? + break; + case "24": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Camera dirty"; + break; + case "25": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; //"AVA_HEALTH_STATUS_TYPE_MOVE" //TODO What does the dreame error string mean? + break; + case "26": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Camera dirty"; + break; + case "27": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Sensor dirty"; + break; + case "28": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging station without power"; + break; + case "29": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Battery temperature out of operating range"; + break; + case "30": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Fan speed abnormal"; + break; + case "31": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case "32": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case "33": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Accelerometer sensor error"; + break; + case "34": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Gyroscope sensor error"; + break; + case "35": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Gyroscope sensor error"; + break; + case "36": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Left magnetic field sensor error"; + break; + case "37": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Right magnetic field sensor error"; + break; + case "38": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; //"AVA_HEALTH_STATUS_TYPE_I_FLOW_ERROR" //TODO What does the dreame error string mean? + break; + case "39": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; //"AVA_HEALTH_STATUS_TYPE_INFRARED_FAULT" //TODO What does the dreame error string mean? + break; + case "40": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Camera fault"; + break; + case "41": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.INFO; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Magnetic interference"; + break; + case "42": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Water pump fault"; + break; + case "43": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "RTC fault"; + break; + case "44": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; //"AVA_HEALTH_STATUS_TYPE_I_AUTO_KEY_TRIG" //TODO What does the dreame error string mean? + break; + case "45": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "3.3V rail abnormal"; + break; + case "46": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "47": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "48": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "LDS jammed"; + break; + case "49": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "LDS bumper jammed"; + break; + case "50": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "51": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Filter jammed"; + break; + case "52": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "53": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "ToF Sensor offline"; + break; + case "54": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Wall sensor dirty"; + break; + case "55": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; //"AVA_HEALTH_STATUS_TYPE_CARPET_WATEBOX_START" //TODO What does the dreame error string mean? + break; + case "56": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "57": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "58": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "59": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot trapped by virtual restrictions"; + break; + case "60": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = `Internal error ${vendorErrorCode}`; + break; + case "61": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "62": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "63": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "64": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "65": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "66": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + case "67": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Cannot reach target"; + break; + // 68: Not an Error. "Docked but mop is still attached. Please remove the mop" + + /* + TODO figure out what these p2027 codes mean + 69 "AVA_HEALTH_STATUS_TYPE_MOP_CHECK" + 70 "AVA_HEALTH_STATUS_TYPE_FASTMAPMODE_MOPCHECK" + */ + + case "71": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Mop motor fault"; + break; + case "72": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Mop motor current abnormal"; + break; + + + case "-2": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Stuck inside restricted area"; + break; + + + case "101": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Auto-Empty Dock dust bag full or dust duct clogged"; + break; + case "102": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Auto-Empty Dock cover open or missing dust bag"; + break; + case "103": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Auto-Empty Dock cover open or missing dust bag"; + break; + case "104": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Auto-Empty Dock dust bag full or dust duct clogged"; + break; + + + + case "105": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Clean Water Tank not installed"; + break; + case "106": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Wastewater Tank not installed or full"; + break; + case "107": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Clean Water Tank empty"; + break; + case "108": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Wastewater Tank not installed or full"; + break; + case "109": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Wastewater pipe clogged"; + break; + case "110": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Wastewater pump damaged"; + break; + case "111": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Tray not installed"; + break; + case "112": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Tray full of water"; + break; + // 114: Not an Error. "Please remember to clean the mop tray" + case "116": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Clean Water Tank empty"; + break; + case "118": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Wastewater Tank not installed or full"; + break; + case "119": + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.DOCK; + parameters.message = "Mop Dock Tray full of water"; + break; } -}; + return new ValetudoRobotError(parameters); +}; module.exports = DreameValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameW10ValetudoRobot.js b/backend/lib/robots/dreame/DreameW10ValetudoRobot.js new file mode 100644 index 00000000..3b4ed55c --- /dev/null +++ b/backend/lib/robots/dreame/DreameW10ValetudoRobot.js @@ -0,0 +1,43 @@ +const DreameMopValetudoRobot = require("./DreameMopValetudoRobot"); +const DreameQuirkFactory = require("./DreameQuirkFactory"); +const DreameValetudoRobot = require("./DreameValetudoRobot"); +const MiioValetudoRobot = require("../MiioValetudoRobot"); +const QuirksCapability = require("../../core/capabilities/QuirksCapability"); + +class DreameW10ValetudoRobot extends DreameMopValetudoRobot { + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(options); + + const QuirkFactory = new DreameQuirkFactory({ + robot: this + }); + + this.registerCapability(new QuirksCapability({ + robot: this, + quirks: [ + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_MOP_CLEANING_FREQUENCY), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.MOP_DOCK_WET_DRY_SWITCH), + QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.CARPET_DETECTION_SENSOR), + ] + })); + } + + getModelName() { + return "W10"; + } + + static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { + const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(DreameValetudoRobot.DEVICE_CONF_PATH); + + return !!(deviceConf && deviceConf.model === "dreame.vacuum.p2027"); + } +} + + +module.exports = DreameW10ValetudoRobot; diff --git a/backend/lib/robots/dreame/DreameZ10ProValetudoRobot.js b/backend/lib/robots/dreame/DreameZ10ProValetudoRobot.js index c8f4079b..627d8224 100644 --- a/backend/lib/robots/dreame/DreameZ10ProValetudoRobot.js +++ b/backend/lib/robots/dreame/DreameZ10ProValetudoRobot.js @@ -3,8 +3,10 @@ const DreameGen2LidarValetudoRobot = require("./DreameGen2LidarValetudoRobot"); const DreameGen2ValetudoRobot = require("./DreameGen2ValetudoRobot"); const DreameQuirkFactory = require("./DreameQuirkFactory"); const DreameValetudoRobot = require("./DreameValetudoRobot"); +const entities = require("../../entities"); const MiioValetudoRobot = require("../MiioValetudoRobot"); const QuirksCapability = require("../../core/capabilities/QuirksCapability"); +const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); class DreameZ10ProValetudoRobot extends DreameGen2LidarValetudoRobot { @@ -21,6 +23,21 @@ class DreameZ10ProValetudoRobot extends DreameGen2LidarValetudoRobot { robot: this }); + this.registerCapability(new capabilities.DreameCarpetModeControlCapability({ + robot: this, + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.CARPET_MODE.PIID + })); + + this.registerCapability(new capabilities.DreameWaterUsageControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.WATER_GRADES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.WATER_GRADES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.WATER_USAGE.PIID + })); + this.registerCapability(new capabilities.DreameConsumableMonitoringCapability({ robot: this, miot_properties: { @@ -79,6 +96,15 @@ class DreameZ10ProValetudoRobot extends DreameGen2LidarValetudoRobot { aiid: DreameGen2ValetudoRobot.MIOT_SERVICES.AUTO_EMPTY_DOCK.ACTIONS.EMPTY_DUSTBIN.AIID })); + this.registerCapability(new capabilities.DreameOperationModeControlCapability({ + robot: this, + presets: Object.keys(DreameValetudoRobot.OPERATION_MODES).map(k => { + return new ValetudoSelectionPreset({name: k, value: DreameValetudoRobot.OPERATION_MODES[k]}); + }), + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + })); + this.registerCapability(new QuirksCapability({ robot: this, quirks: [ @@ -88,8 +114,28 @@ class DreameZ10ProValetudoRobot extends DreameGen2LidarValetudoRobot { QuirkFactory.getQuirk(DreameQuirkFactory.KNOWN_QUIRKS.OBSTACLE_AVOIDANCE) ] })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.DockStatusStateAttribute({ + value: entities.state.attributes.DockStatusStateAttribute.VALUE.IDLE + })); + + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + attached: false + })); } + getStatePropertiesToPoll() { + const superProps = super.getStatePropertiesToPoll(); + + return [ + ...superProps, + { + siid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.SIID, + piid: DreameGen2ValetudoRobot.MIOT_SERVICES.VACUUM_2.PROPERTIES.MOP_DOCK_SETTINGS.PIID + } + ]; + } getModelName() { return "Z10 Pro"; diff --git a/backend/lib/robots/dreame/capabilities/Dreame1CConsumableMonitoringCapability.js b/backend/lib/robots/dreame/capabilities/Dreame1CConsumableMonitoringCapability.js index 9b4e4aa3..ea91bbcd 100644 --- a/backend/lib/robots/dreame/capabilities/Dreame1CConsumableMonitoringCapability.js +++ b/backend/lib/robots/dreame/capabilities/Dreame1CConsumableMonitoringCapability.js @@ -1,4 +1,5 @@ const ConsumableMonitoringCapability = require("../../../core/capabilities/ConsumableMonitoringCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); const ConsumableStateAttribute = require("../../../entities/state/attributes/ConsumableStateAttribute"); @@ -113,7 +114,7 @@ class Dreame1CConsumableMonitoringCapability extends ConsumableMonitoringCapabil } ).then(res => { if (res.code !== 0) { - throw new Error("Error code " + res.code + " while resetting consumable."); + throw new RobotFirmwareError("Error code " + res.code + " while resetting consumable."); } this.markEventsAsProcessed(type, subType); diff --git a/backend/lib/robots/dreame/capabilities/Dreame1CZoneCleaningCapability.js b/backend/lib/robots/dreame/capabilities/Dreame1CZoneCleaningCapability.js index e8854442..4a246f85 100644 --- a/backend/lib/robots/dreame/capabilities/Dreame1CZoneCleaningCapability.js +++ b/backend/lib/robots/dreame/capabilities/Dreame1CZoneCleaningCapability.js @@ -1,4 +1,5 @@ const DreameMapParser = require("../DreameMapParser"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); const ZoneCleaningCapability = require("../../../core/capabilities/ZoneCleaningCapability"); /** @@ -72,7 +73,7 @@ class Dreame1CZoneCleaningCapability extends ZoneCleaningCapability { ); if (res.code !== 0) { - throw new Error("Error code " + res.code); + throw new RobotFirmwareError("Error code " + res.code); } } diff --git a/backend/lib/robots/dreame/capabilities/DreameAICameraGoToLocationCapability.js b/backend/lib/robots/dreame/capabilities/DreameAICameraGoToLocationCapability.js new file mode 100644 index 00000000..2c28a815 --- /dev/null +++ b/backend/lib/robots/dreame/capabilities/DreameAICameraGoToLocationCapability.js @@ -0,0 +1,64 @@ +const DreameMapParser = require("../DreameMapParser"); +const GoToLocationCapability = require("../../../core/capabilities/GoToLocationCapability"); + +const DreameMiotHelper = require("../DreameMiotHelper"); + +/** + * @extends GoToLocationCapability + */ +class DreameAICameraGoToLocationCapability extends GoToLocationCapability { + /** + * + * @param {object} options + * @param {import("../DreameValetudoRobot")} options.robot + * + * @param {object} options.miot_actions + * @param {object} options.miot_actions.start + * @param {number} options.miot_actions.start.siid + * @param {number} options.miot_actions.start.aiid + * + * @param {object} options.miot_properties + * @param {object} options.miot_properties.mode + * @param {object} options.miot_properties.mode.piid + * @param {object} options.miot_properties.additionalCleanupParameters + * @param {number} options.miot_properties.additionalCleanupParameters.piid + * + * @param {number} options.goToModeId + */ + constructor(options) { + super(options); + + this.miot_actions = options.miot_actions; + this.miot_properties = options.miot_properties; + + this.goToModeId = options.goToModeId; + + this.helper = new DreameMiotHelper({robot: this.robot}); + } + + + /** + * @param {import("../../../entities/core/ValetudoGoToLocation")} valetudoGoToLocation + * @returns {Promise} + */ + async goTo(valetudoGoToLocation) { + const dreamePoint = DreameMapParser.CONVERT_TO_DREAME_COORDINATES(valetudoGoToLocation.coordinates.x, valetudoGoToLocation.coordinates.y); + + await this.helper.executeAction( + this.miot_actions.start.siid, + this.miot_actions.start.aiid, + [ + { + piid: this.miot_properties.mode.piid, + value: this.goToModeId + }, + { + piid: this.miot_properties.additionalCleanupParameters.piid, + value: JSON.stringify({"tpoint": [[dreamePoint.x, dreamePoint.y, 0, 0]]}) + } + ] + ); + } +} + +module.exports = DreameAICameraGoToLocationCapability; diff --git a/backend/lib/robots/dreame/capabilities/DreameCombinedVirtualRestrictionsCapability.js b/backend/lib/robots/dreame/capabilities/DreameCombinedVirtualRestrictionsCapability.js index 7436e7ba..6976d6fe 100644 --- a/backend/lib/robots/dreame/capabilities/DreameCombinedVirtualRestrictionsCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameCombinedVirtualRestrictionsCapability.js @@ -4,6 +4,7 @@ const CombinedVirtualRestrictionsCapability = require("../../../core/capabilities/CombinedVirtualRestrictionsCapability"); const DreameMapParser = require("../DreameMapParser"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); const ValetudoRestrictedZone = require("../../../entities/core/ValetudoRestrictedZone"); /** @@ -120,11 +121,11 @@ class DreameCombinedVirtualRestrictionsCapability extends CombinedVirtualRestric this.robot.pollMap(); return; case 10: - throw new Error("Cannot save temporary virtual restrictions. A persistent map exists."); + throw new RobotFirmwareError("Cannot save temporary virtual restrictions. A persistent map exists."); case 11: - throw new Error("Cannot save virtual restrictions. No persistent map exists. Let the robot do a full clean before saving restrictions."); + throw new RobotFirmwareError("Cannot save virtual restrictions. No persistent map exists. Let the robot do a full clean before saving restrictions."); default: - throw new Error("Got error " + res.out[0].value + " while saving virtual restrictions."); + throw new RobotFirmwareError("Got error " + res.out[0].value + " while saving virtual restrictions."); } } } diff --git a/backend/lib/robots/dreame/capabilities/DreameConsumableMonitoringCapability.js b/backend/lib/robots/dreame/capabilities/DreameConsumableMonitoringCapability.js index 78b5ebfe..057bb21f 100644 --- a/backend/lib/robots/dreame/capabilities/DreameConsumableMonitoringCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameConsumableMonitoringCapability.js @@ -1,4 +1,5 @@ const ConsumableMonitoringCapability = require("../../../core/capabilities/ConsumableMonitoringCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); const ConsumableStateAttribute = require("../../../entities/state/attributes/ConsumableStateAttribute"); @@ -30,6 +31,18 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit * @param {number} options.miot_actions.reset_sensor.siid * @param {number} options.miot_actions.reset_sensor.aiid * + * @param {object} [options.miot_actions.reset_mop] + * @param {number} options.miot_actions.reset_mop.siid + * @param {number} options.miot_actions.reset_mop.aiid + * + * @param {object} [options.miot_actions.reset_secondary_filter] + * @param {number} options.miot_actions.reset_secondary_filter.siid + * @param {number} options.miot_actions.reset_secondary_filter.aiid + * + * @param {object} [options.miot_actions.reset_detergent] + * @param {number} options.miot_actions.reset_detergent.siid + * @param {number} options.miot_actions.reset_detergent.aiid + * * * @param {object} options.miot_properties * @param {object} options.miot_properties.main_brush @@ -47,6 +60,18 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit * @param {object} [options.miot_properties.sensor] * @param {number} options.miot_properties.sensor.siid * @param {number} options.miot_properties.sensor.piid + * + * @param {object} [options.miot_properties.mop] + * @param {number} options.miot_properties.mop.siid + * @param {number} options.miot_properties.mop.piid + * + * @param {object} [options.miot_properties.secondary_filter] + * @param {number} options.miot_properties.secondary_filter.siid + * @param {number} options.miot_properties.secondary_filter.piid + * + * @param {object} [options.miot_properties.detergent] + * @param {number} options.miot_properties.detergent.siid + * @param {number} options.miot_properties.detergent.piid */ constructor(options) { super(options); @@ -73,6 +98,18 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit props.push(this.miot_properties.sensor); } + if (this.miot_properties.mop) { + props.push(this.miot_properties.mop); + } + + if (this.miot_properties.secondary_filter) { + props.push(this.miot_properties.secondary_filter); + } + + if (this.miot_properties.detergent) { + props.push(this.miot_properties.detergent); + } + const response = await this.robot.sendCommand("get_properties", props.map(e => { return Object.assign({}, e, {did: this.robot.deviceId}); @@ -117,6 +154,9 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit case ConsumableStateAttribute.SUB_TYPE.MAIN: payload = this.miot_actions.reset_filter; break; + case ConsumableStateAttribute.SUB_TYPE.SECONDARY: + payload = this.miot_actions.reset_secondary_filter; + break; } break; case ConsumableStateAttribute.TYPE.SENSOR: @@ -128,7 +168,24 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit } } break; - + case ConsumableStateAttribute.TYPE.MOP: + if (this.miot_actions.reset_mop) { + switch (subType) { + case ConsumableStateAttribute.SUB_TYPE.ALL: + payload = this.miot_actions.reset_mop; + break; + } + } + break; + case ConsumableStateAttribute.TYPE.DETERGENT: + if (this.miot_actions.reset_detergent) { + switch (subType) { + case ConsumableStateAttribute.SUB_TYPE.MAIN: + payload = this.miot_actions.reset_detergent; + break; + } + } + break; } if (payload) { @@ -141,7 +198,7 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit } ).then(res => { if (res.code !== 0) { - throw new Error("Error code " + res.code + " while resetting consumable."); + throw new RobotFirmwareError("Error code " + res.code + " while resetting consumable."); } this.markEventsAsProcessed(type, subType); @@ -203,8 +260,11 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit } default: - if (this.miot_properties.sensor) { - if (msg.siid === this.miot_properties.sensor.siid && msg.piid === this.miot_properties.sensor.piid) { + if ( + this.miot_properties.sensor && + msg.siid === this.miot_properties.sensor.siid + ) { + if (msg.piid === this.miot_properties.sensor.piid) { consumable = new ConsumableStateAttribute({ type: ConsumableStateAttribute.TYPE.SENSOR, subType: ConsumableStateAttribute.SUB_TYPE.ALL, @@ -214,6 +274,48 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit } }); } + } else if ( + this.miot_properties.mop && + msg.siid === this.miot_properties.mop.siid + ) { + if (msg.piid === this.miot_properties.mop.piid) { + consumable = new ConsumableStateAttribute({ + type: ConsumableStateAttribute.TYPE.MOP, + subType: ConsumableStateAttribute.SUB_TYPE.ALL, + remaining: { + value: Math.round(Math.max(0, msg.value * 60)), + unit: ConsumableStateAttribute.UNITS.MINUTES + } + }); + } + } else if ( + this.miot_properties.secondary_filter && + msg.siid === this.miot_properties.secondary_filter.siid + ) { + if (msg.piid === this.miot_properties.secondary_filter.piid) { + consumable = new ConsumableStateAttribute({ + type: ConsumableStateAttribute.TYPE.FILTER, + subType: ConsumableStateAttribute.SUB_TYPE.SECONDARY, + remaining: { + value: Math.round(Math.max(0, msg.value * 60)), + unit: ConsumableStateAttribute.UNITS.MINUTES + } + }); + } + } else if ( + this.miot_properties.detergent && + msg.siid === this.miot_properties.detergent.siid + ) { + if (msg.piid === this.miot_properties.detergent.piid) { + consumable = new ConsumableStateAttribute({ + type: ConsumableStateAttribute.TYPE.DETERGENT, + subType: ConsumableStateAttribute.SUB_TYPE.NONE, + remaining: { + value: Math.max(0, msg.value), + unit: ConsumableStateAttribute.UNITS.PERCENT + } + }); + } } else { Logger.warn("Unhandled consumable update", msg); } @@ -255,6 +357,36 @@ class DreameConsumableMonitoringCapability extends ConsumableMonitoringCapabilit ); } + if (this.miot_properties.mop) { + availableConsumables.push( + { + type: ConsumableStateAttribute.TYPE.MOP, + subType: ConsumableStateAttribute.SUB_TYPE.ALL, + unit: ConsumableStateAttribute.UNITS.MINUTES + } + ); + } + + if (this.miot_properties.secondary_filter) { + availableConsumables.push( + { + type: ConsumableStateAttribute.TYPE.FILTER, + subType: ConsumableStateAttribute.SUB_TYPE.SECONDARY, + unit: ConsumableStateAttribute.UNITS.MINUTES + } + ); + } + + if (this.miot_properties.detergent) { + availableConsumables.push( + { + type: ConsumableStateAttribute.TYPE.DETERGENT, + subType: ConsumableStateAttribute.SUB_TYPE.NONE, + unit: ConsumableStateAttribute.UNITS.PERCENT + } + ); + } + return { availableConsumables: availableConsumables }; diff --git a/backend/lib/robots/dreame/capabilities/DreameManualControlCapability.js b/backend/lib/robots/dreame/capabilities/DreameManualControlCapability.js index 2f17f8dd..9c359540 100644 --- a/backend/lib/robots/dreame/capabilities/DreameManualControlCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameManualControlCapability.js @@ -11,7 +11,6 @@ class DreameManualControlCapability extends ManualControlCapability { /** * * @param {object} options - * @param {object} options.miot_properties * @param {object} options.miot_properties.manual_control * @param {number} options.miot_properties.manual_control.siid diff --git a/backend/lib/robots/dreame/capabilities/DreameMapResetCapability.js b/backend/lib/robots/dreame/capabilities/DreameMapResetCapability.js index 85f5c2af..0b793f87 100644 --- a/backend/lib/robots/dreame/capabilities/DreameMapResetCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameMapResetCapability.js @@ -1,4 +1,5 @@ const MapResetCapability = require("../../../core/capabilities/MapResetCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); /** * @extends MapResetCapability @@ -61,7 +62,7 @@ class DreameMapResetCapability extends MapResetCapability { this.robot.pollMap(); return; default: - throw new Error("Got error " + res.out[0].value + " while resetting map."); + throw new RobotFirmwareError("Got error " + res.out[0].value + " while resetting map."); } } diff --git a/backend/lib/robots/dreame/capabilities/DreameMapSegmentEditCapability.js b/backend/lib/robots/dreame/capabilities/DreameMapSegmentEditCapability.js index 43a254cc..c93acd4a 100644 --- a/backend/lib/robots/dreame/capabilities/DreameMapSegmentEditCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameMapSegmentEditCapability.js @@ -1,5 +1,6 @@ const DreameMapParser = require("../DreameMapParser"); const MapSegmentEditCapability = require("../../../core/capabilities/MapSegmentEditCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); /** * @extends MapSegmentEditCapability @@ -44,7 +45,7 @@ class DreameMapSegmentEditCapability extends MapSegmentEditCapability { { piid: this.miot_properties.mapDetails.piid, value: JSON.stringify({ - msr: [segmentA.id, segmentB.id] + msr: [parseInt(segmentA.id), parseInt(segmentB.id)] }) } ] @@ -63,9 +64,9 @@ class DreameMapSegmentEditCapability extends MapSegmentEditCapability { this.robot.pollMap(); return; case 1: - throw new Error("Segment join failed. Can't join segments that aren't adjacent to each other."); + throw new RobotFirmwareError("Segment join failed. Can't join segments that aren't adjacent to each other."); default: - throw new Error("Got error " + res.out[0].value + " while merging segments."); + throw new RobotFirmwareError("Got error " + res.out[0].value + " while merging segments."); } } } @@ -94,7 +95,7 @@ class DreameMapSegmentEditCapability extends MapSegmentEditCapability { piid: this.miot_properties.mapDetails.piid, value: JSON.stringify({ dsr: [pA.x, pA.y, pB.x, pB.y], - dsrid: [pA.x, pA.y, pB.x, pB.y, segment.id] + dsrid: [pA.x, pA.y, pB.x, pB.y, parseInt(segment.id)] }) } ] @@ -113,11 +114,11 @@ class DreameMapSegmentEditCapability extends MapSegmentEditCapability { this.robot.pollMap(); return; case 5: - throw new Error("Failed to split segment. Both ends of the cutting line need to be connected with a wall surrounding the chosen segment."); + throw new RobotFirmwareError("Failed to split segment. Both ends of the cutting line need to be connected with a wall surrounding the chosen segment."); case 6: - throw new Error("Failed to split segment. At least one of the resulting segments is too small."); + throw new RobotFirmwareError("Failed to split segment. At least one of the resulting segments is too small."); default: - throw new Error("Got error " + res.out[0].value + " while splitting segments."); + throw new RobotFirmwareError("Got error " + res.out[0].value + " while splitting segments."); } } } diff --git a/backend/lib/robots/dreame/capabilities/DreameMapSegmentRenameCapability.js b/backend/lib/robots/dreame/capabilities/DreameMapSegmentRenameCapability.js index 40e8bc92..37dc8162 100644 --- a/backend/lib/robots/dreame/capabilities/DreameMapSegmentRenameCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameMapSegmentRenameCapability.js @@ -1,4 +1,5 @@ const MapSegmentRenameCapability = require("../../../core/capabilities/MapSegmentRenameCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); /** * @extends MapSegmentRenameCapability @@ -67,7 +68,7 @@ class DreameMapSegmentRenameCapability extends MapSegmentRenameCapability { this.robot.pollMap(); return; default: - throw new Error("Got error " + res.out[0].value + " while naming segment."); + throw new RobotFirmwareError("Got error " + res.out[0].value + " while naming segment."); } } } diff --git a/backend/lib/robots/dreame/capabilities/DreameMopDockCleanManualTriggerCapability.js b/backend/lib/robots/dreame/capabilities/DreameMopDockCleanManualTriggerCapability.js new file mode 100644 index 00000000..a2484134 --- /dev/null +++ b/backend/lib/robots/dreame/capabilities/DreameMopDockCleanManualTriggerCapability.js @@ -0,0 +1,90 @@ +const BasicControlCapability = require("../../../core/capabilities/BasicControlCapability"); +const DreameMiotHelper = require("../DreameMiotHelper"); +const entities = require("../../../entities"); +const MopDockCleanManualTriggerCapability = require("../../../core/capabilities/MopDockCleanManualTriggerCapability"); + +/** + * @extends MopDockCleanManualTriggerCapability + */ +class DreameMopDockCleanManualTriggerCapability extends MopDockCleanManualTriggerCapability { + + /** + * @param {object} options + * @param {import("../DreameValetudoRobot")} options.robot + * + * @param {number} options.siid MIOT Service ID + * @param {number} options.aiid MIOT Action ID + * @param {object} options.additionalCleanupParametersPiid + * + */ + constructor(options) { + super(options); + + this.siid = options.siid; + this.aiid = options.aiid; + this.additionalCleanupParametersPiid = options.additionalCleanupParametersPiid; + + this.helper = new DreameMiotHelper({robot: this.robot}); + } + + /** + * @abstract + * @returns {Promise} + */ + async startCleaning() { + const StatusStateAttribute = this.robot.state.getFirstMatchingAttribute({ + attributeClass: entities.state.attributes.StatusStateAttribute.name, + }); + const DockStatusStateAttribute = this.robot.state.getFirstMatchingAttribute({ + attributeClass: entities.state.attributes.DockStatusStateAttribute.name, + }); + + if ( + StatusStateAttribute?.value === entities.state.attributes.StatusStateAttribute.VALUE.DOCKED && + DockStatusStateAttribute?.value === entities.state.attributes.DockStatusStateAttribute.VALUE.PAUSE + ) { + await this.getBasicControlCapability().stop(); + } + + + await this.helper.executeAction( + this.siid, + this.aiid, + [ + { + piid: this.additionalCleanupParametersPiid, + value: "1,1" + } + ] + ); + } + + /** + * @abstract + * @returns {Promise} + */ + async stopCleaning() { + await this.helper.executeAction( + this.siid, + this.aiid, + [ + { + piid: this.additionalCleanupParametersPiid, + value: "1,0" + } + ] + ); + + await this.getBasicControlCapability().stop(); + } + + /** + * @private + * @returns {import("./DreameBasicControlCapability")} + */ + getBasicControlCapability() { + return this.robot.capabilities[BasicControlCapability.TYPE]; + } +} + +module.exports = DreameMopDockCleanManualTriggerCapability; diff --git a/backend/lib/robots/dreame/capabilities/DreameMopDockDryManualTriggerCapability.js b/backend/lib/robots/dreame/capabilities/DreameMopDockDryManualTriggerCapability.js new file mode 100644 index 00000000..fbccb4fe --- /dev/null +++ b/backend/lib/robots/dreame/capabilities/DreameMopDockDryManualTriggerCapability.js @@ -0,0 +1,89 @@ +const BasicControlCapability = require("../../../core/capabilities/BasicControlCapability"); +const DreameMiotHelper = require("../DreameMiotHelper"); +const entities = require("../../../entities"); +const MopDockDryManualTriggerCapability = require("../../../core/capabilities/MopDockDryManualTriggerCapability"); + +/** + * @extends MopDockDryManualTriggerCapability + */ +class DreameMopDockDryManualTriggerCapability extends MopDockDryManualTriggerCapability { + + /** + * @param {object} options + * @param {import("../DreameValetudoRobot")} options.robot + * + * @param {number} options.siid MIOT Service ID + * @param {number} options.aiid MIOT Action ID + * @param {object} options.additionalCleanupParametersPiid + * + */ + constructor(options) { + super(options); + + this.siid = options.siid; + this.aiid = options.aiid; + this.additionalCleanupParametersPiid = options.additionalCleanupParametersPiid; + + this.helper = new DreameMiotHelper({robot: this.robot}); + } + + /** + * @abstract + * @returns {Promise} + */ + async startDrying() { + const StatusStateAttribute = this.robot.state.getFirstMatchingAttribute({ + attributeClass: entities.state.attributes.StatusStateAttribute.name, + }); + const DockStatusStateAttribute = this.robot.state.getFirstMatchingAttribute({ + attributeClass: entities.state.attributes.DockStatusStateAttribute.name, + }); + + if ( + StatusStateAttribute?.value === entities.state.attributes.StatusStateAttribute.VALUE.DOCKED && + DockStatusStateAttribute?.value === entities.state.attributes.DockStatusStateAttribute.VALUE.PAUSE + ) { + await this.getBasicControlCapability().stop(); + } + + await this.helper.executeAction( + this.siid, + this.aiid, + [ + { + piid: this.additionalCleanupParametersPiid, + value: "3,1" + } + ] + ); + } + + /** + * @abstract + * @returns {Promise} + */ + async stopDrying() { + await this.helper.executeAction( + this.siid, + this.aiid, + [ + { + piid: this.additionalCleanupParametersPiid, + value: "3,0" + } + ] + ); + + await this.getBasicControlCapability().stop(); + } + + /** + * @private + * @returns {import("./DreameBasicControlCapability")} + */ + getBasicControlCapability() { + return this.robot.capabilities[BasicControlCapability.TYPE]; + } +} + +module.exports = DreameMopDockDryManualTriggerCapability; diff --git a/backend/lib/robots/dreame/capabilities/DreameMopDockWaterUsageControlCapability.js b/backend/lib/robots/dreame/capabilities/DreameMopDockWaterUsageControlCapability.js new file mode 100644 index 00000000..7285943f --- /dev/null +++ b/backend/lib/robots/dreame/capabilities/DreameMopDockWaterUsageControlCapability.js @@ -0,0 +1,56 @@ +const DreameMiotHelper = require("../DreameMiotHelper"); +const DreameUtils = require("../DreameUtils"); +const WaterUsageControlCapability = require("../../../core/capabilities/WaterUsageControlCapability"); + +/** + * @extends WaterUsageControlCapability + */ +class DreameMopDockWaterUsageControlCapability extends WaterUsageControlCapability { + + /** + * @param {object} options + * @param {import("../DreameValetudoRobot")} options.robot + * @param {Array} options.presets + * + * @param {number} options.siid MIOT Service ID + * @param {number} options.piid MIOT Property ID + */ + constructor(options) { + super(options); + + this.siid = options.siid; + this.piid = options.piid; + + this.helper = new DreameMiotHelper({robot: this.robot}); + } + /** + * @param {string} preset + * @returns {Promise} + */ + async selectPreset(preset) { + const matchedPreset = this.presets.find(p => { + return p.name === preset; + }); + + if (matchedPreset) { + const res = await this.helper.readProperty(this.siid, this.piid); + + const deserializedResponse = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(res); + + return this.helper.writeProperty( + this.siid, + this.piid, + DreameUtils.SERIALIZE_MOP_DOCK_SETTINGS({ + waterGrade: matchedPreset.value, + padCleaningFrequency: deserializedResponse.padCleaningFrequency, + operationMode: deserializedResponse.operationMode + }) + ); + } else { + throw new Error("Invalid Preset"); + } + } + +} + +module.exports = DreameMopDockWaterUsageControlCapability; diff --git a/backend/lib/robots/dreame/capabilities/DreameOperationModeControlCapability.js b/backend/lib/robots/dreame/capabilities/DreameOperationModeControlCapability.js new file mode 100644 index 00000000..781f24db --- /dev/null +++ b/backend/lib/robots/dreame/capabilities/DreameOperationModeControlCapability.js @@ -0,0 +1,57 @@ +const DreameMiotHelper = require("../DreameMiotHelper"); +const DreameUtils = require("../DreameUtils"); +const OperationModeControlCapability = require("../../../core/capabilities/OperationModeControlCapability"); + +/** + * @extends OperationModeControlCapability + */ +class DreameOperationModeControlCapability extends OperationModeControlCapability { + + /** + * @param {object} options + * @param {import("../DreameValetudoRobot")} options.robot + * @param {Array} options.presets + * + * @param {number} options.siid MIOT Service ID + * @param {number} options.piid MIOT Property ID + */ + constructor(options) { + super(options); + + this.siid = options.siid; + this.piid = options.piid; + + this.helper = new DreameMiotHelper({robot: this.robot}); + } + + /** + * @param {string} preset + * @returns {Promise} + */ + async selectPreset(preset) { + const matchedPreset = this.presets.find(p => { + return p.name === preset; + }); + + if (matchedPreset) { + const res = await this.helper.readProperty(this.siid, this.piid); + + const deserializedResponse = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(res); + + return this.helper.writeProperty( + this.siid, + this.piid, + DreameUtils.SERIALIZE_MOP_DOCK_SETTINGS({ + waterGrade: deserializedResponse.waterGrade, + padCleaningFrequency: deserializedResponse.padCleaningFrequency, + operationMode: matchedPreset.value + }) + ); + } else { + throw new Error("Invalid Preset"); + } + } + +} + +module.exports = DreameOperationModeControlCapability; diff --git a/backend/lib/robots/dreame/capabilities/DreamePendingMapChangeHandlingCapability.js b/backend/lib/robots/dreame/capabilities/DreamePendingMapChangeHandlingCapability.js index 50d6db64..24d2e501 100644 --- a/backend/lib/robots/dreame/capabilities/DreamePendingMapChangeHandlingCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreamePendingMapChangeHandlingCapability.js @@ -1,4 +1,5 @@ const PendingMapChangeHandlingCapability = require("../../../core/capabilities/PendingMapChangeHandlingCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); /** @@ -83,7 +84,7 @@ class DreamePendingMapChangeHandlingCapability extends PendingMapChangeHandlingC this.robot.pollMap(); return; default: - throw new Error("Got error " + res.out[0].value + " while committing choice."); + throw new RobotFirmwareError("Got error " + res.out[0].value + " while committing choice."); } } } diff --git a/backend/lib/robots/dreame/capabilities/DreameVoicePackManagementCapability.js b/backend/lib/robots/dreame/capabilities/DreameVoicePackManagementCapability.js index 7ac6ce05..4d7f8f38 100644 --- a/backend/lib/robots/dreame/capabilities/DreameVoicePackManagementCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameVoicePackManagementCapability.js @@ -56,7 +56,7 @@ class DreameVoicePackManagementCapability extends VoicePackManagementCapability this.install_voicepack_piid, JSON.stringify({ id: typeof options.language === "string" ? options.language.toUpperCase() : "VA", - md5: options.hash, //MD5 is actually validated on dreame + md5: options.hash?.toLowerCase(), //MD5 is actually validated on dreame url: options.url, size: 1 //This doesn't need to be correct. it just needs to be set }) diff --git a/backend/lib/robots/dreame/capabilities/DreameWaterUsageControlCapability.js b/backend/lib/robots/dreame/capabilities/DreameWaterUsageControlCapability.js index c8f2d56e..d545fcf1 100644 --- a/backend/lib/robots/dreame/capabilities/DreameWaterUsageControlCapability.js +++ b/backend/lib/robots/dreame/capabilities/DreameWaterUsageControlCapability.js @@ -32,7 +32,7 @@ class DreameWaterUsageControlCapability extends WaterUsageControlCapability { }); if (matchedPreset) { - await this.helper.writeProperty(this.siid, this.piid, matchedPreset.value); + return this.helper.writeProperty(this.siid, this.piid, matchedPreset.value); } else { throw new Error("Invalid Preset"); } diff --git a/backend/lib/robots/dreame/capabilities/index.js b/backend/lib/robots/dreame/capabilities/index.js index 76d4dc36..943a78ee 100644 --- a/backend/lib/robots/dreame/capabilities/index.js +++ b/backend/lib/robots/dreame/capabilities/index.js @@ -4,6 +4,7 @@ module.exports = { Dreame1CManualControlCapability: require("./Dreame1CManualControlCapability"), Dreame1CVoicePackManagementCapability: require("./Dreame1CVoicePackManagementCapability"), Dreame1CZoneCleaningCapability: require("./Dreame1CZoneCleaningCapability"), + DreameAICameraGoToLocationCapability: require("./DreameAICameraGoToLocationCapability"), DreameAutoEmptyDockAutoEmptyControlCapability: require("./DreameAutoEmptyDockAutoEmptyControlCapability"), DreameAutoEmptyDockManualTriggerCapability: require("./DreameAutoEmptyDockManualTriggerCapability"), DreameBasicControlCapability: require("./DreameBasicControlCapability"), @@ -21,6 +22,10 @@ module.exports = { DreameMapSegmentRenameCapability: require("./DreameMapSegmentRenameCapability"), DreameMapSegmentationCapability: require("./DreameMapSegmentationCapability"), DreameMappingPassCapability: require("./DreameMappingPassCapability"), + DreameMopDockCleanManualTriggerCapability: require("./DreameMopDockCleanManualTriggerCapability"), + DreameMopDockDryManualTriggerCapability: require("./DreameMopDockDryManualTriggerCapability"), + DreameMopDockWaterUsageControlCapability: require("./DreameMopDockWaterUsageControlCapability"), + DreameOperationModeControlCapability: require("./DreameOperationModeControlCapability"), DreamePendingMapChangeHandlingCapability: require("./DreamePendingMapChangeHandlingCapability"), DreamePersistentMapControlCapability: require("./DreamePersistentMapControlCapability"), DreameSpeakerTestCapability: require("./DreameSpeakerTestCapability"), @@ -28,5 +33,5 @@ module.exports = { DreameTotalStatisticsCapability: require("./DreameTotalStatisticsCapability"), DreameVoicePackManagementCapability: require("./DreameVoicePackManagementCapability"), DreameWaterUsageControlCapability: require("./DreameWaterUsageControlCapability"), - DreameZoneCleaningCapability: require("./DreameZoneCleaningCapability") + DreameZoneCleaningCapability: require("./DreameZoneCleaningCapability"), }; diff --git a/backend/lib/robots/dreame/index.js b/backend/lib/robots/dreame/index.js index a6f69f52..3188a280 100644 --- a/backend/lib/robots/dreame/index.js +++ b/backend/lib/robots/dreame/index.js @@ -1,10 +1,15 @@ module.exports = { "Dreame1CValetudoRobot": require("./Dreame1CValetudoRobot"), "Dreame1TValetudoRobot": require("./Dreame1TValetudoRobot"), + "DreameD9ProPlusValetudoRobot": require("./DreameD9ProPlusValetudoRobot"), "DreameD9ProValetudoRobot": require("./DreameD9ProValetudoRobot"), "DreameD9ValetudoRobot": require("./DreameD9ValetudoRobot"), "DreameF9ValetudoRobot": require("./DreameF9ValetudoRobot"), "DreameL10ProValetudoRobot": require("./DreameL10ProValetudoRobot"), + "DreameL10SUltraValetudoRobot": require("./DreameL10SUltraValetudoRobot"), "DreameMovaZ500ValetudoRobot": require("./DreameMovaZ500ValetudoRobot"), + "DreameP2148ValetudoRobot": require("./DreameP2148ValetudoRobot"), + "DreameP2149ValetudoRobot": require("./DreameP2149ValetudoRobot"), + "DreameW10ValetudoRobot": require("./DreameW10ValetudoRobot"), "DreameZ10ProValetudoRobot": require("./DreameZ10ProValetudoRobot") }; diff --git a/backend/lib/robots/mock/MockRobot.js b/backend/lib/robots/mock/MockRobot.js index 12624e13..1a618e83 100644 --- a/backend/lib/robots/mock/MockRobot.js +++ b/backend/lib/robots/mock/MockRobot.js @@ -1,10 +1,13 @@ const capabilities = require("./capabilities"); const DustBinFullValetudoEvent = require("../../valetudo_events/events/DustBinFullValetudoEvent"); +const entities = require("../../entities"); const ErrorStateValetudoEvent = require("../../valetudo_events/events/ErrorStateValetudoEvent"); const MopAttachmentReminderValetudoEvent = require("../../valetudo_events/events/MopAttachmentReminderValetudoEvent"); const PendingMapChangeValetudoEvent = require("../../valetudo_events/events/PendingMapChangeValetudoEvent"); +const Tools = require("../../utils/Tools"); const ValetudoRobot = require("../../core/ValetudoRobot"); const { MapLayer, PointMapEntity, ValetudoMap } = require("../../entities/map"); +const stateAttrs = entities.state.attributes; class MockRobot extends ValetudoRobot { /** @@ -59,6 +62,36 @@ class MockRobot extends ValetudoRobot { return "MockRobot"; } + getModelDetails() { + return Object.assign( + {}, + super.getModelDetails(), + { + supportedAttachments: [ + stateAttrs.AttachmentStateAttribute.TYPE.DUSTBIN, + stateAttrs.AttachmentStateAttribute.TYPE.WATERTANK, + stateAttrs.AttachmentStateAttribute.TYPE.MOP, + ] + } + ); + } + + /** + * @return {object} + */ + getProperties() { + const superProps = super.getProperties(); + const ourProps = { + [ValetudoRobot.WELL_KNOWN_PROPERTIES.FIRMWARE_VERSION]: Tools.GET_VALETUDO_VERSION() + }; + + return Object.assign( + {}, + superProps, + ourProps + ); + } + /** * @public */ diff --git a/backend/lib/robots/roborock/RoborockGen4ValetudoRobot.js b/backend/lib/robots/roborock/RoborockGen4ValetudoRobot.js index 185537e8..a11b8620 100644 --- a/backend/lib/robots/roborock/RoborockGen4ValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockGen4ValetudoRobot.js @@ -90,6 +90,7 @@ class RoborockGen4ValetudoRobot extends RoborockValetudoRobot { * @param {object} options * @param {import("../../Configuration")} options.config * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + * @param {Array} [options.supportedAttachments] */ constructor(options) { super(Object.assign({}, options, {fanSpeeds: FAN_SPEEDS})); @@ -111,8 +112,8 @@ class RoborockGen4ValetudoRobot extends RoborockValetudoRobot { })); } - onMessage(msg) { - if (super.onMessage(msg) === true) { + onIncomingCloudMessage(msg) { + if (super.onIncomingCloudMessage(msg) === true) { return true; } @@ -170,10 +171,12 @@ class RoborockGen4ValetudoRobot extends RoborockValetudoRobot { switch (msg.piid) { // error event case MIOT_SERVICES.VACUUM_2.PROPERTIES.ERROR_CODE.PIID: - this.parseAndUpdateState({ - state: 12, // error value - error_code: msg.value - }); + if (msg.value !== 0) { + this.parseAndUpdateState({ + state: 12, // error value + error_code: msg.value + }); + } return; case MIOT_SERVICES.VACUUM_2.PROPERTIES.CONSUMABLE_ID.PIID: // consumable reminder event case MIOT_SERVICES.VACUUM_2.PROPERTIES.FAILED_REASON.PIID: // schedule cancled event @@ -195,7 +198,7 @@ class RoborockGen4ValetudoRobot extends RoborockValetudoRobot { // the consumables only reports percent through this property, ignore return; } - Logger.info("Unknown property change message received:", JSON.stringify(msg)); + Logger.info("Unknown property change message received:", msg); } } diff --git a/backend/lib/robots/roborock/RoborockM1SValetudoRobot.js b/backend/lib/robots/roborock/RoborockM1SValetudoRobot.js new file mode 100644 index 00000000..27134b29 --- /dev/null +++ b/backend/lib/robots/roborock/RoborockM1SValetudoRobot.js @@ -0,0 +1,67 @@ +const capabilities = require("./capabilities"); +const entities = require("../../entities"); +const MiioValetudoRobot = require("../MiioValetudoRobot"); +const RoborockValetudoRobot = require("./RoborockValetudoRobot"); + + +class RoborockM1SValetudoRobot extends RoborockValetudoRobot { + /** + * + * @param {object} options + * @param {import("../../Configuration")} options.config + * @param {import("../../ValetudoEventStore")} options.valetudoEventStore + */ + constructor(options) { + super(Object.assign({}, options, {fanSpeeds: FAN_SPEEDS})); + + this.registerCapability(new capabilities.RoborockMapSnapshotCapability({ + robot: this + })); + this.registerCapability(new capabilities.RoborockCombinedVirtualRestrictionsCapability({ + robot: this + })); + this.registerCapability(new capabilities.RoborockPersistentMapControlCapability({ + robot: this + })); + this.registerCapability(new capabilities.RoborockMapResetCapability({ + robot: this + })); + this.registerCapability(new capabilities.RoborockMapSegmentSimpleCapability({ + robot: this + })); + this.registerCapability(new capabilities.RoborockMapSegmentEditCapability({ + robot: this + })); + this.registerCapability(new capabilities.RoborockMapSegmentRenameCapability({ + robot: this + })); + } + + setEmbeddedParameters() { + this.deviceConfPath = RoborockM1SValetudoRobot.DEVICE_CONF_PATH; + this.tokenFilePath = RoborockM1SValetudoRobot.TOKEN_FILE_PATH; + } + + getModelName() { + return "M1S"; + } + + static IMPLEMENTATION_AUTO_DETECTION_HANDLER() { + const deviceConf = MiioValetudoRobot.READ_DEVICE_CONF(RoborockValetudoRobot.DEVICE_CONF_PATH); + + return !!(deviceConf && deviceConf.model === "roborock.vacuum.m1s"); + } +} + +RoborockM1SValetudoRobot.DEVICE_CONF_PATH = "/mnt/default/device.conf"; +RoborockM1SValetudoRobot.TOKEN_FILE_PATH = "/data/miio/device.token"; + +const FAN_SPEEDS = { + [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.LOW]: 101, + [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.MEDIUM]: 102, + [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.HIGH]: 103, + [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.MAX]: 104, + [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.OFF] : 105 //also known as mop mode +}; + +module.exports = RoborockM1SValetudoRobot; diff --git a/backend/lib/robots/roborock/RoborockMapParser.js b/backend/lib/robots/roborock/RoborockMapParser.js index 2a289b46..fd62e0c0 100644 --- a/backend/lib/robots/roborock/RoborockMapParser.js +++ b/backend/lib/robots/roborock/RoborockMapParser.js @@ -317,7 +317,7 @@ class RoborockMapParser { if (segmentsCount > 0) { for (let i = 0; i < block.data_length; i++) { - segments.push(block.view.readUInt8(0x0c + i)); + segments.push(block.view.readUInt8(0x0c + i).toString()); } return segments; @@ -356,12 +356,11 @@ class RoborockMapParser { ); } - Object.keys(blocks[BlockTypes.IMAGE].segments).forEach(k => { - if (blocks[BlockTypes.IMAGE].segments[k].length === 0) { + Object.keys(blocks[BlockTypes.IMAGE].segments).forEach(segmentId => { + if (blocks[BlockTypes.IMAGE].segments[segmentId].length === 0) { return; } - const segmentId = parseInt(k); let isActive = false; if (blocks[BlockTypes.CURRENTLY_CLEANED_SEGMENTS]) { @@ -369,7 +368,7 @@ class RoborockMapParser { } layers.push(new Map.MapLayer({ - pixels: blocks[BlockTypes.IMAGE].segments[k].sort(Map.MapLayer.COORDINATE_TUPLE_SORT).flat(), + pixels: blocks[BlockTypes.IMAGE].segments[segmentId].sort(Map.MapLayer.COORDINATE_TUPLE_SORT).flat(), type: Map.MapLayer.TYPE.SEGMENT, metaData: { segmentId: segmentId, diff --git a/backend/lib/robots/roborock/RoborockS5MaxValetudoRobot.js b/backend/lib/robots/roborock/RoborockS5MaxValetudoRobot.js index 55bd6d68..3d5445e6 100644 --- a/backend/lib/robots/roborock/RoborockS5MaxValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS5MaxValetudoRobot.js @@ -14,7 +14,17 @@ class RoborockS5MaxValetudoRobot extends RoborockValetudoRobot { * @param {import("../../ValetudoEventStore")} options.valetudoEventStore */ constructor(options) { - super(Object.assign({}, options, {fanSpeeds: FAN_SPEEDS, waterGrades: WATER_GRADES})); + super( + Object.assign( + {}, + options, + { + fanSpeeds: FAN_SPEEDS, + waterGrades: WATER_GRADES, + supportedAttachments: SUPPORTED_ATTACHMENTS + } + ) + ); this.registerCapability(new capabilities.RoborockCombinedVirtualRestrictionsCapability({ robot: this, @@ -46,16 +56,6 @@ class RoborockS5MaxValetudoRobot extends RoborockValetudoRobot { }) })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: false - })); - const quirkFactory = new RoborockQuirkFactory({ robot: this }); @@ -93,4 +93,9 @@ const WATER_GRADES = { [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.HIGH]: 203 }; +const SUPPORTED_ATTACHMENTS = [ + entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, +]; + module.exports = RoborockS5MaxValetudoRobot; diff --git a/backend/lib/robots/roborock/RoborockS5ValetudoRobot.js b/backend/lib/robots/roborock/RoborockS5ValetudoRobot.js index a47b5127..c2d36866 100644 --- a/backend/lib/robots/roborock/RoborockS5ValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS5ValetudoRobot.js @@ -38,16 +38,6 @@ class RoborockS5ValetudoRobot extends RoborockValetudoRobot { robot: this })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: false - })); - const quirkFactory = new RoborockQuirkFactory({ robot: this }); diff --git a/backend/lib/robots/roborock/RoborockS6MaxVValetudoRobot.js b/backend/lib/robots/roborock/RoborockS6MaxVValetudoRobot.js index 869ef492..9af4c386 100644 --- a/backend/lib/robots/roborock/RoborockS6MaxVValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS6MaxVValetudoRobot.js @@ -15,7 +15,18 @@ class RoborockS6MaxVValetudoRobot extends RoborockValetudoRobot { * @param {import("../../ValetudoEventStore")} options.valetudoEventStore */ constructor(options) { - super(Object.assign({}, options, {fanSpeeds: FAN_SPEEDS, waterGrades: WATER_GRADES})); + super( + Object.assign( + {}, + options, + { + fanSpeeds: FAN_SPEEDS, + waterGrades: WATER_GRADES, + supportedAttachments: SUPPORTED_ATTACHMENTS + } + ) + ); + this.registerCapability(new capabilities.RoborockCombinedVirtualRestrictionsCapability({ robot: this, @@ -46,17 +57,6 @@ class RoborockS6MaxVValetudoRobot extends RoborockValetudoRobot { }) })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: false - })); - const quirkFactory = new RoborockQuirkFactory({ robot: this }); @@ -94,4 +94,9 @@ const WATER_GRADES = { [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.HIGH]: 203 }; +const SUPPORTED_ATTACHMENTS = [ + entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, +]; + module.exports = RoborockS6MaxVValetudoRobot; diff --git a/backend/lib/robots/roborock/RoborockS6PureValetudoRobot.js b/backend/lib/robots/roborock/RoborockS6PureValetudoRobot.js index 886d4554..ade4f698 100644 --- a/backend/lib/robots/roborock/RoborockS6PureValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS6PureValetudoRobot.js @@ -34,16 +34,6 @@ class RoborockS6PureValetudoRobot extends RoborockValetudoRobot { robot: this })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: false - })); - const quirkFactory = new RoborockQuirkFactory({ robot: this }); diff --git a/backend/lib/robots/roborock/RoborockS6ValetudoRobot.js b/backend/lib/robots/roborock/RoborockS6ValetudoRobot.js index 8190fe96..53bb5ef1 100644 --- a/backend/lib/robots/roborock/RoborockS6ValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS6ValetudoRobot.js @@ -42,16 +42,6 @@ class RoborockS6ValetudoRobot extends RoborockValetudoRobot { robot: this })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: false - })); - const quirkFactory = new RoborockQuirkFactory({ robot: this }); diff --git a/backend/lib/robots/roborock/RoborockS7ValetudoRobot.js b/backend/lib/robots/roborock/RoborockS7ValetudoRobot.js index e7d28a20..7b9a1136 100644 --- a/backend/lib/robots/roborock/RoborockS7ValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockS7ValetudoRobot.js @@ -15,7 +15,17 @@ class RoborockS7ValetudoRobot extends RoborockGen4ValetudoRobot { * @param {import("../../ValetudoEventStore")} options.valetudoEventStore */ constructor(options) { - super(Object.assign({}, options, {waterGrades: WATER_GRADES})); + super( + Object.assign( + {}, + options, + { + waterGrades: WATER_GRADES, + supportedAttachments: SUPPORTED_ATTACHMENTS + } + ) + ); + this.registerCapability(new capabilities.RoborockCombinedVirtualRestrictionsCapability({ robot: this, @@ -32,16 +42,6 @@ class RoborockS7ValetudoRobot extends RoborockGen4ValetudoRobot { }) })); - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, - attached: false - })); - - this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ - type: entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, - attached: false - })); - [ capabilities.RoborockKeyLockCapability, ].forEach(capability => { @@ -78,5 +78,10 @@ const WATER_GRADES = { [entities.state.attributes.PresetSelectionStateAttribute.INTENSITY.HIGH]: 203 }; +const SUPPORTED_ATTACHMENTS = [ + entities.state.attributes.AttachmentStateAttribute.TYPE.WATERTANK, + entities.state.attributes.AttachmentStateAttribute.TYPE.MOP, +]; + module.exports = RoborockS7ValetudoRobot; diff --git a/backend/lib/robots/roborock/RoborockValetudoRobot.js b/backend/lib/robots/roborock/RoborockValetudoRobot.js index 4579b3eb..1ea2f620 100644 --- a/backend/lib/robots/roborock/RoborockValetudoRobot.js +++ b/backend/lib/robots/roborock/RoborockValetudoRobot.js @@ -6,13 +6,14 @@ const zlib = require("zlib"); const DustBinFullValetudoEvent = require("../../valetudo_events/events/DustBinFullValetudoEvent"); const entities = require("../../entities"); +const LinuxTools = require("../../utils/LinuxTools"); const LinuxWifiScanCapability = require("../common/linuxCapabilities/LinuxWifiScanCapability"); const MapLayer = require("../../entities/map/MapLayer"); const MiioValetudoRobot = require("../MiioValetudoRobot"); const PendingMapChangeValetudoEvent = require("../../valetudo_events/events/PendingMapChangeValetudoEvent"); -const Tools = require("../../Tools"); const ValetudoMap = require("../../entities/map/ValetudoMap"); const ValetudoRobot = require("../../core/ValetudoRobot"); +const ValetudoRobotError = require("../../entities/core/ValetudoRobotError"); const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); const stateAttrs = entities.state.attributes; @@ -25,13 +26,21 @@ class RoborockValetudoRobot extends MiioValetudoRobot { * @param {import("../../ValetudoEventStore")} options.valetudoEventStore * @param {object} options.fanSpeeds * @param {object} [options.waterGrades] + * @param {Array} [options.supportedAttachments] */ constructor(options) { super(options); - this.lastMapPoll = new Date(0); this.fanSpeeds = options.fanSpeeds; this.waterGrades = options.waterGrades ?? {}; + this.supportedAttachments = options.supportedAttachments ?? []; + + this.supportedAttachments.forEach(attachmentType => { + this.state.upsertFirstMatchingAttribute(new entities.state.attributes.AttachmentStateAttribute({ + type: attachmentType, + attached: false + })); + }); this.registerCapability(new capabilities.RoborockFanSpeedControlCapability({ robot: this, @@ -69,11 +78,6 @@ class RoborockValetudoRobot extends MiioValetudoRobot { networkInterface: "wlan0" })); } - - this.state.upsertFirstMatchingAttribute(new stateAttrs.AttachmentStateAttribute({ - type: stateAttrs.AttachmentStateAttribute.TYPE.DUSTBIN, - attached: true - })); } setEmbeddedParameters() { @@ -82,7 +86,7 @@ class RoborockValetudoRobot extends MiioValetudoRobot { } - onMessage(msg) { + onIncomingCloudMessage(msg) { switch (msg.method) { case "props": this.parseAndUpdateState(msg.params); @@ -130,17 +134,13 @@ class RoborockValetudoRobot extends MiioValetudoRobot { if (Array.isArray(msg.params?.indexes)) { msg.params.indexes.forEach(idx => { mapUploadUrls.push( - this.mapUploadUrlPrefix + - "/api/miio/map_upload_handler/" + filename + "_" + idx + "?" + - process.hrtime().toString().replace(/,/g, "") + `${this.mapUploadUrlPrefix}/api/miio/fds_upload_handler/${filename}_${idx}?${process.hrtime().toString().replace(/,/g, "")}` ); }); } else { for (let i = 0; i < 4; i++) { mapUploadUrls.push( - this.mapUploadUrlPrefix + - "/api/miio/map_upload_handler/" + filename + "_" + i + "?" + - process.hrtime().toString().replace(/,/g, "") + `${this.mapUploadUrlPrefix}/api/miio/fds_upload_handler/${filename}_${i}?${process.hrtime().toString().replace(/,/g, "")}` ); } } @@ -172,6 +172,7 @@ class RoborockValetudoRobot extends MiioValetudoRobot { case "event.zoned_clean_partial_done": case "event.zoned_clean_failed": case "event.relocate_fail": + case "event.fan_power_reduced": case "event.low_power_back": //If the robot is currently cleaning and the battery drops below 20% it drives home to charge this.sendCloud({id: msg.id, result: "ok"}); return true; @@ -197,6 +198,7 @@ class RoborockValetudoRobot extends MiioValetudoRobot { if (data["state"] !== undefined && STATUS_MAP[data["state"]]) { let statusValue = STATUS_MAP[data["state"]].value; let statusFlag = STATUS_MAP[data["state"]].flag; + let statusError = undefined; let statusMetaData = {}; if ( @@ -209,20 +211,39 @@ class RoborockValetudoRobot extends MiioValetudoRobot { ) { statusFlag = stateAttrs.StatusStateAttribute.FLAG.RESUMABLE; - if (data["in_cleaning"] === 2) { + if (data["in_cleaning"] === undefined) { + const previousState = this.state.getFirstMatchingAttributeByConstructor(stateAttrs.StatusStateAttribute); + + // keep statusFlag and metaData from previous state + if (previousState && + ( + previousState.value === stateAttrs.StatusStateAttribute.VALUE.PAUSED || + previousState.value === stateAttrs.StatusStateAttribute.VALUE.RETURNING || + previousState.value === stateAttrs.StatusStateAttribute.VALUE.DOCKED + ) + ) { + statusFlag = previousState.flag; + + if (previousState.metaData.zoned === true) { + statusMetaData.zoned = true; + } else if (previousState.metaData.segment_cleaning === true) { + statusMetaData.segment_cleaning = true; + } + } + } else if (data["in_cleaning"] === 2) { //Since this is some roborock-related weirdness, we're using the metaData to store this statusMetaData.zoned = true; } else if (data["in_cleaning"] === 3) { statusMetaData.segment_cleaning = true; } } else if (statusValue === stateAttrs.StatusStateAttribute.VALUE.ERROR) { - statusMetaData.error_code = data["error_code"]; - statusMetaData.error_description = GET_ERROR_CODE_DESCRIPTION(data["error_code"]); + statusError = RoborockValetudoRobot.MAP_ERROR_CODE(data["error_code"]); } newStateAttr = new stateAttrs.StatusStateAttribute({ value: statusValue, flag: statusFlag, + error: statusError, metaData: statusMetaData }); @@ -263,27 +284,40 @@ class RoborockValetudoRobot extends MiioValetudoRobot { } if (data["lab_status"] !== undefined && this.hasCapability(capabilities.RoborockPersistentMapControlCapability.TYPE)) { - this.capabilities[capabilities.RoborockPersistentMapControlCapability.TYPE].persistentMapState = data["lab_status"] === 1; + /* + lab_status is a byte that consists of + + XXXXXXMP + + X is currently (2022-02-21) unused + M is the multi-map flag + P is the persistent-map flag + */ + + this.labStatus = { + persistentMapEnabled: !!(data["lab_status"] & 0b00000001), + multiMapEnabled: !!(data["lab_status"] & 0b00000010) + }; } - if (data["water_box_status"] !== undefined) { + if ( + data["water_box_status"] !== undefined && + this.supportedAttachments.includes(stateAttrs.AttachmentStateAttribute.TYPE.WATERTANK) + ) { this.state.upsertFirstMatchingAttribute(new stateAttrs.AttachmentStateAttribute({ type: stateAttrs.AttachmentStateAttribute.TYPE.WATERTANK, attached: data["water_box_status"] === 1 })); + } - if (data["water_box_carriage_status"] !== undefined) { - this.state.upsertFirstMatchingAttribute(new stateAttrs.AttachmentStateAttribute({ - type: stateAttrs.AttachmentStateAttribute.TYPE.MOP, - attached: data["water_box_carriage_status"] === 1 - })); - } else { - this.state.upsertFirstMatchingAttribute(new stateAttrs.AttachmentStateAttribute({ - type: stateAttrs.AttachmentStateAttribute.TYPE.MOP, - attached: data["water_box_status"] === 1 - })); - } - + if ( + data["water_box_carriage_status"] !== undefined && + this.supportedAttachments.includes(stateAttrs.AttachmentStateAttribute.TYPE.MOP) + ) { + this.state.upsertFirstMatchingAttribute(new stateAttrs.AttachmentStateAttribute({ + type: stateAttrs.AttachmentStateAttribute.TYPE.MOP, + attached: data["water_box_carriage_status"] === 1 + })); } //data["dnd_enabled"] @@ -320,65 +354,47 @@ class RoborockValetudoRobot extends MiioValetudoRobot { } if (data["map_status"] !== undefined) { - this.mapStatus = data["map_status"]; - } + /* + map_status is a byte that consists of - this.emitStateAttributesUpdated(); - } - - pollMap() { - // Guard against multiple concurrent polls. - if (this.pollingMap) { - return; - } + IIIIIISM - const now = new Date(); - if (now.getTime() - 600 > this.lastMapPoll.getTime()) { - this.pollingMap = true; - this.lastMapPoll = now; - - // Clear pending timeout, since we’re starting a new poll right now. - if (this.pollMapTimeout) { - clearTimeout(this.pollMapTimeout); - } + I being all part of the current mapId 0-63 + S being a "segment present" flag + M being a "map present" flag + */ - this.sendCloud({"method": "get_map_v1"}).then(res => { - if (res?.length === 1) { - let repollSeconds = this.mapPollingIntervals.default; + this.mapStatus = { + mapPresent: !!(data["map_status"] & 0b00000001), + segmentsPresent: !!(data["map_status"] & 0b00000010), + mapSlotId: data["map_status"] >> 2 + }; + } - let StatusStateAttribute = this.state.getFirstMatchingAttribute({ - attributeClass: stateAttrs.StatusStateAttribute.name - }); + this.emitStateAttributesUpdated(); + } - if (StatusStateAttribute && StatusStateAttribute.isActiveState) { - repollSeconds = this.mapPollingIntervals.active; - } + async executeMapPoll() { + return this.sendCloud({"method": "get_map_v1"}); + } - if (res && res[0] === "retry") { - /** - * This fixes the map not being available on boot for another 60 seconds which is annoying - */ - if (this.state.map?.metaData?.defaultMap !== true) { - repollSeconds += 1; - } else { - repollSeconds = this.mapPollingIntervals.active; - } - } + determineNextMapPollInterval(pollResponse) { + let repollSeconds = super.determineNextMapPollInterval(); - setTimeout(() => { - return this.pollMap(); - }, repollSeconds * 1000); + if (pollResponse?.length === 1) { + if (pollResponse && pollResponse[0] === "retry") { + /** + * This fixes the map not being available on boot for another 60 seconds + */ + if (this.state.map?.metaData?.defaultMap !== true) { + repollSeconds += 1; + } else { + repollSeconds = this.mapPollingIntervals.active; } - }, err => { - // ¯\_(ツ)_/¯ - }).finally(() => { - this.pollingMap = false; - }); + } } - this.pollMapTimeout = setTimeout(() => { - return this.pollMap(); - }, 5 * 60 * 1000); // 5 minutes + return repollSeconds; } preprocessMap(data) { @@ -429,13 +445,13 @@ class RoborockValetudoRobot extends MiioValetudoRobot { try { - const {partitions, rootPartition} = Tools.PARSE_PROC_CMDLINE(); + const parsedCmdline = LinuxTools.READ_PROC_CMDLINE(); - if (partitions[rootPartition]) { - Logger.info(`Current rootfs: ${partitions[rootPartition]} (${rootPartition})`); + if (parsedCmdline.partitions[parsedCmdline.root]) { + Logger.info(`Current rootfs: ${parsedCmdline.partitions[parsedCmdline.root]} (${parsedCmdline.root})`); } } catch (e) { - Logger.warn("Unable to parse /proc/cmdline", e); + Logger.warn("Unable to read /proc/cmdline", e); } } } @@ -465,6 +481,16 @@ class RoborockValetudoRobot extends MiioValetudoRobot { } } + getModelDetails() { + return Object.assign( + {}, + super.getModelDetails(), + { + supportedAttachments: this.supportedAttachments + } + ); + } + /** * @return {object} */ @@ -565,44 +591,329 @@ const STATUS_MAP = { } }; -const ERROR_CODES = { - 0: "No error", - 1: "LDS jammed", - 2: "Stuck front bumper", - 3: "Wheel lost floor contact. Robot is on the verge of falling", - 4: "Cliff sensor dirty or robot on the verge of falling", - 5: "Main brush jammed", - 6: "Side brush jammed", - 7: "Wheel jammed", - 8: "Robot stuck or trapped", - 9: "Dustbin missing", - 10: "Filter jammed", - 11: "Magnetic interference", - 12: "Low battery", - 13: "Charging issues", - 14: "Battery temperature out of operating range", - 15: "Wall sensor dirty", - 16: "Tilted robot", - 17: "Side brush error. Reboot required", - 18: "Fan error. Reboot required", - 19: "Charging station without power", - 21: "LDS bumper jammed", - 22: "Charging contacts dirty", - 23: "Charging station dirty", - 24: "Stuck inside restricted area", - 25: "Camera dirty", - 26: "Wall sensor dirty", - 29: "Animal excrements detected" - - //TODO: there are also 100+ codes. No idea when they might appear though -}; - -const GET_ERROR_CODE_DESCRIPTION = (errorCodeId) => { - if (ERROR_CODES[errorCodeId] !== undefined) { - return ERROR_CODES[errorCodeId]; - } else { - return "UNKNOWN ERROR CODE " + errorCodeId; +/** + * + * @param {number} vendorErrorCode + * + * @returns {ValetudoRobotError} + */ +RoborockValetudoRobot.MAP_ERROR_CODE = (vendorErrorCode) => { + const parameters = { + severity: { + kind: ValetudoRobotError.SEVERITY_KIND.UNKNOWN, + level: ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN, + }, + subsystem: ValetudoRobotError.SUBSYSTEM.UNKNOWN, + message: `Unknown error ${vendorErrorCode}`, + vendorErrorCode: typeof vendorErrorCode === "number" ? vendorErrorCode.toString() : `unknown (${vendorErrorCode})` + }; + + switch (vendorErrorCode) { + case 0: + parameters.message = "No error"; + break; + case 1: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "LDS jammed"; + break; + case 2: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Stuck front bumper"; + break; + case 3: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "Wheel lost floor contact"; + break; + case 4: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Cliff sensor dirty or robot on the verge of falling"; + break; + case 5: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Main brush jammed"; + break; + case 6: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Side brush jammed"; + break; + case 7: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Wheel jammed"; + break; + case 8: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Robot stuck or trapped"; + break; + case 9: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Dustbin missing"; + break; + case 10: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.ATTACHMENTS; + parameters.message = "Filter jammed"; + break; + case 11: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.INFO; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Magnetic interference"; + break; + case 12: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.INFO; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Low battery"; + break; + case 13: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging error"; + break; + case 14: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Battery temperature out of operating range"; + break; + case 15: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Wall sensor dirty"; + break; + case 16: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Tilted robot"; + break; + case 17: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Side brush error. Reboot required"; + break; + case 18: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Fan error. Reboot required"; + break; + case 19: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging station without power"; + break; + //20? + case 21: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "LDS bumper jammed"; + break; + case 22: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging contacts dirty"; + break; + case 23: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.ERROR; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging station dirty"; + break; + case 24: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.NAVIGATION; + parameters.message = "Stuck inside restricted area"; + break; + case 25: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Camera dirty"; + break; + case 26: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.WARNING; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Wall sensor dirty"; + break; + //27? + //28? + case 29: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.TRANSIENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.UNKNOWN; + parameters.message = "Animal excrements detected"; + break; + + + case 100: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.UNKNOWN; + parameters.message = "Unknown hardware fault"; + break; + case 101: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Compass fault"; + break; + case 102: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.UNKNOWN; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Right compass fault"; + break; + case 103: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Main brush short circuit"; + break; + case 104: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Main brush open circuit"; + break; + case 105: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Left wheel short circuit"; + break; + case 106: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Left wheel open circuit"; + break; + case 107: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Right wheel short circuit"; + break; + case 108: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Right wheel open circuit"; + break; + case 109: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.MOTORS; + parameters.message = "Fan open circuit"; + break; + case 110: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Motion tracking sensor initialization error"; + break; + case 111: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Inertial measurement unit initialization error"; + break; + case 112: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.POWER; + parameters.message = "Charging uC fault"; + break; + case 113: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "NVRAM fault"; + break; + case 114: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "Wi-Fi module fault 1"; + break; + case 115: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "Wi-Fi module fault 2"; + break; + case 116: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Odometer fault"; + break; + case 117: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Left odometer fault"; + break; + case 118: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Right odometer fault"; + break; + case 119: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.CORE; + parameters.message = "Speaker fault"; + break; + case 120: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Wall sensor initialization error"; + break; + case 121: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Wall sensor fault"; + break; + case 122: + parameters.severity.kind = ValetudoRobotError.SEVERITY_KIND.PERMANENT; + parameters.severity.level = ValetudoRobotError.SEVERITY_LEVEL.CATASTROPHIC; + parameters.subsystem = ValetudoRobotError.SUBSYSTEM.SENSORS; + parameters.message = "Wall sensor fault"; + break; } + + return new ValetudoRobotError(parameters); }; module.exports = RoborockValetudoRobot; diff --git a/backend/lib/robots/roborock/capabilities/RoborockCombinedVirtualRestrictionsCapability.js b/backend/lib/robots/roborock/capabilities/RoborockCombinedVirtualRestrictionsCapability.js index 33330a85..0bd60edb 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockCombinedVirtualRestrictionsCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockCombinedVirtualRestrictionsCapability.js @@ -18,6 +18,7 @@ class RoborockCombinedVirtualRestrictionsCapability extends CombinedVirtualRestr */ async setVirtualRestrictions(virtualRestrictions) { const roborockPayload = []; + let vertexCount = 0; virtualRestrictions.virtualWalls.forEach(wall => { roborockPayload.push([ @@ -28,6 +29,8 @@ class RoborockCombinedVirtualRestrictionsCapability extends CombinedVirtualRestr Math.floor(wall.points.pB.x * 10), Math.floor(RoborockMapParser.DIMENSION_MM - wall.points.pB.y * 10), ]); + + vertexCount = vertexCount + 2; }); virtualRestrictions.restrictedZones.forEach(zone => { @@ -54,12 +57,12 @@ class RoborockCombinedVirtualRestrictionsCapability extends CombinedVirtualRestr Math.floor(zone.points.pD.x * 10), Math.floor(RoborockMapParser.DIMENSION_MM - zone.points.pD.y * 10) ]); + + vertexCount = vertexCount + 4; }); - if (roborockPayload.reduce((total, currentElem) => { - return total + currentElem.length - 1; - }, 0) > 68) { - throw new Error("too many forbidden markers to save!"); + if (vertexCount > 68) { + throw new Error("Too many vertices to save"); } diff --git a/backend/lib/robots/roborock/capabilities/RoborockManualControlCapability.js b/backend/lib/robots/roborock/capabilities/RoborockManualControlCapability.js index 64146b24..c3949a08 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockManualControlCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockManualControlCapability.js @@ -59,12 +59,21 @@ class RoborockManualControlCapability extends ManualControlCapability { let angle = 0; let velocity = 0; + /** + * According to user reports, the Roborock V1 doesn't like velocities >= (-)0.3 + * They work fine with the S5 and newer(?) but get ignored by the V1 firmware + * causing it to not move at all. + * + * For now (2022-04-10) we just reduce it for all robots. + * In the future, the velocity value might become robot-specific + */ + switch (movementCommand) { case ManualControlCapability.MOVEMENT_COMMAND_TYPE.FORWARD: - velocity = 0.3; + velocity = 0.29; break; case ManualControlCapability.MOVEMENT_COMMAND_TYPE.BACKWARD: - velocity = -0.3; + velocity = -0.29; break; case ManualControlCapability.MOVEMENT_COMMAND_TYPE.ROTATE_CLOCKWISE: angle = (60*(Math.PI / 180)) * -1; diff --git a/backend/lib/robots/roborock/capabilities/RoborockMapResetCapability.js b/backend/lib/robots/roborock/capabilities/RoborockMapResetCapability.js index c2ba8f51..bd67a189 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockMapResetCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockMapResetCapability.js @@ -1,4 +1,5 @@ const MapResetCapability = require("../../../core/capabilities/MapResetCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); /** * @extends MapResetCapability @@ -11,7 +12,7 @@ class RoborockMapResetCapability extends MapResetCapability { let res = await this.robot.sendCommand("reset_map", [], {}); if (!(Array.isArray(res) && res[0] === "ok")) { - throw new Error("Failed to reset map: " + res); + throw new RobotFirmwareError("Failed to reset map: " + res); } this.robot.clearValetudoMap(); diff --git a/backend/lib/robots/roborock/capabilities/RoborockMapSegmentEditCapability.js b/backend/lib/robots/roborock/capabilities/RoborockMapSegmentEditCapability.js index 65fe8247..718dd9df 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockMapSegmentEditCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockMapSegmentEditCapability.js @@ -11,7 +11,7 @@ class RoborockMapSegmentEditCapability extends MapSegmentEditCapability { * @returns {Promise} */ async joinSegments(segmentA, segmentB) { - await this.robot.sendCommand("merge_segment", [segmentA.id, segmentB.id], {timeout: 5000}); + await this.robot.sendCommand("merge_segment", [parseInt(segmentA.id), parseInt(segmentB.id)], {timeout: 5000}); this.robot.pollMap(); } @@ -28,7 +28,7 @@ class RoborockMapSegmentEditCapability extends MapSegmentEditCapability { */ async splitSegment(segment, pA, pB) { const flippedSplitLine = [ - segment.id, + parseInt(segment.id), Math.floor(pA.x * 10), Math.floor(RoborockMapParser.DIMENSION_MM - pA.y * 10), Math.floor(pB.x * 10), diff --git a/backend/lib/robots/roborock/capabilities/RoborockMapSegmentSimpleCapability.js b/backend/lib/robots/roborock/capabilities/RoborockMapSegmentSimpleCapability.js new file mode 100644 index 00000000..e8756435 --- /dev/null +++ b/backend/lib/robots/roborock/capabilities/RoborockMapSegmentSimpleCapability.js @@ -0,0 +1,39 @@ +const MapSegmentationCapability = require("../../../core/capabilities/MapSegmentationCapability"); + +/** + * @extends MapSegmentationCapability + */ +class RoborockMapSegmentSimpleCapability extends MapSegmentationCapability { + /** + * Could be phrased as "cleanSegments" for vacuums or "mowSegments" for lawnmowers + * + * + * @param {Array} segments + * @param {object} [options] + * @param {number} [options.iterations] + * @param {boolean} [options.customOrder] + * @returns {Promise} + */ + async executeSegmentAction(segments, options) { + const segmentIds = segments.map(segment => { + return parseInt(segment.id); + }); + + await this.robot.sendCommand("app_segment_clean", segmentIds, {}); + } + + /** + * @returns {import("../../../core/capabilities/MapSegmentationCapability").MapSegmentationCapabilityProperties} + */ + getProperties() { + return { + iterationCount: { + min: 1, + max: 1 + }, + customOrderSupport: false + }; + } +} + +module.exports = RoborockMapSegmentSimpleCapability; diff --git a/backend/lib/robots/roborock/capabilities/RoborockMultiMapMapResetCapability.js b/backend/lib/robots/roborock/capabilities/RoborockMultiMapMapResetCapability.js index 13ceab50..a2d24275 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockMultiMapMapResetCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockMultiMapMapResetCapability.js @@ -1,4 +1,5 @@ const MapResetCapability = require("../../../core/capabilities/MapResetCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); /** * @extends MapResetCapability @@ -8,47 +9,41 @@ class RoborockMultiMapMapResetCapability extends MapResetCapability { * @returns {Promise} */ async reset() { - if (this.robot.mapStatus === MAP_STATUS.NO_MAP) { + if (!this.robot.mapStatus) { + throw new Error("Unknown map status: " + this.robot.mapStatus + ". Unable to reset map."); + } + + if (this.robot.mapStatus.mapPresent === false) { throw new Error("Map doesn't exist. Nothing to reset."); } - if (this.robot.mapStatus === MAP_STATUS.NEW_MAP) { - // saving the map takes a bit of time, usually up to 5 secs + + + /* + 63 means new map and isn't a proper map slot ID + We're trying to manually trigger the segmentation to store the map into a real map slot + */ + if (this.robot.mapStatus.mapSlotId === 63) { + // segmenting the map takes a bit of time, usually up to 5 secs let res = await this.robot.sendCommand("manual_segment_map", [{"map_flag":-1}], {timeout: 10000}); + if (!(Array.isArray(res) && res[0] === 1)) { - throw new Error("Map is incomplete and not saved. Attempt to save map failed."); + throw new Error("Map is incomplete and not saved. Attempt to segment map failed."); } await this.robot.pollState(); } - const multiMapId = MAP_STATUS_TO_MUTIMAP_ID[this.robot.mapStatus]; - if (multiMapId === undefined) { - throw new Error("Unknown map status: " + this.robot.mapStatus + ". Unable to reset map."); - } - let res = await this.robot.sendCommand("del_map", [multiMapId], {}); + + + let res = await this.robot.sendCommand("del_map", [this.robot.mapStatus.mapSlotId], {}); if (!(Array.isArray(res) && res[0] === "ok")) { - throw new Error("Failed to reset map: " + res); + throw new RobotFirmwareError("Failed to reset map: " + res); } this.robot.clearValetudoMap(); } } -const MAP_STATUS = Object.freeze({ - NO_MAP: 252, - NEW_MAP: 253, // a full clean-up hasn't been completed yet, map is incomplete and not saved into a slot - MAP_0: 3, - MAP_1: 7, - MAP_2: 11, - MAP_3: 15, -}); - -const MAP_STATUS_TO_MUTIMAP_ID = Object.freeze({ - [MAP_STATUS.MAP_0]: 0, - [MAP_STATUS.MAP_1]: 1, - [MAP_STATUS.MAP_2]: 2, - [MAP_STATUS.MAP_3]: 3, -}); module.exports = RoborockMultiMapMapResetCapability; diff --git a/backend/lib/robots/roborock/capabilities/RoborockMultiMapPersistentMapControlCapability.js b/backend/lib/robots/roborock/capabilities/RoborockMultiMapPersistentMapControlCapability.js index 4d9ff5f3..282d724f 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockMultiMapPersistentMapControlCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockMultiMapPersistentMapControlCapability.js @@ -1,11 +1,30 @@ const RoborockPersistentMapControlCapability = require("./RoborockPersistentMapControlCapability"); + class RoborockMultiMapPersistentMapControlCapability extends RoborockPersistentMapControlCapability { /** * @returns {Promise} */ async enable() { - await this.robot.sendCommand("set_lab_status", [{lab_status: 1}], {}); + await this.robot.pollState(); //The labStatus is part of the status response and gets stored in the robot instance + + const payload = { + lab_status: 1 + }; + + /* + If the robot was previously used with the official app, it might be in multi-map mode. + In those cases, this command needs a reserve_map or else it will fail. + We use the current multi-map slot for that + + "Enabling" persistent maps with multi-maps enabled actually disables multi-maps + Whether that is a good design decision is TBD + */ + if (this.robot.labStatus?.multiMapEnabled === true && this.robot.mapStatus?.mapSlotId !== undefined) { + payload["reserve_map"] = this.robot.mapStatus.mapSlotId; + } + + await this.robot.sendCommand("set_lab_status", [payload], {}); } /** diff --git a/backend/lib/robots/roborock/capabilities/RoborockPersistentMapControlCapability.js b/backend/lib/robots/roborock/capabilities/RoborockPersistentMapControlCapability.js index 49c2ed4e..0fb51cc4 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockPersistentMapControlCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockPersistentMapControlCapability.js @@ -10,17 +10,15 @@ class RoborockPersistentMapControlCapability extends PersistentMapControlCapabil */ constructor(options) { super(options); - - this.persistentMapState = undefined; } /** * @returns {Promise} */ async isEnabled() { - await this.robot.pollState(); //fetching robot state populates the capability's internal state. somewhat spaghetti :( + await this.robot.pollState(); //The labStatus is part of the status response and gets stored in the robot instance - return this.persistentMapState; + return this.robot.labStatus?.persistentMapEnabled ?? false; } /** diff --git a/backend/lib/robots/roborock/capabilities/RoborockTotalStatisticsCapability.js b/backend/lib/robots/roborock/capabilities/RoborockTotalStatisticsCapability.js index f6486de9..a3b8eec2 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockTotalStatisticsCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockTotalStatisticsCapability.js @@ -11,25 +11,45 @@ class RoborockTotalStatisticsCapability extends TotalStatisticsCapability { async getStatistics() { const res = await this.robot.sendCommand("get_clean_summary", [], {}); - if (!(Array.isArray(res) && res.length === 4)) { + // This is how roborock robots before the S7 reported total statistics + if (Array.isArray(res) && res.length === 4) { + return [ + new ValetudoDataPoint({ + type: ValetudoDataPoint.TYPES.TIME, + value: res[0] + }), + new ValetudoDataPoint({ + type: ValetudoDataPoint.TYPES.AREA, + value: Math.round(res[1] / 100) + }), + new ValetudoDataPoint({ + type: ValetudoDataPoint.TYPES.COUNT, + value: res[2] + }) + ]; + } else if ( //S7 and up + res && + res.clean_time !== undefined && + res.clean_area !== undefined && + res.clean_count !== undefined + ) { + return [ + new ValetudoDataPoint({ + type: ValetudoDataPoint.TYPES.TIME, + value: res.clean_time + }), + new ValetudoDataPoint({ + type: ValetudoDataPoint.TYPES.AREA, + value: Math.round(res.clean_area / 100) + }), + new ValetudoDataPoint({ + type: ValetudoDataPoint.TYPES.COUNT, + value: res.clean_count + }) + ]; + } else { throw new Error("Received invalid response"); } - - - return [ - new ValetudoDataPoint({ - type: ValetudoDataPoint.TYPES.TIME, - value: res[0] - }), - new ValetudoDataPoint({ - type: ValetudoDataPoint.TYPES.AREA, - value: Math.round(res[1] / 100) - }), - new ValetudoDataPoint({ - type: ValetudoDataPoint.TYPES.COUNT, - value: res[2] - }) - ]; } getProperties() { diff --git a/backend/lib/robots/roborock/capabilities/RoborockZoneCleaningCapability.js b/backend/lib/robots/roborock/capabilities/RoborockZoneCleaningCapability.js index eba35acf..6723183b 100644 --- a/backend/lib/robots/roborock/capabilities/RoborockZoneCleaningCapability.js +++ b/backend/lib/robots/roborock/capabilities/RoborockZoneCleaningCapability.js @@ -22,10 +22,12 @@ class RoborockZoneCleaningCapability extends ZoneCleaningCapability { // it seems as the vacuum only works with 'positive rectangles'! So flip the coordinates if the user entered them wrong. // x1 has to be < x2 and y1 < y2 return [ - yFlippedZone[0] > yFlippedZone[2] ? yFlippedZone[2] : yFlippedZone[0], - yFlippedZone[1] > yFlippedZone[3] ? yFlippedZone[3] : yFlippedZone[1], - yFlippedZone[0] > yFlippedZone[2] ? yFlippedZone[0] : yFlippedZone[2], - yFlippedZone[1] > yFlippedZone[3] ? yFlippedZone[1] : yFlippedZone[3], + Math.min(yFlippedZone[0], yFlippedZone[2]), + Math.min(yFlippedZone[1], yFlippedZone[3]), + + Math.max(yFlippedZone[0], yFlippedZone[2]), + Math.max(yFlippedZone[1], yFlippedZone[3]), + yFlippedZone[4] ]; }); diff --git a/backend/lib/robots/roborock/capabilities/index.js b/backend/lib/robots/roborock/capabilities/index.js index 56a205cc..c01b9b1c 100644 --- a/backend/lib/robots/roborock/capabilities/index.js +++ b/backend/lib/robots/roborock/capabilities/index.js @@ -13,6 +13,7 @@ module.exports = { RoborockMapResetCapability: require("./RoborockMapResetCapability"), RoborockMapSegmentEditCapability: require("./RoborockMapSegmentEditCapability"), RoborockMapSegmentRenameCapability: require("./RoborockMapSegmentRenameCapability"), + RoborockMapSegmentSimpleCapability: require("./RoborockMapSegmentSimpleCapability"), RoborockMapSegmentationCapability: require("./RoborockMapSegmentationCapability"), RoborockMapSnapshotCapability: require("./RoborockMapSnapshotCapability"), RoborockMultiMapMapResetCapability: require("./RoborockMultiMapMapResetCapability"), diff --git a/backend/lib/robots/roborock/index.js b/backend/lib/robots/roborock/index.js index 2137e6d8..82d40224 100644 --- a/backend/lib/robots/roborock/index.js +++ b/backend/lib/robots/roborock/index.js @@ -1,4 +1,5 @@ module.exports = { + "RoborockM1SValetudoRobot": require("./RoborockM1SValetudoRobot"), "RoborockS4MaxValetudoRobot": require("./RoborockS4MaxValetudoRobot"), "RoborockS4ValetudoRobot": require("./RoborockS4ValetudoRobot"), "RoborockS5MaxValetudoRobot": require("./RoborockS5MaxValetudoRobot"), diff --git a/backend/lib/robots/viomi/ViomiMapParser.js b/backend/lib/robots/viomi/ViomiMapParser.js index ca436489..961580fa 100644 --- a/backend/lib/robots/viomi/ViomiMapParser.js +++ b/backend/lib/robots/viomi/ViomiMapParser.js @@ -93,16 +93,17 @@ class ViomiMapParser { this.mapId = asInts(this.take(0x4, "mapId"))[0]; - if (featureFlags & 0b000000000000001) { + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.ROBOT_STATUS) { this.robotStatus = this.take(0x28, "robot status"); } - if (featureFlags & 0b000000000000010) { + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.MAP_IMAGE) { this.mapHead = this.take(0x28, "map head"); this.parseImg(); } - if (featureFlags & 0b000000000000100) { + + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.PATH) { let head = asInts(this.take(12, "history")); this.history = []; for (let i = 0; i < head[2]; i++) { @@ -114,7 +115,8 @@ class ViomiMapParser { this.offset += 9; } } - if (featureFlags & 0b000000000001000) { + + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.CHARGER_LOCATION) { // TODO: Figure out charge station location from this. let chargeStation = this.take(16, "charge station"); this.chargeStation = { @@ -122,7 +124,8 @@ class ViomiMapParser { orientation: chargeStation.readFloatLE(12) }; } - if (featureFlags & 0b000000000010000) { + + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.VIRTUAL_RESTRICTIONS) { let head = asInts(this.take(12, "virtual wall")); this.virtual_wall = []; @@ -159,7 +162,8 @@ class ViomiMapParser { this.take(48, "unknown48"); } } - if (featureFlags & 0b000000000100000) { + + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.ACTIVE_ZONES) { let head = asInts(this.take(12, "area head")); let area_num = head[2]; @@ -183,11 +187,13 @@ class ViomiMapParser { this.take(48, "unknown48"); } } - if (featureFlags & 0b000000001000000) { + + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.GO_TO_TARGET) { let navigateTarget = this.take(20, "navigate"); this.navigateTarget = {position: this.readFloatPosition(navigateTarget, 8)}; } - if (featureFlags & 0b000000010000000) { + + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.ROBOT_POSITION) { let realtimePose = this.take(21, "realtime"); this.realtimePose = { position: this.readFloatPosition(realtimePose, 9), @@ -195,7 +201,7 @@ class ViomiMapParser { }; } - if (featureFlags & 0b000100000000000) { + if (featureFlags & ViomiMapParser.FEATURE_FLAGS.SEGMENTS) { //v6 example: 5b590f5f00000001 //v7 example: e35a185e00000001 this.take(8, "unknown8"); @@ -210,6 +216,7 @@ class ViomiMapParser { } } } + this.take(this.buf.length - this.offset, "trailing"); // TODO: one of them is just the room outline, not actual past navigation logic @@ -287,20 +294,19 @@ class ViomiMapParser { })); if (mapContents.image.pixels.rooms && mapContents.zones) { - Object.keys(mapContents.image.pixels.rooms).forEach(k => { + Object.keys(mapContents.image.pixels.rooms).forEach(segmentId => { // Ignore unnamed segments (they pollute the map). - if (!mapContents.zones[k]) { + if (!mapContents.zones[segmentId]) { return; } - const segmentId = parseInt(k); layers.push(new Map.MapLayer({ - pixels: mapContents.image.pixels.rooms[k].sort(Map.MapLayer.COORDINATE_TUPLE_SORT).flat(), + pixels: mapContents.image.pixels.rooms[segmentId].sort(Map.MapLayer.COORDINATE_TUPLE_SORT).flat(), type: Map.MapLayer.TYPE.SEGMENT, metaData: { segmentId: segmentId, active: false, - name: mapContents.zones[k].name + name: mapContents.zones[segmentId].name } })); }); @@ -517,8 +523,8 @@ class ViomiMapParser { * an obstacle, non-room area or are undefined (0). */ parseImg() { - var height = this.mapHead.readUInt32LE(12); - var width = this.mapHead.readUInt32LE(16); + const height = this.mapHead.readUInt32LE(12); + const width = this.mapHead.readUInt32LE(16); let pixels = { floor: [], obstacle_strong: [], @@ -635,5 +641,19 @@ ViomiMapParser.MAX_MAP_HEIGHT = ViomiMapParser.convertFloat(20); // 4000 ViomiMapParser.POSITION_UNKNOWN = 1100; +ViomiMapParser.FEATURE_FLAGS = { + ROBOT_STATUS: 0b000000000000001, + MAP_IMAGE: 0b000000000000010, + PATH: 0b000000000000100, + CHARGER_LOCATION: 0b000000000001000, + VIRTUAL_RESTRICTIONS: 0b000000000010000, + ACTIVE_ZONES: 0b000000000100000, + GO_TO_TARGET: 0b000000001000000, + ROBOT_POSITION: 0b000000010000000, + //unknowns + SEGMENTS: 0b000100000000000, + //more unknowns +}; + module.exports = ViomiMapParser; diff --git a/backend/lib/robots/viomi/ViomiValetudoRobot.js b/backend/lib/robots/viomi/ViomiValetudoRobot.js index fee4dfa9..b3614d3b 100644 --- a/backend/lib/robots/viomi/ViomiValetudoRobot.js +++ b/backend/lib/robots/viomi/ViomiValetudoRobot.js @@ -6,6 +6,8 @@ const LinuxWifiScanCapability = require("../common/linuxCapabilities/LinuxWifiSc const Logger = require("../../Logger"); const miioCapabilities = require("../common/miioCapabilities"); const MiioValetudoRobot = require("../MiioValetudoRobot"); +const ValetudoRobot = require("../../core/ValetudoRobot"); +const ValetudoRobotError = require("../../entities/core/ValetudoRobotError"); const ValetudoSelectionPreset = require("../../entities/core/ValetudoSelectionPreset"); const ViomiMapParser = require("./ViomiMapParser"); const zlib = require("zlib"); @@ -29,7 +31,6 @@ class ViomiValetudoRobot extends MiioValetudoRobot { super(options); this.debugConfig = options.config.get("debug"); - this.lastMapPoll = new Date(0); if (options.fanSpeeds !== undefined) { this.fanSpeeds = options.fanSpeeds; } else { @@ -44,7 +45,8 @@ class ViomiValetudoRobot extends MiioValetudoRobot { this.ephemeralState = { carpetModeEnabled: undefined, lastOperationType: null, - lastOperationAdditionalParams: [] + lastOperationAdditionalParams: [], + operationMode: undefined }; this.registerCapability(new capabilities.ViomiBasicControlCapability({ @@ -175,6 +177,7 @@ class ViomiValetudoRobot extends MiioValetudoRobot { * @param {object} options * @param {number=} options.retries * @param {number=} options.timeout custom timeout in milliseconds + * @param {boolean=} options.preferLocalInterface * @returns {Promise} */ sendCommand(method, args = [], options = {}) { @@ -200,15 +203,16 @@ class ViomiValetudoRobot extends MiioValetudoRobot { return super.sendCloud(msg, options); } - onMessage(msg) { + onIncomingCloudMessage(msg) { if (msg.method?.startsWith("prop.")) { this.parseAndUpdateState({ - [msg.method.substr(5)]: msg.params[0] + [msg.method.slice(5)]: msg.params[0] }); return true; } - return super.onMessage(msg); + + return super.onIncomingCloudMessage(msg); } async pollState() { @@ -235,6 +239,7 @@ class ViomiValetudoRobot extends MiioValetudoRobot { let status; let error; let statusValue; + let statusError; let statusMetaData = {}; const previousState = this.state.getFirstMatchingAttributeByConstructor(stateAttrs.StatusStateAttribute); @@ -256,17 +261,22 @@ class ViomiValetudoRobot extends MiioValetudoRobot { if (error !== undefined) { if (error.value === stateAttrs.StatusStateAttribute.VALUE.ERROR) { + //TODO: classify errors + statusError = new ValetudoRobotError({ + severity: { + kind: ValetudoRobotError.SEVERITY_KIND.UNKNOWN, + level: ValetudoRobotError.SEVERITY_LEVEL.UNKNOWN, + }, + subsystem: ValetudoRobotError.SUBSYSTEM.UNKNOWN, + message: error.desc, + vendorErrorCode: data["err_state"] + }); // If status is an error, mark it as such - statusMetaData.error_code = data["err_state"]; statusValue = stateAttrs.StatusStateAttribute.VALUE.ERROR; } else if (status === undefined) { // If it is not an error but we don't have any status data, use the status code from the error statusValue = error.value; } - // Some errors are rather "warnings": keep the error description if we have one - if (error.desc !== undefined) { - statusMetaData.error_description = error.desc; - } } let statusFlag = stateAttrs.StatusStateAttribute.FLAG.NONE; @@ -285,7 +295,8 @@ class ViomiValetudoRobot extends MiioValetudoRobot { newStateAttr = new stateAttrs.StatusStateAttribute({ value: statusValue, flag: statusFlag, - metaData: statusMetaData + metaData: statusMetaData, + error: statusError }); this.state.upsertFirstMatchingAttribute(newStateAttr); @@ -402,25 +413,17 @@ class ViomiValetudoRobot extends MiioValetudoRobot { // Viomi naming is abysmal if (data["is_mop"] !== undefined) { - let operationModeValue; - switch (data["is_mop"]) { case attributes.ViomiOperationMode.VACUUM: - operationModeValue = stateAttrs.OperationModeStateAttribute.VALUE.VACUUM; + this.ephemeralState.operationMode = stateAttrs.PresetSelectionStateAttribute.MODE.VACUUM; break; case attributes.ViomiOperationMode.MIXED: - operationModeValue = stateAttrs.OperationModeStateAttribute.VALUE.VACUUM_AND_MOP; + this.ephemeralState.operationMode = stateAttrs.PresetSelectionStateAttribute.MODE.VACUUM_AND_MOP; break; case attributes.ViomiOperationMode.MOP: - operationModeValue = stateAttrs.OperationModeStateAttribute.VALUE.MOP; + this.ephemeralState.operationMode = stateAttrs.PresetSelectionStateAttribute.MODE.MOP; break; } - - if (operationModeValue) { - this.state.upsertFirstMatchingAttribute(new stateAttrs.OperationModeStateAttribute({ - value: operationModeValue - })); - } } if (data["mop_type"] !== undefined) { @@ -453,49 +456,10 @@ class ViomiValetudoRobot extends MiioValetudoRobot { this.emitStateAttributesUpdated(); } - pollMap() { - // Guard against multiple concurrent polls. - if (this.pollingMap) { - return; - } - - const now = new Date(); - if (now.getTime() - 600 > this.lastMapPoll.getTime()) { - this.pollingMap = true; - this.lastMapPoll = now; - - // Clear pending timeout, since we’re starting a new poll right now. - if (this.pollMapTimeout) { - clearTimeout(this.pollMapTimeout); - } - - this.sendCommand("set_uploadmap", [2], {timeout: 2000}).then(() => { - let repollSeconds = this.mapPollingIntervals.default; - - let StatusStateAttribute = this.state.getFirstMatchingAttribute({ - attributeClass: stateAttrs.StatusStateAttribute.name - }); - - if (StatusStateAttribute && StatusStateAttribute.isActiveState) { - repollSeconds = this.mapPollingIntervals.active; - } - - setTimeout(() => { - return this.pollMap(); - }, repollSeconds * 1000); - }, err => { - // ¯\_(ツ)_/¯ - }).finally(() => { - this.pollingMap = false; - }); - } - - this.pollMapTimeout = setTimeout(() => { - return this.pollMap(); - }, 5 * 60 * 1000); // 5 minutes + async executeMapPoll() { + return this.sendCommand("set_uploadmap", [2], {timeout: 2000}); } - preprocessMap(data) { return new Promise((resolve, reject) => { zlib.inflate(data, (err, result) => { @@ -532,6 +496,63 @@ class ViomiValetudoRobot extends MiioValetudoRobot { getManufacturer() { return "Viomi"; } + + getModelDetails() { + return Object.assign( + {}, + super.getModelDetails(), + { + supportedAttachments: [ + stateAttrs.AttachmentStateAttribute.TYPE.DUSTBIN, + stateAttrs.AttachmentStateAttribute.TYPE.WATERTANK, + stateAttrs.AttachmentStateAttribute.TYPE.MOP, + ] + } + ); + } + + /** + * @private + * @returns {string | null} + */ + getFirmwareVersion() { + try { + const os_release = fs.readFileSync("/etc/YMsave01/os-release").toString(); + const parsedFile = /^VIOMI_VERSION=(?[\d._]*)$/m.exec(os_release); + + if (parsedFile !== null && parsedFile.groups && parsedFile.groups.version) { + return parsedFile.groups.version.split("_")?.[1]; + } else { + return null; + } + } catch (e) { + Logger.warn("Unable to determine the Firmware Version", e); + + return null; + } + } + + /** + * @return {object} + */ + getProperties() { + const superProps = super.getProperties(); + const ourProps = {}; + + if (this.config.get("embedded") === true) { + const firmwareVersion = this.getFirmwareVersion(); + + if (firmwareVersion) { + ourProps[ValetudoRobot.WELL_KNOWN_PROPERTIES.FIRMWARE_VERSION] = firmwareVersion; + } + } + + return Object.assign( + {}, + superProps, + ourProps + ); + } } ViomiValetudoRobot.DEVICE_CONF_PATH = "/etc/miio/device.conf"; diff --git a/backend/lib/robots/viomi/capabilities/ViomiBasicControlCapability.js b/backend/lib/robots/viomi/capabilities/ViomiBasicControlCapability.js index 73378448..e6ce4063 100644 --- a/backend/lib/robots/viomi/capabilities/ViomiBasicControlCapability.js +++ b/backend/lib/robots/viomi/capabilities/ViomiBasicControlCapability.js @@ -81,10 +81,8 @@ class ViomiBasicControlCapability extends BasicControlCapability { * @returns {Promise} */ async ensureCleaningOperationMode(operationMode) { - const curOperationMode = this.robot.state.getFirstMatchingAttributeByConstructor( - stateAttrs.OperationModeStateAttribute - ); - if (!curOperationMode || curOperationMode && curOperationMode.VALUE !== operationMode) { + const curOperationMode = this.robot.ephemeralState.operationMode; + if (!curOperationMode || curOperationMode !== operationMode) { await this.robot.sendCommand("set_mop", [operationMode]); } } diff --git a/backend/lib/robots/viomi/capabilities/ViomiMapSegmentEditCapability.js b/backend/lib/robots/viomi/capabilities/ViomiMapSegmentEditCapability.js index 0109e813..a1659cee 100644 --- a/backend/lib/robots/viomi/capabilities/ViomiMapSegmentEditCapability.js +++ b/backend/lib/robots/viomi/capabilities/ViomiMapSegmentEditCapability.js @@ -1,4 +1,5 @@ const MapSegmentEditCapability = require("../../../core/capabilities/MapSegmentEditCapability"); +const RobotFirmwareError = require("../../../core/RobotFirmwareError"); const ViomiMapParser = require("../ViomiMapParser"); /** @@ -51,13 +52,13 @@ class ViomiMapSegmentEditCapability extends MapSegmentEditCapability { const result = await this.robot.sendCommand("arrange_room", { lang: this.lang, mapId: this.robot.state.map.metaData.vendorMapId, - roomArr: [[segmentA.id, segmentB.id]], + roomArr: [[parseInt(segmentA.id), parseInt(segmentB.id)]], type: this.mapActions.JOIN_SEGMENT_TYPE }, { timeout: 5000 }); if (Array.isArray(result) && result.length === 1 && result[0] === "fail") { - throw new Error("Segments must be adjacent!"); + throw new RobotFirmwareError("Segments must be adjacent!"); } } finally { this.robot.pollMap(); @@ -88,13 +89,13 @@ class ViomiMapSegmentEditCapability extends MapSegmentEditCapability { this.pointToViomiString(ViomiMapParser.positionToViomi(pA.x, pA.y)), this.pointToViomiString(ViomiMapParser.positionToViomi(pB.x, pB.y)) ]], - roomId: segment.id, + roomId: parseInt(segment.id), type: this.mapActions.SPLIT_SEGMENT_TYPE }, { timeout: 5000 }); if (Array.isArray(result) && result.length === 1 && result[0] === "fail") { - throw new Error("Split segment is too small!"); + throw new RobotFirmwareError("Split segment is too small!"); } } finally { this.robot.pollMap(); diff --git a/backend/lib/robots/viomi/capabilities/ViomiMapSegmentRenameCapability.js b/backend/lib/robots/viomi/capabilities/ViomiMapSegmentRenameCapability.js index 50117f7d..1019b85e 100644 --- a/backend/lib/robots/viomi/capabilities/ViomiMapSegmentRenameCapability.js +++ b/backend/lib/robots/viomi/capabilities/ViomiMapSegmentRenameCapability.js @@ -16,7 +16,7 @@ class ViomiMapSegmentRenameCapability extends MapSegmentRenameCapability { await this.robot.sendCommand("rename_room", [ this.robot.state.map.metaData.vendorMapId, 1, - segment.id, + parseInt(segment.id), name ], {timeout: 5000} diff --git a/backend/lib/robots/viomi/capabilities/ViomiPersistentMapControlCapability.js b/backend/lib/robots/viomi/capabilities/ViomiPersistentMapControlCapability.js index 9b834363..c70768ea 100644 --- a/backend/lib/robots/viomi/capabilities/ViomiPersistentMapControlCapability.js +++ b/backend/lib/robots/viomi/capabilities/ViomiPersistentMapControlCapability.js @@ -53,7 +53,6 @@ class ViomiPersistentMapControlCapability extends PersistentMapControlCapability * @returns {Promise} */ async enable() { - // TODO: test await this.robot.sendCommand("set_remember", [1], {}); // wait for persistentMapState to change (up to 10 seconds) await this.waitForState(true,10); @@ -63,7 +62,6 @@ class ViomiPersistentMapControlCapability extends PersistentMapControlCapability * @returns {Promise} */ async disable() { - // TODO: test await this.robot.sendCommand("set_remember", [0], {}); // wait for persistentMapState to change (up to 10 seconds) await this.waitForState(false,10); diff --git a/backend/lib/robots/viomi/capabilities/ViomiZoneCleaningCapability.js b/backend/lib/robots/viomi/capabilities/ViomiZoneCleaningCapability.js index 5c57a8f9..f0728e79 100644 --- a/backend/lib/robots/viomi/capabilities/ViomiZoneCleaningCapability.js +++ b/backend/lib/robots/viomi/capabilities/ViomiZoneCleaningCapability.js @@ -62,7 +62,7 @@ class ViomiZoneCleaningCapability extends ZoneCleaningCapability { return { zoneCount: { min: 1, - max: 5 + max: 10 }, iterationCount: { min: 1, diff --git a/backend/lib/scheduler/Scheduler.js b/backend/lib/scheduler/Scheduler.js index 6728e8ea..e2ba2333 100644 --- a/backend/lib/scheduler/Scheduler.js +++ b/backend/lib/scheduler/Scheduler.js @@ -1,11 +1,9 @@ const Logger = require("../Logger"); const ValetudoFullCleanupTimerAction = require("./actions/ValetudoFullCleanupTimerAction"); -const ValetudoGoToTimerAction = require("./actions/ValetudoGoToTimerAction"); const ValetudoNTPClientDisabledState = require("../entities/core/ntpClient/ValetudoNTPClientDisabledState"); const ValetudoNTPClientSyncedState = require("../entities/core/ntpClient/ValetudoNTPClientSyncedState"); const ValetudoSegmentCleanupTimerAction = require("./actions/ValetudoSegmentCleanupTimerAction"); const ValetudoTimer = require("../entities/core/ValetudoTimer"); -const ValetudoZoneCleanupTimerAction = require("./actions/ValetudoZoneCleanupTimerAction"); const MS_PER_MIN = 60 * 1000; @@ -91,12 +89,6 @@ class Scheduler { case ValetudoTimer.ACTION_TYPE.FULL_CLEANUP: action = new ValetudoFullCleanupTimerAction({robot: this.robot}); break; - case ValetudoTimer.ACTION_TYPE.ZONE_CLEANUP: - action = new ValetudoZoneCleanupTimerAction({ - robot: this.robot, - zoneId: timerDefinition.action?.params?.zone_id - }); - break; case ValetudoTimer.ACTION_TYPE.SEGMENT_CLEANUP: action = new ValetudoSegmentCleanupTimerAction({ robot: this.robot, @@ -105,12 +97,6 @@ class Scheduler { customOrder: timerDefinition.action?.params?.custom_order }); break; - case ValetudoTimer.ACTION_TYPE.GOTO_LOCATION: - action = new ValetudoGoToTimerAction({ - robot: this.robot, - goToId: timerDefinition.action?.params?.goto_id - }); - break; } if (action) { diff --git a/backend/lib/scheduler/actions/ValetudoGoToTimerAction.js b/backend/lib/scheduler/actions/ValetudoGoToTimerAction.js deleted file mode 100644 index 8ab5e377..00000000 --- a/backend/lib/scheduler/actions/ValetudoGoToTimerAction.js +++ /dev/null @@ -1,36 +0,0 @@ -const GoToLocationCapability = require("../../core/capabilities/GoToLocationCapability"); -const ValetudoTimerAction = require("./ValetudoTimerAction"); - -class ValetudoGoToTimerAction extends ValetudoTimerAction { - /** - * @param {object} options - * @param {import("../../core/ValetudoRobot")} options.robot - * @param {string} options.goToId - */ - constructor(options) { - super(options); - - this.goToId = options.goToId; - } - - async run() { - if (!this.goToId) { - throw new Error("Missing goToId"); - } - - if (!this.robot.hasCapability(GoToLocationCapability.TYPE)) { - throw new Error("Robot is missing the GoToLocationCapability"); - } else { - const capability = this.robot.capabilities[GoToLocationCapability.TYPE]; - const goToLocationPreset = this.robot.config.get("goToLocationPresets")[this.goToId]; - - if (goToLocationPreset) { - return capability.goTo(goToLocationPreset); - } else { - throw new Error("There is no go to location preset with id " + this.goToId); - } - } - } -} - -module.exports = ValetudoGoToTimerAction; diff --git a/backend/lib/scheduler/actions/ValetudoZoneCleanupTimerAction.js b/backend/lib/scheduler/actions/ValetudoZoneCleanupTimerAction.js deleted file mode 100644 index 3b5b3b29..00000000 --- a/backend/lib/scheduler/actions/ValetudoZoneCleanupTimerAction.js +++ /dev/null @@ -1,36 +0,0 @@ -const ValetudoTimerAction = require("./ValetudoTimerAction"); -const ZoneCleaningCapability = require("../../core/capabilities/ZoneCleaningCapability"); - -class ValetudoZoneCleanupTimerAction extends ValetudoTimerAction { - /** - * @param {object} options - * @param {import("../../core/ValetudoRobot")} options.robot - * @param {string} options.zoneId - */ - constructor(options) { - super(options); - - this.zoneId = options.zoneId; - } - - async run() { - if (!this.zoneId) { - throw new Error("Missing zoneId"); - } - - if (!this.robot.hasCapability(ZoneCleaningCapability.TYPE)) { - throw new Error("Robot is missing the ZoneCleaningCapability"); - } else { - const capability = this.robot.capabilities[ZoneCleaningCapability.TYPE]; - const zonePreset = this.robot.config.get("zonePresets")[this.zoneId]; - - if (zonePreset) { - return capability.start(zonePreset.zones); - } else { - throw new Error("There is no zone preset with id " + this.zoneId); - } - } - } -} - -module.exports = ValetudoZoneCleanupTimerAction; diff --git a/backend/lib/updater/Updater.js b/backend/lib/updater/Updater.js index 5530e909..75ce7fc0 100644 --- a/backend/lib/updater/Updater.js +++ b/backend/lib/updater/Updater.js @@ -1,22 +1,10 @@ -// @ts-nocheck Required due to too many annoyances - -const crypto = require("crypto"); const fs = require("fs"); -const os = require("os"); -const path = require("path/posix"); -const pipeline = require("stream/promises").pipeline; -const spawnSync = require("child_process").spawnSync; - - -const axios = require("axios").default; -const uuid = require("uuid"); - -const GithubValetudoNightlyUpdateProvider = require("./update_provider/GithubValetudoNightlyUpdateProvider"); -const GithubValetudoUpdateProvider = require("./update_provider/GithubValetudoUpdateProvider"); +const GithubValetudoNightlyUpdateProvider = require("./lib/update_provider/GithubValetudoNightlyUpdateProvider"); +const GithubValetudoUpdateProvider = require("./lib/update_provider/GithubValetudoUpdateProvider"); const Logger = require("../Logger"); -const stateAttrs = require("../entities/state/attributes"); const States = require("../entities/core/updater"); -const Tools = require("../Tools"); +const Steps = require("./lib/steps"); +const Tools = require("../utils/Tools"); @@ -32,7 +20,9 @@ class Updater { this.updaterConfig = this.config.get("updater"); + /** @type {import("../entities/core/updater/ValetudoUpdaterState")} */ this.state = undefined; + /** @type {import("./lib/update_provider/ValetudoUpdateProvider")} */ this.updateProvider = undefined; if (this.updaterConfig.enabled === true) { @@ -45,10 +35,10 @@ class Updater { switch (this.updaterConfig.updateProvider.type) { - case "github": + case GithubValetudoUpdateProvider.TYPE: this.updateProvider = new GithubValetudoUpdateProvider(); break; - case "github_nightly": + case GithubValetudoNightlyUpdateProvider.TYPE: this.updateProvider = new GithubValetudoNightlyUpdateProvider(); break; default: @@ -61,7 +51,7 @@ class Updater { * and then asynchronously process it. * Updates are reported via the updaters state * - * @return {boolean} + * @return {void} */ triggerCheck() { if ( @@ -76,364 +66,91 @@ class Updater { this.state.busy = true; - this.check().catch(err => { - //This should never happen - Logger.error("Unexpected error during check", err); + + const step = new Steps.ValetudoUpdaterCheckStep({ + embedded: this.config.get("embedded"), + architectures: Updater.ARCHITECTURES, + spaceRequired: Updater.SPACE_REQUIREMENTS, + robot: this.robot, + updateProvider: this.updateProvider }); - return true; + step.execute().then((state) => { + this.state = state; + }).catch(err => { + this.state = new States.ValetudoUpdaterErrorState({ + type: err.type, + message: err.message + }); + }); } + /** + * @return {void} + */ triggerDownload() { if (!(this.state instanceof States.ValetudoUpdaterApprovalPendingState)) { throw new Error("Downloads can only be started when there's pending approval"); } - + const downloadPath = this.state.downloadPath; this.state.busy = true; - this.download().catch(err => { - //This should never happen - Logger.error("Unexpected error during download", err); - }); - - return true; - } - - triggerApply() { - if (!(this.state instanceof States.ValetudoUpdaterApplyPendingState)) { - throw new Error("Can only apply if there's finalization pending"); - } - this.state.busy = true; - this.apply().catch(err => { - //This should never happen - Logger.error("Unexpected error during apply", err); + const step = new Steps.ValetudoUpdaterDownloadStep({ + downloadUrl: this.state.downloadUrl, + downloadPath: this.state.downloadPath, + expectedHash: this.state.expectedHash, + version: this.state.version, + releaseTimestamp: this.state.releaseTimestamp }); - return true; - } - - async apply() { - const applyPendingState = this.state; - - fs.unlinkSync(process.argv0); - fs.copyFileSync(applyPendingState.downloadPath, process.argv0); - fs.chmodSync(process.argv0, fs.constants.S_IXUSR | fs.constants.S_IXGRP | fs.constants.S_IXOTH); - fs.unlinkSync(applyPendingState.downloadPath); - - spawnSync("sync"); - spawnSync("reboot"); - } - - async download() { - const approvalState = this.state; - const downloadingState = new States.ValetudoUpdaterDownloadingState({ - version: approvalState.version, - releaseTimestamp: approvalState.releaseTimestamp, - downloadUrl: approvalState.downloadUrl, - expectedHash: approvalState.expectedHash, - downloadPath: approvalState.downloadPath + this.state = new States.ValetudoUpdaterDownloadingState({ + downloadUrl: this.state.downloadUrl, + downloadPath: this.state.downloadPath, + expectedHash: this.state.expectedHash, + version: this.state.version, + releaseTimestamp: this.state.releaseTimestamp }); + this.state.busy = true; - this.state = downloadingState; - - try { - const downloadResponse = await axios.get(downloadingState.downloadUrl, {responseType: "stream"}); - await pipeline( - downloadResponse.data, - fs.createWriteStream(downloadingState.downloadPath) - ); - } catch (e) { - Logger.error("Error while downloading release binary", e); - - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.DOWNLOAD_FAILED, - message: "Error while downloading release binary" - }); - - return; - } - - let checksum; - - try { - checksum = await new Promise((resolve, reject) => { - const hash = crypto.createHash("sha256"); - const readStream = fs.createReadStream(downloadingState.downloadPath); - - readStream.on("error", err => { - reject(err); - }); - - readStream.on("data", data => { - hash.update(data); - }); - - readStream.on("end", () => { - resolve(hash.digest("hex")); - }); - }); - } catch (e) { - Logger.error("Error while calculating downloaded binary checksum", e); - - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.UNKNOWN, - message: "Error while calculating downloaded binary checksum" - }); - } - - if (checksum !== downloadingState.expectedHash) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.INVALID_CHECKSUM, - message: `Expected Checksum: ${downloadingState.expectedHash}. Actual: ${checksum}` - }); - } else { - this.state = new States.ValetudoUpdaterApplyPendingState({ - version: downloadingState.version, - releaseTimestamp: downloadingState.releaseTimestamp, - downloadPath: downloadingState.downloadPath - }); + step.execute().then((state) => { + this.state = state; setTimeout(() => { Logger.warn("Updater: User confirmation timeout."); - fs.unlinkSync(downloadingState.downloadPath); + fs.unlinkSync(downloadPath); this.state = new States.ValetudoUpdaterIdleState({ currentVersion: Tools.GET_VALETUDO_VERSION() }); - - }, 10 * 60 * 1000); - } - - } - - - /** - * - * @private - */ - async check() { - const lowmemRequired = Tools.IS_LOWMEM_HOST(); - const archRequired = Updater.ARCHITECTURES[process.arch]; - const currentVersion = Tools.GET_VALETUDO_VERSION(); - let binaryRequired = `valetudo-${archRequired}${lowmemRequired ? "-lowmem" : ""}${Tools.IS_UPX_COMPRESSED(process.argv0) ? ".upx" : ""}`; - - if (this.config.get("embedded") !== true) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_EMBEDDED, - message: "Updating is only possible in embedded mode" - }); - - return; - } - - try { - await this.robot.pollState(); - } catch (e) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.UNKNOWN, - message: "Error while polling the robots state" - }); - } - - const statusAttribute = this.robot.state.getFirstMatchingAttributeByConstructor( - stateAttrs.StatusStateAttribute - ); - - if (!(statusAttribute && statusAttribute.value === stateAttrs.StatusStateAttribute.VALUE.DOCKED)) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_DOCKED, - message: "Updating is only possible while the robot is docked" - }); - - return; - } - - - const downloadPath = this.getDownloadPath(); - - if (!downloadPath) { //This works because getDownloadPath already set the correct current state - return; - } - - let releases; - try { - releases = await this.updateProvider.fetchReleases(); - } catch (e) { - Logger.error("Error while fetching releases", e); - - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.DOWNLOAD_FAILED, - message: "Error while fetching releases" - }); - - return; - } - - - const releaseVersions = releases.map(r => { - return r.version; - }); - const currentVersionIndex = releaseVersions.indexOf(currentVersion); - let releaseToDownload; - - - if (currentVersionIndex === -1) { //Default to the latest release - releaseToDownload = releases[0]; - } else if (currentVersionIndex > 0) { //Always try to pick the next chronological release if possible - releaseToDownload = releases[currentVersionIndex-1]; - } else { //We're already on the latest release - let changelog; - - if (releases[0] && releases[0].version === currentVersion && releases[0].changelog) { - changelog = releases[0].changelog; - } - - this.state = new States.ValetudoUpdaterNoUpdateRequiredState({ - currentVersion: currentVersion, - changelog: changelog - }); - - return; - } - - if (!releaseToDownload) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NO_RELEASE, - message: "No release found" - }); - - return; - } - - let releaseBinaries; - try { - releaseBinaries = await this.updateProvider.fetchBinariesForRelease(releaseToDownload); - } catch (e) { - Logger.error(`Error while fetching release binaries for ${releaseToDownload.version}`, e); - - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.DOWNLOAD_FAILED, - message: `Error while fetching release binaries for ${releaseToDownload.version}` - }); - - return; - } - - const binaryToUse = releaseBinaries.find(b => { - return b.name === binaryRequired; - }); - - if (!binaryToUse) { + }, 10 * 60 * 1000); // 10 minutes + }).catch(err => { this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NO_MATCHING_BINARY, - message: `Release ${releaseToDownload.version} doesn't feature a ${binaryRequired} binary.` + type: err.type, + message: err.message }); - - return; - } - - this.state = new States.ValetudoUpdaterApprovalPendingState({ - version: releaseToDownload.version, - releaseTimestamp: releaseToDownload.releaseTimestamp, - changelog: releaseToDownload.changelog, - downloadUrl: binaryToUse.downloadUrl, - expectedHash: binaryToUse.sha256sum, - downloadPath: path.join(downloadPath, uuid.v4()) }); } /** - * @private - * @return {string|null} + * @return {void} */ - getDownloadPath() { - let downloadLocation; - - try { - fs.accessSync(process.argv0, fs.constants.W_OK); - } catch (e) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_WRITABLE, - message: `Updating is impossible because binary location "${process.argv0}" is not writable.` - }); - - return null; - } - - const spaceBinaryLocation = Tools.GET_DISK_SPACE_INFO(process.argv0); - - if (spaceBinaryLocation === null) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_ENOUGH_SPACE, - message: `Unable to determine the free space of ${process.argv0}.` - }); - - return null; - } else if (spaceBinaryLocation.free < Updater.SPACE_REQUIREMENTS) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_ENOUGH_SPACE, - message: ` - Updating is impossible because there's not enough space to store the new binary at ${process.argv0}. - Required: ${Updater.SPACE_REQUIREMENTS} bytes. Available: ${spaceBinaryLocation.free} bytes. - ` - }); - - return null; + triggerApply() { + if (!(this.state instanceof States.ValetudoUpdaterApplyPendingState)) { + throw new Error("Can only apply if there's finalization pending"); } - const tmpPath = os.tmpdir(); - const spaceTmp = Tools.GET_DISK_SPACE_INFO(tmpPath); - - if (spaceTmp === null) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_ENOUGH_SPACE, - message: `Unable to determine the free space of ${tmpPath}.` - }); - - return null; - } else if (spaceTmp.free < Updater.SPACE_REQUIREMENTS) { - const shmPath = "/dev/shm"; - const spaceShm = Tools.GET_DISK_SPACE_INFO(shmPath); - - if (spaceShm === null) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_ENOUGH_SPACE, - message: `Unable to determine the free space of ${shmPath}.` - }); - - return null; - } else if (spaceShm.free < Updater.SPACE_REQUIREMENTS) { - this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_ENOUGH_SPACE, - message: ` - Updating is impossible because there's no download location with enough free space available. - Required: ${Updater.SPACE_REQUIREMENTS} bytes. - - ${tmpPath} only has ${spaceTmp.free} bytes of free space. - ${shmPath} only has ${spaceShm.free} bytes of free space. - ` - }); + this.state.busy = true; - return null; - } else { - downloadLocation = shmPath; - } - } else { - downloadLocation = tmpPath; - } + const step = new Steps.ValetudoUpdaterApplyStep({ + downloadPath: this.state.downloadPath + }); - try { - fs.accessSync(downloadLocation, fs.constants.W_OK); - } catch (e) { + step.execute().catch(err => { //no .then() required as the system will reboot this.state = new States.ValetudoUpdaterErrorState({ - type: States.ValetudoUpdaterErrorState.ERROR_TYPE.NOT_WRITABLE, - message: `Updating is impossible because download location "${downloadLocation}" is not writable.` + type: err.type, + message: err.message }); - - return null; - } - - return downloadLocation; + }); } } diff --git a/backend/lib/updater/lib/UpdaterUtils.js b/backend/lib/updater/lib/UpdaterUtils.js new file mode 100644 index 00000000..b0ca617b --- /dev/null +++ b/backend/lib/updater/lib/UpdaterUtils.js @@ -0,0 +1,128 @@ +const fs = require("fs"); +const LinuxTools = require("../../utils/LinuxTools"); +const os = require("os"); +const ValetudoUpdaterError = require("./ValetudoUpdaterError"); + +/** + * @param {number} spaceRequired + * + * @return {string} + * @throws {ValetudoUpdaterError} + */ +function getDownloadPath(spaceRequired) { + let downloadLocation; + + try { + fs.accessSync(process.argv0, fs.constants.W_OK); + } catch (e) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_WRITABLE, + `Updating is impossible because binary location "${process.argv0}" is not writable.` + ); + } + + const spaceBinaryLocation = LinuxTools.GET_DISK_SPACE_INFO(process.argv0); + + if (spaceBinaryLocation === null) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_ENOUGH_SPACE, + `Unable to determine the free space of ${process.argv0}.` + ); + } else if (spaceBinaryLocation.free < spaceRequired) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_ENOUGH_SPACE, + `Updating is impossible because there's not enough space to store the new binary at ${process.argv0}.` + "\n" + + `Required: ${spaceRequired} bytes. Available: ${spaceBinaryLocation.free} bytes.` + ); + } + + const tmpPath = os.tmpdir(); + const spaceTmp = LinuxTools.GET_DISK_SPACE_INFO(tmpPath); + + if (spaceTmp === null) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_ENOUGH_SPACE, + `Unable to determine the free space of ${tmpPath}.` + ); + } else if (spaceTmp.free < spaceRequired) { + const shmPath = "/dev/shm"; + const spaceShm = LinuxTools.GET_DISK_SPACE_INFO(shmPath); + + if (spaceShm === null) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_ENOUGH_SPACE, + `Unable to determine the free space of ${shmPath}.` + ); + } else if (spaceShm.free < spaceRequired) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_ENOUGH_SPACE, + ` + Updating is impossible because there's no download location with enough free space available. + Required: ${spaceRequired} bytes. + + ${tmpPath} only has ${spaceTmp.free} bytes of free space. + ${shmPath} only has ${spaceShm.free} bytes of free space. + ` + ); + } else { + downloadLocation = shmPath; + } + } else { + downloadLocation = tmpPath; + } + + try { + fs.accessSync(downloadLocation, fs.constants.W_OK); + } catch (e) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_WRITABLE, + `Updating is impossible because download location "${downloadLocation}" is not writable.` + ); + } + + return downloadLocation; +} + +/** + * + * @param {Array} releases + * @param {string} currentVersion + * + * @return {{release: import("./update_provider/ValetudoRelease"), updateRequired: boolean}} + * @throws {ValetudoUpdaterError} + */ +function determineReleaseToDownload(releases, currentVersion) { + if (releases.length === 0) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NO_RELEASE, + "No release found" + ); + } + + const releaseVersions = releases.map(r => { + return r.version; + }); + const currentVersionIndex = releaseVersions.indexOf(currentVersion); + + if (currentVersionIndex === -1) { //Default to the latest release + return { + release: releases[0], + updateRequired: true + }; + } else if (currentVersionIndex > 0) { //Always try to pick the next chronological release if possible + return { + release: releases[currentVersionIndex-1], + updateRequired: true + }; + } else { //We're already on the latest release + return { + release: releases[0], + updateRequired: false + }; + } +} + +module.exports = { + getDownloadPath: getDownloadPath, + determineReleaseToDownload: determineReleaseToDownload +}; diff --git a/backend/lib/updater/lib/ValetudoUpdaterError.js b/backend/lib/updater/lib/ValetudoUpdaterError.js new file mode 100644 index 00000000..827779d8 --- /dev/null +++ b/backend/lib/updater/lib/ValetudoUpdaterError.js @@ -0,0 +1,33 @@ +class ValetudoUpdaterError extends Error { + /** + * + * @param {ValetudoUpdaterErrorType} type + * @param {string} message + */ + constructor(type, message) { + super(message); + this.name = "ValetudoUpdaterError"; + + this.type = type; + } +} + +/** + * @typedef {string} ValetudoUpdaterErrorType + * @enum {string} + * + */ +ValetudoUpdaterError.ERROR_TYPE = Object.freeze({ + UNKNOWN: "unknown", + NOT_EMBEDDED: "not_embedded", + NOT_DOCKED: "not_docked", + NOT_WRITABLE: "not_writable", + NOT_ENOUGH_SPACE: "not_enough_space", + DOWNLOAD_FAILED: "download_failed", + NO_RELEASE: "no_release", + NO_MATCHING_BINARY: "no_matching_binary", + INVALID_CHECKSUM: "invalid_checksum", +}); + + +module.exports = ValetudoUpdaterError; diff --git a/backend/lib/updater/lib/steps/ValetudoUpdaterApplyStep.js b/backend/lib/updater/lib/steps/ValetudoUpdaterApplyStep.js new file mode 100644 index 00000000..abf853bf --- /dev/null +++ b/backend/lib/updater/lib/steps/ValetudoUpdaterApplyStep.js @@ -0,0 +1,28 @@ +const fs = require("fs"); +const ValetudoUpdaterStep = require("./ValetudoUpdaterStep"); +const {spawnSync} = require("child_process"); + +class ValetudoUpdaterApplyStep extends ValetudoUpdaterStep { + /** + * @param {object} options + * @param {string} options.downloadPath + */ + constructor(options) { + super(); + + this.downloadPath = options.downloadPath; + } + + // @ts-ignore - Because spawnSync("reboot") ends our process, we don't have to return anything + async execute() { + fs.unlinkSync(process.argv0); + fs.copyFileSync(this.downloadPath, process.argv0); + fs.chmodSync(process.argv0, fs.constants.S_IXUSR | fs.constants.S_IXGRP | fs.constants.S_IXOTH); + fs.unlinkSync(this.downloadPath); + + spawnSync("sync"); + spawnSync("reboot"); + } +} + +module.exports = ValetudoUpdaterApplyStep; diff --git a/backend/lib/updater/lib/steps/ValetudoUpdaterCheckStep.js b/backend/lib/updater/lib/steps/ValetudoUpdaterCheckStep.js new file mode 100644 index 00000000..7caa5d2a --- /dev/null +++ b/backend/lib/updater/lib/steps/ValetudoUpdaterCheckStep.js @@ -0,0 +1,127 @@ +const Logger = require("../../../Logger"); +const path = require("path/posix"); +const stateAttrs = require("../../../entities/state/attributes"); +const States = require("../../../entities/core/updater"); +const Tools = require("../../../utils/Tools"); +const UpdaterUtils = require("../UpdaterUtils"); +const uuid = require("uuid"); +const ValetudoUpdaterError = require("../ValetudoUpdaterError"); +const ValetudoUpdaterStep = require("./ValetudoUpdaterStep"); + +class ValetudoUpdaterCheckStep extends ValetudoUpdaterStep { + /** + * @param {object} options + * @param {boolean} options.embedded + * @param {object} options.architectures + * @param {number} options.spaceRequired + * @param {import("../../../core/ValetudoRobot")} options.robot + * @param {import("../update_provider/ValetudoUpdateProvider")} options.updateProvider + */ + constructor(options) { + super(); + + this.embedded = options.embedded; + this.architectures = options.architectures; + this.spaceRequired = options.spaceRequired; + + this.robot = options.robot; + this.updateProvider = options.updateProvider; + } + + async execute() { + const lowmemRequired = Tools.IS_LOWMEM_HOST(); + const archRequired = this.architectures[process.arch]; + const currentVersion = Tools.GET_VALETUDO_VERSION(); + let binaryRequired = `valetudo-${archRequired}${lowmemRequired ? "-lowmem" : ""}${Tools.IS_UPX_COMPRESSED(process.argv0) ? ".upx" : ""}`; + + if (this.embedded !== true) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_EMBEDDED, + "Updating is only possible in embedded mode" + ); + } + + try { + await this.robot.pollState(); + } catch (e) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.UNKNOWN, + "Error while polling the robots state" + ); + } + + const statusAttribute = this.robot.state.getFirstMatchingAttributeByConstructor( + stateAttrs.StatusStateAttribute + ); + + if (!(statusAttribute && statusAttribute.value === stateAttrs.StatusStateAttribute.VALUE.DOCKED)) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NOT_DOCKED, + "Updating is only possible while the robot is docked" + ); + } + + + const downloadPath = UpdaterUtils.getDownloadPath(this.spaceRequired); //Also throws a ValetudoUpdaterError + + let releases; + try { + releases = await this.updateProvider.fetchReleases(); + } catch (e) { + Logger.error("Error while fetching releases", e); + + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.DOWNLOAD_FAILED, + "Error while fetching releases" + ); + } + + const releaseToDownload = UpdaterUtils.determineReleaseToDownload(releases, currentVersion); + if (releaseToDownload.updateRequired === false) { + let changelog; + + if (releaseToDownload.release.version === currentVersion && releaseToDownload.release.changelog) { + changelog = releaseToDownload.release.changelog; + } + + return new States.ValetudoUpdaterNoUpdateRequiredState({ + currentVersion: currentVersion, + changelog: changelog + }); + } + + let releaseBinaries; + try { + releaseBinaries = await this.updateProvider.fetchBinariesForRelease(releaseToDownload.release); + } catch (e) { + Logger.error(`Error while fetching release binaries for ${releaseToDownload.release.version}`, e); + + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.DOWNLOAD_FAILED, + `Error while fetching release binaries for ${releaseToDownload.release.version}` + ); + } + + const binaryToUse = releaseBinaries.find(b => { + return b.name === binaryRequired; + }); + + if (!binaryToUse) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.NO_MATCHING_BINARY, + `Release ${releaseToDownload.release.version} doesn't feature a ${binaryRequired} binary.` + ); + } + + return new States.ValetudoUpdaterApprovalPendingState({ + version: releaseToDownload.release.version, + releaseTimestamp: releaseToDownload.release.releaseTimestamp, + changelog: releaseToDownload.release.changelog, + downloadUrl: binaryToUse.downloadUrl, + expectedHash: binaryToUse.sha256sum, + downloadPath: path.join(downloadPath, uuid.v4()) + }); + } +} + +module.exports = ValetudoUpdaterCheckStep; diff --git a/backend/lib/updater/lib/steps/ValetudoUpdaterDownloadStep.js b/backend/lib/updater/lib/steps/ValetudoUpdaterDownloadStep.js new file mode 100644 index 00000000..fa8f76b3 --- /dev/null +++ b/backend/lib/updater/lib/steps/ValetudoUpdaterDownloadStep.js @@ -0,0 +1,90 @@ +const axios = require("axios").default; +const crypto = require("crypto"); +const fs = require("fs"); +const Logger = require("../../../Logger"); +const States = require("../../../entities/core/updater"); +const ValetudoUpdaterError = require("../ValetudoUpdaterError"); +const ValetudoUpdaterStep = require("./ValetudoUpdaterStep"); +const {pipeline} = require("stream/promises"); + +class ValetudoUpdaterDownloadStep extends ValetudoUpdaterStep { + /** + * @param {object} options + * @param {string} options.downloadUrl + * @param {string} options.downloadPath + * @param {string} options.expectedHash + * @param {string} options.version + * @param {Date} options.releaseTimestamp + * + */ + constructor(options) { + super(); + + this.downloadUrl = options.downloadUrl; + this.downloadPath = options.downloadPath; + this.expectedHash = options.expectedHash; + this.version = options.version; + this.releaseTimestamp = options.releaseTimestamp; + } + + + async execute() { + try { + const downloadResponse = await axios.get(this.downloadUrl, {responseType: "stream"}); + await pipeline( + downloadResponse.data, + fs.createWriteStream(this.downloadPath) + ); + } catch (e) { + Logger.error("Error while downloading release binary", e); + + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.DOWNLOAD_FAILED, + "Error while downloading release binary" + ); + } + + let checksum; + + try { + checksum = await new Promise((resolve, reject) => { + const hash = crypto.createHash("sha256"); + const readStream = fs.createReadStream(this.downloadPath); + + readStream.on("error", err => { + reject(err); + }); + + readStream.on("data", data => { + hash.update(data); + }); + + readStream.on("end", () => { + resolve(hash.digest("hex")); + }); + }); + } catch (e) { + Logger.error("Error while calculating downloaded binary checksum", e); + + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.UNKNOWN, + "Error while calculating downloaded binary checksum" + ); + } + + if (checksum !== this.expectedHash) { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.INVALID_CHECKSUM, + `Expected Checksum: ${this.expectedHash}. Actual: ${checksum}` + ); + } else { + return new States.ValetudoUpdaterApplyPendingState({ + version: this.version, + releaseTimestamp: this.releaseTimestamp, + downloadPath: this.downloadPath + }); + } + } +} + +module.exports = ValetudoUpdaterDownloadStep; diff --git a/backend/lib/updater/lib/steps/ValetudoUpdaterStep.js b/backend/lib/updater/lib/steps/ValetudoUpdaterStep.js new file mode 100644 index 00000000..a50859b3 --- /dev/null +++ b/backend/lib/updater/lib/steps/ValetudoUpdaterStep.js @@ -0,0 +1,19 @@ +const ValetudoUpdaterError = require("../ValetudoUpdaterError"); +const ValetudoUpdaterState = require("../../../entities/core/updater/ValetudoUpdaterState"); + +class ValetudoUpdaterStep { + /** + * @abstract + * + * @returns {Promise} + * @throws {ValetudoUpdaterError} + */ + async execute() { + throw new ValetudoUpdaterError( + ValetudoUpdaterError.ERROR_TYPE.UNKNOWN, + "Empty ValetudoUpdaterStep implementation" + ); + } +} + +module.exports = ValetudoUpdaterStep; diff --git a/backend/lib/updater/lib/steps/index.js b/backend/lib/updater/lib/steps/index.js new file mode 100644 index 00000000..be06a034 --- /dev/null +++ b/backend/lib/updater/lib/steps/index.js @@ -0,0 +1,5 @@ +module.exports = { + ValetudoUpdaterApplyStep: require("./ValetudoUpdaterApplyStep"), + ValetudoUpdaterCheckStep: require("./ValetudoUpdaterCheckStep"), + ValetudoUpdaterDownloadStep: require("./ValetudoUpdaterDownloadStep"), +}; diff --git a/backend/lib/updater/update_provider/GithubValetudoNightlyUpdateProvider.js b/backend/lib/updater/lib/update_provider/GithubValetudoNightlyUpdateProvider.js similarity index 80% rename from backend/lib/updater/update_provider/GithubValetudoNightlyUpdateProvider.js rename to backend/lib/updater/lib/update_provider/GithubValetudoNightlyUpdateProvider.js index 1c22fbb2..48190235 100644 --- a/backend/lib/updater/update_provider/GithubValetudoNightlyUpdateProvider.js +++ b/backend/lib/updater/lib/update_provider/GithubValetudoNightlyUpdateProvider.js @@ -21,11 +21,24 @@ class GithubValetudoNightlyUpdateProvider extends ValetudoUpdateProvider { throw new Error("GithubValetudoNightlyUpdateProvider: Received invalid branch response"); } + let changelog = rawBranchResponse.data.commit.commit.message; + let manifest; + + try { + manifest = await this.fetchManifest(); + + if (typeof manifest?.changelog === "string") { + changelog = manifest.changelog; + } + } catch (e) { + // intentional + } + return [ new ValetudoRelease({ version: rawBranchResponse.data.commit.sha, releaseTimestamp: new Date(rawBranchResponse.data.commit.commit.committer.date), - changelog: rawBranchResponse.data.commit.commit.message, + changelog: changelog, }) ]; } @@ -35,18 +48,10 @@ class GithubValetudoNightlyUpdateProvider extends ValetudoUpdateProvider { * @return {Promise>} */ async fetchBinariesForRelease(release) { - let releaseBinaries = []; - let rawManifestResponse = await axios.get(`${GithubValetudoNightlyUpdateProvider.ASSET_BASE_URL}${GithubValetudoNightlyUpdateProvider.MANIFEST_NAME}`); - - // @ts-ignore - if (!rawManifestResponse.data) { - throw new Error(`GithubValetudoNightlyUpdateProvider: Invalid ${GithubValetudoNightlyUpdateProvider.MANIFEST_NAME}`); - } - - const manifest = rawManifestResponse.data; + const manifest = await this.fetchManifest(); // @ts-ignore - releaseBinaries = Object.keys(manifest.sha256sums).map(name => { + return Object.keys(manifest.sha256sums).map(name => { return new ValetudoReleaseBinary({ name: name, // @ts-ignore @@ -54,12 +59,28 @@ class GithubValetudoNightlyUpdateProvider extends ValetudoUpdateProvider { downloadUrl: `${GithubValetudoNightlyUpdateProvider.ASSET_BASE_URL}${GithubValetudoNightlyUpdateProvider.BINARY_NAMES[name]}` }); }); + } - return releaseBinaries; + + /** + * @private + * @return {Promise} + */ + async fetchManifest() { + let rawManifestResponse = await axios.get(`${GithubValetudoNightlyUpdateProvider.ASSET_BASE_URL}${GithubValetudoNightlyUpdateProvider.MANIFEST_NAME}`); + + // @ts-ignore + if (!rawManifestResponse.data) { + throw new Error(`GithubValetudoNightlyUpdateProvider: Invalid ${GithubValetudoNightlyUpdateProvider.MANIFEST_NAME}`); + } + + return rawManifestResponse.data; } } +GithubValetudoNightlyUpdateProvider.TYPE = "github_nightly"; + GithubValetudoNightlyUpdateProvider.REPO_URL = "https://api.github.com/repos/Hypfer/valetudo-nightly-builds/branches/master"; GithubValetudoNightlyUpdateProvider.ASSET_BASE_URL = "https://raw.githubusercontent.com/Hypfer/valetudo-nightly-builds/master/"; GithubValetudoNightlyUpdateProvider.MANIFEST_NAME = "valetudo_release_manifest.json"; diff --git a/backend/lib/updater/update_provider/GithubValetudoUpdateProvider.js b/backend/lib/updater/lib/update_provider/GithubValetudoUpdateProvider.js similarity index 90% rename from backend/lib/updater/update_provider/GithubValetudoUpdateProvider.js rename to backend/lib/updater/lib/update_provider/GithubValetudoUpdateProvider.js index 1024117c..9d90f7bc 100644 --- a/backend/lib/updater/update_provider/GithubValetudoUpdateProvider.js +++ b/backend/lib/updater/lib/update_provider/GithubValetudoUpdateProvider.js @@ -10,30 +10,13 @@ class GithubValetudoUpdateProvider extends ValetudoUpdateProvider { */ async fetchReleases() { let rawReleasesResponse = await axios.get(GithubValetudoUpdateProvider.RELEASES_URL); - let releases = []; + if (!Array.isArray(rawReleasesResponse?.data)) { throw new Error("GithubValetudoUpdateProvider: Received invalid releases response"); } - releases = rawReleasesResponse.data.filter(rR => { - return rR.prerelease === false && rR.draft === false; - }).map(rR => { - return new ValetudoRelease({ - version: rR.tag_name, - releaseTimestamp: new Date(rR.published_at), - changelog: rR.body, - metaData: { - githubReleaseUrl: rR.url - } - }); - }); - - releases.sort((a, b) => { - return b.releaseTimestamp.getTime() - a.releaseTimestamp.getTime(); - }); - - return releases; + return this.parseReleaseOverviewApiResponse(rawReleasesResponse.data); } /** @@ -88,10 +71,36 @@ class GithubValetudoUpdateProvider extends ValetudoUpdateProvider { return releaseBinaries; } + + /** + * @param {object} data + * @return {Array} + */ + parseReleaseOverviewApiResponse(data) { + const releases = data.filter(rR => { + return rR.prerelease === false && rR.draft === false; + }).map(rR => { + return new ValetudoRelease({ + version: rR.tag_name, + releaseTimestamp: new Date(rR.published_at), + changelog: rR.body, + metaData: { + githubReleaseUrl: rR.url + } + }); + }); + + releases.sort((a, b) => { + return b.releaseTimestamp.getTime() - a.releaseTimestamp.getTime(); + }); + + return releases; + } } -GithubValetudoUpdateProvider.RELEASES_URL = "https://api.github.com/repos/freeconga/Valetudo/releases"; +GithubValetudoUpdateProvider.TYPE = "github"; +GithubValetudoUpdateProvider.RELEASES_URL = "https://api.github.com/repos/freeconga/Congatudo/releases"; GithubValetudoUpdateProvider.MANIFEST_NAME = "valetudo_release_manifest.json"; diff --git a/backend/lib/updater/update_provider/ValetudoRelease.js b/backend/lib/updater/lib/update_provider/ValetudoRelease.js similarity index 100% rename from backend/lib/updater/update_provider/ValetudoRelease.js rename to backend/lib/updater/lib/update_provider/ValetudoRelease.js diff --git a/backend/lib/updater/update_provider/ValetudoReleaseBinary.js b/backend/lib/updater/lib/update_provider/ValetudoReleaseBinary.js similarity index 100% rename from backend/lib/updater/update_provider/ValetudoReleaseBinary.js rename to backend/lib/updater/lib/update_provider/ValetudoReleaseBinary.js diff --git a/backend/lib/updater/update_provider/ValetudoUpdateProvider.js b/backend/lib/updater/lib/update_provider/ValetudoUpdateProvider.js similarity index 89% rename from backend/lib/updater/update_provider/ValetudoUpdateProvider.js rename to backend/lib/updater/lib/update_provider/ValetudoUpdateProvider.js index cf9422a4..23a94569 100644 --- a/backend/lib/updater/update_provider/ValetudoUpdateProvider.js +++ b/backend/lib/updater/lib/update_provider/ValetudoUpdateProvider.js @@ -1,4 +1,4 @@ -const NotImplementedError = require("../../core/NotImplementedError"); +const NotImplementedError = require("../../../core/NotImplementedError"); class ValetudoUpdateProvider { constructor() { diff --git a/backend/lib/utils/KeyValueDeduplicationCache.js b/backend/lib/utils/KeyValueDeduplicationCache.js new file mode 100644 index 00000000..417705df --- /dev/null +++ b/backend/lib/utils/KeyValueDeduplicationCache.js @@ -0,0 +1,80 @@ +const crypto = require("crypto"); +const os = require("os"); + +class KeyValueDeduplicationCache { + /** + * This thing keeps track of key/value pairs to find out if they've changed. + * + * Instead of storing the whole payload, we'll just store a hash to save memory + * The hashing algorithm is determined based on the hardware we're running on as benchmarks have shown + * that performance may vary greatly based on cpu architecture + * + * Strings in JS are UTF-16 take up 2 byte per character, which ends up as 80 bytes for sha1 and 64 for md5 + * Numbers in JS however will always just take up 8 bytes so instead of saving the hash in hex or base64, + * we take as much of the hashes a JS number can safely fit and store that. This enables us to greatly reduce + * the likelihood of collisions without having to use more memory + * + * As JS numbers are IEEE-754 doubles, we may safely use up to 2^52-1 without any precision loss + * 0xfffffffffffff (13x f) is exactly that 2^52-1 + * Thus, we just take the first 13 characters of the hash digest in hex, parse that as int, and we're good. + * + * Thanks to Raman Shishniou for this idea! + * + * + * @param {object} options + */ + constructor(options) { + this.hashingAlgorithm = KeyValueDeduplicationCache.determineHashAlgorithm(); + + this.clear(); + } + + clear() { + this.cache = new Map(); + } + + /** + * Returns true if the new value differs from the stored one + * otherwise returns false + * + * Works with strings and buffers. Everything else will always return true + * + * @param {string} key + * @param {any} value + * @return {boolean} + */ + update(key, value) { + if (typeof value === "string" || Buffer.isBuffer(value)) { + const derivedKey = parseInt(crypto.createHash(this.hashingAlgorithm).update(key).digest("hex").substring(0, 13), 16); + const derivedValue = parseInt(crypto.createHash(this.hashingAlgorithm).update(value).digest("hex").substring(0, 13), 16); + + // An empty cache for the key will return undefined, which is != any hash. This saves a check :) + if (this.cache.get(derivedKey) !== derivedValue) { + this.cache.set(derivedKey, derivedValue); + + return true; + } else { + return false; + } + } else { + return true; + } + } + + static determineHashAlgorithm() { + let algorithm = "sha1"; + const cpus = os.cpus(); + + // Another approach could be to do a short benchmark on startup like mdadm does, however that would increase startup times. + if (Array.isArray(cpus) && cpus.length > 0) { + // Benchmarks have shown that md5 is a lot faster on armv7 than sha1, which is the exact opposite of the results on aarch64 and x86 + if (cpus[0].model.startsWith("ARMv7 Processor")) { + algorithm = "md5"; + } + } + + return algorithm; + } +} + +module.exports = KeyValueDeduplicationCache; diff --git a/backend/lib/utils/LinuxTools.js b/backend/lib/utils/LinuxTools.js new file mode 100644 index 00000000..d5cc60b8 --- /dev/null +++ b/backend/lib/utils/LinuxTools.js @@ -0,0 +1,100 @@ +const fs = require("fs"); +const LinuxToolsHelper = require("./LinuxToolsHelper"); +const {spawnSync} = require("child_process"); + +class LinuxTools { + /** + * @return {object} + */ + static READ_PROC_CMDLINE() { + const cmdline = fs.readFileSync("/proc/cmdline").toString(); + + return LinuxToolsHelper.PARSE_PROC_CMDLINE(cmdline); + } + + /** + * @return {object} + */ + static READ_PROC_MEMINFO() { + const meminfo = fs.readFileSync("/proc/meminfo").toString(); + + return LinuxToolsHelper.PARSE_PROC_MEMINFO(meminfo); + } + + static GET_FREE_SYSTEM_MEMORY() { + const meminfo = LinuxTools.READ_PROC_MEMINFO(); + + /* + MemAvailable is only available on kernel 3.14 and newer + + See: https://manpages.debian.org/buster/manpages/proc.5.en.html + */ + if (meminfo["MemAvailable"] !== undefined) { + return meminfo["MemAvailable"]; + } else { + return meminfo["MemFree"] + meminfo["Buffers"] + meminfo["Cached"]; + } + } + + static GET_NETWORK_INTERFACE_MACS() { + const interfaces = fs.readdirSync("/sys/class/net"); + const macAddresses = new Set(); + + interfaces.forEach(i => { + const mac = fs.readFileSync(`/sys/class/net/${i}/address`).toString().trim(); + + if (!mac.startsWith("00:00")) { + /* + Some supported robots feature two wireless interfaces of which one is never used + as it is only capable of Wi-Fi direct + + Currently (2021-12-28) all wlan1 use the mac of wlan0 with the first octet incremented + by 2 which we'll use here to filter out the bogus interfaces + This might be specific to the realtek Wi-Fi chips used by basically all of them + + This code is not great. + */ + const octets = mac.split(":"); + const firstOctetAsNumber = parseInt(`0x${octets.shift()}`); + octets.unshift((firstOctetAsNumber - 2).toString(16)); + + const possibleBaseMac = octets.join(":"); + + if (!macAddresses.has(possibleBaseMac)) { + macAddresses.add(mac); + } + } + }); + + return Array.from(macAddresses.values()); + } + + /** + * Returns the total and free size in bytes + * + * @param {string} pathOnDisk + * @returns {{total: number, free: number} | null} + */ + static GET_DISK_SPACE_INFO(pathOnDisk) { + try { + //Inspired by https://github.com/Alex-D/check-disk-space + const dfResult = spawnSync("df", ["-Pk", "--", pathOnDisk]); + const dfOutput = dfResult.stdout.toString().trim().split("\n").slice(1).map(l => { + return l.trim().split(/\s+(?=[\d/])/); + }); + + if (dfOutput.length !== 1 || dfOutput[0].length !== 6) { + return null; + } + + return { + total: parseInt(dfOutput[0][1], 10) * 1024, + free: parseInt(dfOutput[0][3], 10) * 1024, + }; + } catch (e) { + return null; + } + } +} + +module.exports = LinuxTools; diff --git a/backend/lib/utils/LinuxToolsHelper.js b/backend/lib/utils/LinuxToolsHelper.js new file mode 100644 index 00000000..9c6417fa --- /dev/null +++ b/backend/lib/utils/LinuxToolsHelper.js @@ -0,0 +1,60 @@ +class LinuxToolsHelper { + static PARSE_PROC_CMDLINE(cmdline) { + const pairs = cmdline.trim().split(" "); + const output = {}; + + pairs.forEach(pair => { + const splitPair = pair.split("="); + + output[splitPair[0]] = splitPair[1] ?? true; + }); + + if (output["partitions"] !== undefined) { + output["partitions"] = LinuxToolsHelper.PARSE_PARTITIONS_LINUX_COMMANDLINE_PARAMETER(output["partitions"]); + } + + return output; + } + + /** + * The format can be found in /block/partitions/cmdline.c of the linux kernel source + * + * @param {string} partitions + */ + static PARSE_PARTITIONS_LINUX_COMMANDLINE_PARAMETER(partitions) { + const pairs = partitions.split(":"); + const output = {}; + + pairs.forEach(pair => { + const splitPair = pair.split("@"); + + //For consistency with other parameters such as "root", we prepend the "/dev/" here + output[`/dev/${splitPair[1]}`] = splitPair[0]; + }); + + return output; + } + + /** + * Note that all values are returned as bytes + * + * + * @param {string} meminfo + * @return {object} + */ + static PARSE_PROC_MEMINFO(meminfo) { + const output = {}; + + meminfo.trim().split("\n").forEach(line => { + const parsed = /^(?.+):\s+(?\d+) kB$/.exec(line); + + if (parsed?.groups?.key !== undefined && parsed?.groups?.value !== undefined) { + output[parsed.groups.key] = parseInt(parsed.groups.value) * 1024; + } + }); + + return output; + } +} + +module.exports = LinuxToolsHelper; diff --git a/backend/lib/utils/SSDPServer.js b/backend/lib/utils/SSDPServer.js new file mode 100644 index 00000000..7fa2518a --- /dev/null +++ b/backend/lib/utils/SSDPServer.js @@ -0,0 +1,102 @@ +const dgram = require("dgram"); +const Logger = require("../Logger"); +const Tools = require("./Tools"); + +/* + This class is inspired by these projects: + + https://github.com/diversario/node-ssdp + https://github.com/jlgallego99/simple-ssdp + */ + +class SSDPServer { + /** + * + * This is a very basic SSDP/UPNP server implementation, which works well enough + * to make valetudo show up in the network tab of the Windows explorer + * + * For now, it only supports IPv4 + * + * + * @param {object} options + * @param {number} options.port + */ + constructor(options) { + this.webserverPort = options.port; + + this.interfaces = Tools.GET_NETWORK_INTERFACES().filter(i => { + return i.family === "IPv4"; + }); + this.ip = this.interfaces[0]?.address ?? "127.0.0.1"; + + this.addMembershipTimeout = undefined; + } + + start() { + this.socket = dgram.createSocket({type: "udp4", reuseAddr: true}); + + this.socket.on("listening", () => { + Logger.debug(`SSDP: Socket bound to port ${MULTICAST_SSDP_PORT}`); + + /* + For some reason that is beyond me, we need to wait before we add the multicast membership, + as otherwise Valetudo simply won't receive the UDP packages + */ + this.addMembershipTimeout = setTimeout(() => { + for (let iface of this.interfaces) { + Logger.debug(`SSDP: Adding Multicast membership to ${MULTICAST_SSDP_ADDRESS_v4} for ${iface.address}`); + + try { + this.socket.addMembership(MULTICAST_SSDP_ADDRESS_v4, iface.address); + } catch (e) { + Logger.warn(`SSDP: Error while adding Multicast membership to ${MULTICAST_SSDP_ADDRESS_v4} for ${iface.address}`, e); + } + } + + this.socket.setMulticastTTL(4); + }, 2500); + }); + + this.socket.on("message", (msg, rinfo) => { + if (msg.includes("M-SEARCH") && msg.includes("ST: upnp:rootdevice")) { + Logger.debug(`SSDP: Received M-SEARCH request for upnp:rootdevice from ${rinfo.address}:${rinfo.port}`); + + const response = [ + "HTTP/1.1 200 OK", + "ST: upnp:rootdevice", + `USN: uuid:${Tools.GET_SYSTEM_ID()}::upnp:rootdevice`, + "CACHE-CONTROL: max-age=1800", + `SERVER: Valetudo/${Tools.GET_VALETUDO_VERSION()} UPnP/1.1`, + `LOCATION: http://${this.ip}:${this.webserverPort}/_ssdp/valetudo.xml`, + + "", + "" //Empty line at the end. Without this it won't work!! + ].join("\r\n"); + + this.socket.send(response, 0, response.length, rinfo.port, rinfo.address); + } + }); + + this.socket.on("error", (err) => { + Logger.warn("SSDP: Socket error", err); + }); + + this.socket.bind(MULTICAST_SSDP_PORT); + } + + stop() { + clearTimeout(this.addMembershipTimeout); + + if (this.socket) { + this.socket.close(); + + this.socket = undefined; + } + } +} + +const MULTICAST_SSDP_ADDRESS_v4 = "239.255.255.250"; +const MULTICAST_SSDP_PORT = 1900; + + +module.exports = SSDPServer; diff --git a/backend/lib/Tools.js b/backend/lib/utils/Tools.js similarity index 56% rename from backend/lib/Tools.js rename to backend/lib/utils/Tools.js index 6f903d3b..030e91f6 100644 --- a/backend/lib/Tools.js +++ b/backend/lib/utils/Tools.js @@ -1,18 +1,21 @@ const fs = require("fs"); const os = require("os"); const path = require("path"); -const spawnSync = require("child_process").spawnSync; const uuid = require("uuid"); const zooIDs = require("zoo-ids"); +const LinuxTools = require("./LinuxTools"); + let SYSTEM_ID; class Tools { static MK_DIR_PATH(filepath) { - var dirname = path.dirname(filepath); + const dirname = path.dirname(filepath); + if (!fs.existsSync(dirname)) { Tools.MK_DIR_PATH(dirname); } + if (!fs.existsSync(filepath)) { fs.mkdirSync(filepath); } @@ -40,7 +43,7 @@ class Tools { let valetudoVersion = "unknown"; try { - const rootDirectory = path.resolve(__dirname, "../.."); + const rootDirectory = path.resolve(__dirname, "../../.."); const packageContent = fs.readFileSync(rootDirectory + "/package.json", {"encoding": "utf-8"}); if (packageContent) { @@ -57,7 +60,7 @@ class Tools { let commitId = "unknown"; try { - const rootDirectory = path.resolve(__dirname, "../.."); + const rootDirectory = path.resolve(__dirname, "../../.."); commitId = fs.readFileSync(rootDirectory + "/.git/HEAD", {"encoding": "utf-8"}).trim(); if (commitId.match(/^ref: refs\/heads\/master$/) !== null) { @@ -71,31 +74,11 @@ class Tools { } static GET_FREE_SYSTEM_MEMORY() { - let considered_free; - - /* - We can't use MemAvailable here, since that's only available on kernel 3.14 and newer - however roborock still uses kernel 3.4 on some of their devices - - See: https://manpages.debian.org/buster/manpages/proc.5.en.html - */ - try { - const meminfo = fs.readFileSync("/proc/meminfo").toString(); - - const buffers = /^Buffers:\s*(?\d+) kB/m.exec(meminfo)?.groups?.buffers; - const cached = /^Cached:\s*(?\d+) kB/m.exec(meminfo)?.groups?.cached; - - considered_free = (parseInt(buffers) + parseInt(cached)) * 1024; - } catch (e) { - //intentional - } - - // This intentionally uses isNaN and not Number.isNaN - if (isNaN(considered_free)) { - considered_free = 0; + if (os.type() === "Linux") { + return LinuxTools.GET_FREE_SYSTEM_MEMORY(); + } else { + return os.freemem(); } - - return os.freemem() + considered_free; } static GET_SYSTEM_STATS() { @@ -123,13 +106,11 @@ class Tools { if (SYSTEM_ID) { return SYSTEM_ID; } - - - let macAddresses = Tools.GET_NETWORK_INTERFACE_MACS_FROM_NODEJS(); + let macAddresses = []; if (os.type() === "Linux") { try { - macAddresses = Tools.GET_NETWORK_INTERFACE_MACS_FROM_SYSFS(); + macAddresses = LinuxTools.GET_NETWORK_INTERFACE_MACS(); } catch (e) { /* Referencing the Logger here would be a circular dependency @@ -139,6 +120,8 @@ class Tools { // eslint-disable-next-line no-console console.warn("Error while retrieving network interface macs from sysfs", e); } + } else { + macAddresses = Tools.GET_NETWORK_INTERFACE_MACS_FROM_NODEJS(); } SYSTEM_ID = uuid.v5( @@ -157,58 +140,10 @@ class Tools { return "valetudo-" + Tools.GET_HUMAN_READABLE_SYSTEM_ID().toLowerCase() + ".local"; } - static PARSE_PROC_CMDLINE() { - const cmdline = fs.readFileSync("/proc/cmdline").toString()?.split(" ") ?? []; - const rootPartition = cmdline.find(e => { - return e.startsWith("root="); - })?.split("=")?.[1]?.replace("/dev/", ""); - - const partitions = {}; - cmdline.find(e => { - return e.startsWith("partitions="); - })?.split("=")?.[1]?.split(":")?.forEach(partitionEntry => { - const entry = partitionEntry.split("@"); - partitions[entry[1]] = entry[0]; - }); - - return { - cmdline: cmdline, - rootPartition: rootPartition, - partitions: partitions - }; - } - static CLONE(obj) { return JSON.parse(JSON.stringify(obj)); } - /** - * Returns the total and free size in bytes - * - * @param {string} pathOnDisk - * @returns {{total: number, free: number} | null} - */ - static GET_DISK_SPACE_INFO(pathOnDisk) { - try { - //Inspired by https://github.com/Alex-D/check-disk-space - const dfResult = spawnSync("df", ["-Pk", "--", pathOnDisk]); - const dfOutput = dfResult.stdout.toString().trim().split("\n").slice(1).map(l => { - return l.trim().split(/\s+(?=[\d/])/); - }); - - if (dfOutput.length !== 1 || dfOutput[0].length !== 6) { - return null; - } - - return { - total: parseInt(dfOutput[0][1], 10) * 1024, - free: parseInt(dfOutput[0][3], 10) * 1024, - }; - } catch (e) { - return null; - } - } - static IS_UPX_COMPRESSED(pathOnDisk) { let is_upx = false; @@ -270,37 +205,14 @@ class Tools { return [...new Set(macs)]; // dedupe } - static GET_NETWORK_INTERFACE_MACS_FROM_SYSFS() { - const interfaces = fs.readdirSync("/sys/class/net"); - const macAddresses = new Set(); - - interfaces.forEach(i => { - const mac = fs.readFileSync(`/sys/class/net/${i}/address`).toString().trim(); - - if (!mac.startsWith("00:00")) { - /* - Some supported robots feature two wireless interfaces of which one is never used - as it is only capable of Wi-Fi direct - - Currently (2021-12-28) all wlan1 use the mac of wlan0 with the first octet incremented - by 2 which we'll use here to filter out the bogus interfaces - This might be specific to the realtek Wi-Fi chips used by basically all of them - - This code is not great. - */ - const octets = mac.split(":"); - const firstOctetAsNumber = parseInt(`0x${octets.shift()}`); - octets.unshift((firstOctetAsNumber - 2).toString(16)); - - const possibleBaseMac = octets.join(":"); - - if (!macAddresses.has(possibleBaseMac)) { - macAddresses.add(mac); - } - } - }); + // taken from https://stackoverflow.com/a/34491287 + static IS_EMPTY_OBJECT_OR_UNDEFINED_OR_NULL(obj) { + // noinspection LoopStatementThatDoesntLoopJS + for (const x in obj) { + return false; + } - return Array.from(macAddresses.values()); + return true; } } diff --git a/backend/lib/webserver/CapabilitiesRouter.js b/backend/lib/webserver/CapabilitiesRouter.js index a8f14f98..7d40c839 100644 --- a/backend/lib/webserver/CapabilitiesRouter.js +++ b/backend/lib/webserver/CapabilitiesRouter.js @@ -54,6 +54,7 @@ const CAPABILITY_TYPE_TO_ROUTER_MAPPING = { [capabilities.BasicControlCapability.TYPE]: capabilityRouters.BasicControlCapabilityRouter, [capabilities.FanSpeedControlCapability.TYPE]: capabilityRouters.PresetSelectionCapabilityRouter, [capabilities.WaterUsageControlCapability.TYPE]: capabilityRouters.PresetSelectionCapabilityRouter, + [capabilities.OperationModeControlCapability.TYPE]: capabilityRouters.PresetSelectionCapabilityRouter, [capabilities.ConsumableMonitoringCapability.TYPE]: capabilityRouters.ConsumableMonitoringCapabilityRouter, [capabilities.ZoneCleaningCapability.TYPE]: capabilityRouters.ZoneCleaningCapabilityRouter, [capabilities.GoToLocationCapability.TYPE]: capabilityRouters.GoToLocationCapabilityRouter, @@ -63,7 +64,6 @@ const CAPABILITY_TYPE_TO_ROUTER_MAPPING = { [capabilities.ManualControlCapability.TYPE]: capabilityRouters.ManualControlCapabilityRouter, [capabilities.CombinedVirtualRestrictionsCapability.TYPE]: capabilityRouters.CombinedVirtualRestrictionsCapabilityRouter, [capabilities.PersistentMapControlCapability.TYPE]: capabilityRouters.SimpleToggleCapabilityRouter, - [capabilities.SensorCalibrationCapability.TYPE]: capabilityRouters.SensorCalibrationCapabilityRouter, [capabilities.SpeakerVolumeControlCapability.TYPE]: capabilityRouters.SpeakerVolumeControlCapabilityRouter, [capabilities.MapSegmentationCapability.TYPE]: capabilityRouters.MapSegmentationCapabilityRouter, [capabilities.DoNotDisturbCapability.TYPE]: capabilityRouters.DoNotDisturbCapabilityRouter, @@ -81,7 +81,9 @@ const CAPABILITY_TYPE_TO_ROUTER_MAPPING = { [capabilities.TotalStatisticsCapability.TYPE]: capabilityRouters.StatisticsCapabilityRouter, [capabilities.CurrentStatisticsCapability.TYPE]: capabilityRouters.StatisticsCapabilityRouter, [capabilities.QuirksCapability.TYPE]: capabilityRouters.QuirksCapabilityRouter, - [capabilities.WifiScanCapability.TYPE]: capabilityRouters.WifiScanCapabilityRouter + [capabilities.WifiScanCapability.TYPE]: capabilityRouters.WifiScanCapabilityRouter, + [capabilities.MopDockCleanManualTriggerCapability.TYPE]: capabilityRouters.MopDockCleanManualTriggerCapabilityRouter, + [capabilities.MopDockDryManualTriggerCapability.TYPE]: capabilityRouters.MopDockDryManualTriggerCapabilityRouter, }; module.exports = CapabilitiesRouter; diff --git a/backend/lib/webserver/MQTTRouter.js b/backend/lib/webserver/MQTTRouter.js new file mode 100644 index 00000000..f2166cdf --- /dev/null +++ b/backend/lib/webserver/MQTTRouter.js @@ -0,0 +1,41 @@ +const express = require("express"); + +class MQTTRouter { + /** + * + * @param {object} options + * @param {import("../mqtt/MqttController")} options.mqttController + * @param {import("../Configuration")} options.config + * @param {*} options.validator + */ + constructor(options) { + this.router = express.Router({mergeParams: true}); + + this.config = options.config; + this.mqttController = options.mqttController; + this.validator = options.validator; + + this.initRoutes(); + } + + + initRoutes() { + this.router.get("/status", (req, res) => { + res.json(this.mqttController.getStatus()); + }); + + this.router.get("/properties", (req, res) => { + res.json({ + defaults: this.mqttController.getConfigDefaults(), + optionalExposableCapabilities: this.mqttController.getOptionalExposableCapabilities() + }); + }); + + } + + getRouter() { + return this.router; + } +} + +module.exports = MQTTRouter; diff --git a/backend/lib/webserver/NTPClientRouter.js b/backend/lib/webserver/NTPClientRouter.js index 938c26bb..ee64b5b1 100644 --- a/backend/lib/webserver/NTPClientRouter.js +++ b/backend/lib/webserver/NTPClientRouter.js @@ -29,9 +29,15 @@ class NTPClientRouter { }); this.router.put("/config", this.validator, (req, res) => { - this.config.set("ntpClient", req.body); - - res.sendStatus(202); + this.config.set("ntpClient", { + enabled: req.body.enabled, + server: req.body.server, + port: req.body.port, + interval: req.body.interval, + timeout: req.body.timeout + }); + + res.sendStatus(200); }); } diff --git a/backend/lib/webserver/NetworkAdvertisementManagerRouter.js b/backend/lib/webserver/NetworkAdvertisementManagerRouter.js new file mode 100644 index 00000000..a73a74bd --- /dev/null +++ b/backend/lib/webserver/NetworkAdvertisementManagerRouter.js @@ -0,0 +1,49 @@ +const express = require("express"); + + +class NetworkAdvertisementManagerRouter { + /** + * + * @param {object} options + * @param {import("../NetworkAdvertisementManager")} options.networkAdvertisementManager + * @param {import("../Configuration")} options.config + * @param {*} options.validator + */ + constructor(options) { + this.router = express.Router({mergeParams: true}); + this.networkAdvertisementManager = options.networkAdvertisementManager; + this.config = options.config; + this.validator = options.validator; + + this.initRoutes(); + } + + + initRoutes() { + this.router.get("/config", (req, res) => { + res.json(this.config.get("networkAdvertisement")); + }); + + this.router.put("/config", this.validator, (req, res) => { + if (typeof req.body.enabled === "boolean") { + const conf = this.config.get("networkAdvertisement"); + this.config.set("networkAdvertisement", Object.assign({}, conf, {enabled: req.body.enabled})); + + res.sendStatus(200); + } else { + res.sendStatus(400); + } + }); + + + this.router.get("/properties", (req, res) => { + res.json(this.networkAdvertisementManager.getProperties()); + }); + } + + getRouter() { + return this.router; + } +} + +module.exports = NetworkAdvertisementManagerRouter; diff --git a/backend/lib/webserver/RobotRouter.js b/backend/lib/webserver/RobotRouter.js index 19c4ab06..c4eefbc1 100644 --- a/backend/lib/webserver/RobotRouter.js +++ b/backend/lib/webserver/RobotRouter.js @@ -29,6 +29,7 @@ class RobotRouter { res.json({ manufacturer: this.robot.getManufacturer(), modelName: this.robot.getModelName(), + modelDetails: this.robot.getModelDetails(), implementation: this.robot.constructor.name }); }); diff --git a/backend/lib/webserver/SSDPRouter.js b/backend/lib/webserver/SSDPRouter.js index 9c09945d..e1cc62ea 100644 --- a/backend/lib/webserver/SSDPRouter.js +++ b/backend/lib/webserver/SSDPRouter.js @@ -1,6 +1,7 @@ const express = require("express"); const jstoxml = require("jstoxml"); -const Tools = require("../Tools"); +const Logger = require("../Logger"); +const Tools = require("../utils/Tools"); class SSDPRouter { @@ -22,6 +23,8 @@ class SSDPRouter { initRoutes() { this.router.get("/valetudo.xml", (req, res) => { + Logger.debug(`SSDP: Received device description request from ${req.ip}`); + res.set("Content-Type", "text/xml"); res.send(this.getDeviceDescription(req.hostname)); }); diff --git a/backend/lib/webserver/SystemRouter.js b/backend/lib/webserver/SystemRouter.js index f496e6a0..2687f29a 100644 --- a/backend/lib/webserver/SystemRouter.js +++ b/backend/lib/webserver/SystemRouter.js @@ -1,6 +1,6 @@ const express = require("express"); const os = require("os"); -const Tools = require("../Tools"); +const Tools = require("../utils/Tools"); class SystemRouter { /** diff --git a/backend/lib/webserver/TimerRouter.js b/backend/lib/webserver/TimerRouter.js index b2da9a1b..a87a6dc5 100644 --- a/backend/lib/webserver/TimerRouter.js +++ b/backend/lib/webserver/TimerRouter.js @@ -1,9 +1,7 @@ const BasicControlCapability = require("../core/capabilities/BasicControlCapability"); const express = require("express"); -const GoToLocationCapability = require("../core/capabilities/GoToLocationCapability"); const MapSegmentationCapability = require("../core/capabilities/MapSegmentationCapability"); const ValetudoTimer = require("../entities/core/ValetudoTimer"); -const ZoneCleaningCapability = require("../core/capabilities/ZoneCleaningCapability"); class TimerRouter { /** @@ -42,14 +40,6 @@ class TimerRouter { response.supportedActions.push(ValetudoTimer.ACTION_TYPE.SEGMENT_CLEANUP); } - if (this.robot.hasCapability(ZoneCleaningCapability.TYPE)) { - response.supportedActions.push(ValetudoTimer.ACTION_TYPE.ZONE_CLEANUP); - } - - if (this.robot.hasCapability(GoToLocationCapability.TYPE)) { - response.supportedActions.push(ValetudoTimer.ACTION_TYPE.GOTO_LOCATION); - } - res.json(response); }); @@ -71,25 +61,32 @@ class TimerRouter { typeof req.body.minute === "number" && req.body.action && typeof req.body.action.type === "string" ) { - const storedTimers = this.config.get("timers"); - const newTimer = new ValetudoTimer({ - enabled: req.body.enabled === true, - dow: req.body.dow, - hour: req.body.hour, - minute: req.body.minute, - action: req.body.action - }); - - storedTimers[newTimer.id] = newTimer; - - this.config.set("timers", storedTimers); - res.sendStatus(201); + const action = TimerRouter.MAP_ACTION_FROM_BODY(req.body); + + if (!action) { + res.sendStatus(400); + } else { + const storedTimers = this.config.get("timers"); + const newTimer = new ValetudoTimer({ + enabled: req.body.enabled === true, + dow: req.body.dow, + hour: req.body.hour, + minute: req.body.minute, + action: action + }); + + storedTimers[newTimer.id] = newTimer; + + this.config.set("timers", storedTimers); + res.sendStatus(200); + } + } else { res.sendStatus(400); } }); - this.router.post("/:id", this.validator, (req, res) => { + this.router.put("/:id", this.validator, (req, res) => { const storedTimers = this.config.get("timers"); if (storedTimers[req.params.id]) { @@ -100,19 +97,25 @@ class TimerRouter { typeof req.body.minute === "number" && req.body.action && typeof req.body.action.type === "string" ) { - const newTimer = new ValetudoTimer({ - id: req.params.id, - enabled: req.body.enabled === true, - dow: req.body.dow, - hour: req.body.hour, - minute: req.body.minute, - action: req.body.action - }); - - storedTimers[newTimer.id] = newTimer; - - this.config.set("timers", storedTimers); - res.sendStatus(200); + const action = TimerRouter.MAP_ACTION_FROM_BODY(req.body); + + if (!action) { + res.sendStatus(400); + } else { + const newTimer = new ValetudoTimer({ + id: req.params.id, + enabled: req.body.enabled === true, + dow: req.body.dow, + hour: req.body.hour, + minute: req.body.minute, + action: action + }); + + storedTimers[newTimer.id] = newTimer; + + this.config.set("timers", storedTimers); + res.sendStatus(200); + } } else { res.sendStatus(400); } @@ -139,6 +142,35 @@ class TimerRouter { getRouter() { return this.router; } + + /** + * @private + * @param {object} body + */ + static MAP_ACTION_FROM_BODY(body) { + let action; + + switch (body.action.type) { + case ValetudoTimer.ACTION_TYPE.FULL_CLEANUP: + action = { + type: ValetudoTimer.ACTION_TYPE.FULL_CLEANUP, + params: {} + }; + break; + case ValetudoTimer.ACTION_TYPE.SEGMENT_CLEANUP: + action = { + type: ValetudoTimer.ACTION_TYPE.SEGMENT_CLEANUP, + params: { + segment_ids: body.action.params.segment_ids, + iterations: body.action.params.iterations, + custom_order: body.action.params.custom_order, + } + }; + break; + } + + return action; + } } module.exports = TimerRouter; diff --git a/backend/lib/webserver/UpdaterRouter.js b/backend/lib/webserver/UpdaterRouter.js index a72aa632..7b885300 100644 --- a/backend/lib/webserver/UpdaterRouter.js +++ b/backend/lib/webserver/UpdaterRouter.js @@ -25,34 +25,27 @@ class UpdaterRouter { res.json(this.updater.state); }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - try { - switch (req.body.action) { - case "check": - this.updater.triggerCheck(); - - break; - case "download": - this.updater.triggerDownload(); - break; - - case "apply": - this.updater.triggerApply(); - break; - - default: - // noinspection ExceptionCaughtLocallyJS - throw new Error("Invalid action"); - } - - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while executing action \"" + req.body.action + "\" for Updater", e); - res.status(400).json(e.message); + this.router.put("/", this.validator, async (req, res) => { + try { + switch (req.body.action) { + case "check": + this.updater.triggerCheck(); + break; + case "download": + this.updater.triggerDownload(); + break; + case "apply": + this.updater.triggerApply(); + break; + default: + // noinspection ExceptionCaughtLocallyJS + throw new Error("Invalid action"); } - } else { - res.status(400).send("Missing action in request body"); + + res.sendStatus(200); + } catch (e) { + Logger.warn("Error while executing action \"" + req.body.action + "\" for Updater", e); + res.status(400).json(e.message); } }); } diff --git a/backend/lib/webserver/ValetudoEventRouter.js b/backend/lib/webserver/ValetudoEventRouter.js index d1694dab..33cceb97 100644 --- a/backend/lib/webserver/ValetudoEventRouter.js +++ b/backend/lib/webserver/ValetudoEventRouter.js @@ -36,16 +36,16 @@ class ValetudoEventRouter { const event = this.valetudoEventStore.getById(req.params.id); if (event) { - if (req.body && req.body.interaction) { + if (req.body.interaction) { try { await this.valetudoEventStore.interact(event, req.body.interaction); } catch (e) { - return res.status(400).send("Failed to interact with event: " + e?.message); + return res.status(500).send("Failed to interact with event: " + e?.message); } res.json(event); } else { - res.status(400).send("Missing or invalid request body"); + res.sendStatus(400); } } else { res.sendStatus(404); diff --git a/backend/lib/webserver/ValetudoRouter.js b/backend/lib/webserver/ValetudoRouter.js index 827522e6..cd306b7e 100644 --- a/backend/lib/webserver/ValetudoRouter.js +++ b/backend/lib/webserver/ValetudoRouter.js @@ -3,7 +3,7 @@ const nestedProperty = require("nested-property"); const RateLimit = require("express-rate-limit"); const Logger = require("../Logger"); -const Tools = require("../Tools"); +const Tools = require("../utils/Tools"); const {SSEHub, SSEMiddleware} = require("./middlewares/sse"); class ValetudoRouter { @@ -21,10 +21,8 @@ class ValetudoRouter { this.robot = options.robot; this.validator = options.validator; - //@ts-ignore - // noinspection PointlessArithmeticExpressionJS - this.limiter = new RateLimit({ - windowMs: 1*30*1000, + this.limiter = RateLimit.rateLimit({ + windowMs: 30*1000, max: 30 }); @@ -36,7 +34,8 @@ class ValetudoRouter { initRoutes() { this.router.get("/", (req, res) => { res.json({ - embedded: this.config.get("embedded") + embedded: this.config.get("embedded"), + systemId: Tools.GET_HUMAN_READABLE_SYSTEM_ID() }); }); @@ -61,10 +60,10 @@ class ValetudoRouter { }); this.router.put("/log/level", this.validator, (req, res) => { - if (req.body && req.body.level && typeof req.body.level === "string") { + if (typeof req.body.level === "string") { Logger.setLogLevel(req.body.level); - res.sendStatus(202); + res.sendStatus(200); } else { res.sendStatus(400); } @@ -83,23 +82,8 @@ class ValetudoRouter { res.json(mqttConfig); }); - this.router.get("/config/interfaces/mqtt/properties", (req, res) => { - //It might make sense to pull this from the mqttController but that would introduce a dependency between the webserver and the mqttController :/ - res.json({ - defaults: { - identity: { - friendlyName: this.robot.getModelName() + " " + Tools.GET_HUMAN_READABLE_SYSTEM_ID(), - identifier: Tools.GET_HUMAN_READABLE_SYSTEM_ID() - }, - customizations: { - topicPrefix: "valetudo" - } - } - }); - }); - this.router.put("/config/interfaces/mqtt", this.validator, (req, res) => { - let mqttConfig = req.body; + let mqttConfig = ValetudoRouter.MAP_MQTT_CONFIG(req.body); let oldConfig = this.config.get("mqtt"); @@ -111,7 +95,7 @@ class ValetudoRouter { this.config.set("mqtt", mqttConfig); - res.sendStatus(202); + res.sendStatus(200); }); this.router.get("/config/interfaces/http/auth/basic", (req, res) => { @@ -120,7 +104,6 @@ class ValetudoRouter { this.router.put("/config/interfaces/http/auth/basic", this.validator, (req, res) => { if ( - req.body && typeof req.body === "object" && typeof req.body.enabled === "boolean" && typeof req.body.username === "string" && typeof req.body.password === "string" @@ -135,15 +118,15 @@ class ValetudoRouter { if (!options.password && (webserverConfig.basicAuth.enabled === false && options.enabled === true)) { - res.status(400).send("Missing password for basic auth enable. Don't lock yourself out!"); + res.sendStatus(400); } else { webserverConfig.basicAuth = options; this.config.set("webserver", webserverConfig); - res.sendStatus(201); + res.sendStatus(200); } } else { - res.status(400).send("bad request body"); + res.sendStatus(400); } }); @@ -194,6 +177,52 @@ class ValetudoRouter { hub.shutdown(); }); } + + static MAP_MQTT_CONFIG(obj) { + return { + enabled: obj.enabled, + connection: { + host: obj.connection.host, + port: obj.connection.port, + tls: { + enabled: obj.connection.tls.enabled, + ca: obj.connection.tls.ca + }, + authentication: { + credentials: { + enabled: obj.connection.authentication.credentials.enabled, + username: obj.connection.authentication.credentials.username, + password: obj.connection.authentication.credentials.password + }, + clientCertificate: { + enabled: obj.connection.authentication.clientCertificate.enabled, + certificate: obj.connection.authentication.clientCertificate.certificate, + key: obj.connection.authentication.clientCertificate.key + } + } + }, + identity: { + friendlyName: obj.identity.friendlyName, + identifier: obj.identity.identifier + }, + customizations: { + topicPrefix: obj.customizations.topicPrefix, + provideMapData: obj.customizations.provideMapData + }, + interfaces: { + homie: { + enabled: obj.interfaces.homie.enabled, + addICBINVMapProperty: obj.interfaces.homie.addICBINVMapProperty, + cleanAttributesOnShutdown: obj.interfaces.homie.cleanAttributesOnShutdown + }, + homeassistant: { + enabled: obj.interfaces.homeassistant.enabled, + cleanAutoconfOnShutdown: obj.interfaces.homeassistant.cleanAutoconfOnShutdown + } + }, + optionalExposedCapabilities: Array.isArray(obj.optionalExposedCapabilities) ? [...new Set(obj.optionalExposedCapabilities)] : [] + }; + } } const MAGIC_PRIVACY_STRING = ""; diff --git a/backend/lib/webserver/WebServer.js b/backend/lib/webserver/WebServer.js index 64db7dcb..d8a2010d 100644 --- a/backend/lib/webserver/WebServer.js +++ b/backend/lib/webserver/WebServer.js @@ -1,5 +1,4 @@ const basicAuth = require("express-basic-auth"); -const bodyParser = require("body-parser"); const compression = require("compression"); const dynamicMiddleware = require("express-dynamic-middleware"); const express = require("express"); @@ -20,12 +19,13 @@ const ValetudoRouter = require("./ValetudoRouter"); const fs = require("fs"); -const MiioValetudoRobot = require("../robots/MiioValetudoRobot"); +const MQTTRouter = require("./MQTTRouter"); +const NetworkAdvertisementManagerRouter = require("./NetworkAdvertisementManagerRouter"); const NTPClientRouter = require("./NTPClientRouter"); const SSDPRouter = require("./SSDPRouter"); const SystemRouter = require("./SystemRouter"); const TimerRouter = require("./TimerRouter"); -const Tools = require("../Tools"); +const Tools = require("../utils/Tools"); const UpdaterRouter = require("./UpdaterRouter"); const ValetudoEventRouter = require("./ValetudoEventRouter"); @@ -33,6 +33,8 @@ class WebServer { /** * @param {object} options * @param {import("../core/ValetudoRobot")} options.robot + * @param {import("../mqtt/MqttController")} options.mqttController + * @param {import("../NetworkAdvertisementManager")} options.networkAdvertisementManager * @param {import("../NTPClient")} options.ntpClient * @param {import("../updater/Updater")} options.updater * @param {import("../ValetudoEventStore")} options.valetudoEventStore @@ -50,11 +52,11 @@ class WebServer { this.port = this.webserverConfig.port; - this.basicAuthInUse = false; //TODO: redo auth with jwt or something like that + this.basicAuthInUse = false; //TODO: redo auth this.app = express(); this.app.use(compression()); - this.app.use(bodyParser.json()); + this.app.use(express.json()); this.app.disable("x-powered-by"); @@ -92,8 +94,18 @@ class WebServer { const server = http.createServer(this.app); this.loadApiSpec(); - this.validator = function noOpValidationMiddleware(req, res, next) { - next(); + this.validator = function superBasicValidationMiddleware(req, res, next) { + // We can save a lot of code in our routers by always at least making sure that req.body exists + // even if it is not being validated by the schema + if (req.method === "PUT" || req.method === "POST") { + if (Tools.IS_EMPTY_OBJECT_OR_UNDEFINED_OR_NULL(req.body)) { + res.sendStatus(400); + } else { + next(); + } + } else { + next(); + } }; if (this.openApiSpec) { @@ -112,6 +124,10 @@ class WebServer { this.app.use("/api/v2/valetudo/", this.valetudoRouter.getRouter()); + this.app.use("/api/v2/mqtt/", new MQTTRouter({config: this.config, mqttController: options.mqttController, validator: this.validator}).getRouter()); + + this.app.use("/api/v2/networkadvertisement/", new NetworkAdvertisementManagerRouter({config: this.config, networkAdvertisementManager: options.networkAdvertisementManager, validator: this.validator}).getRouter()); + this.app.use("/api/v2/ntpclient/", new NTPClientRouter({config: this.config, ntpClient: options.ntpClient, validator: this.validator}).getRouter()); this.app.use("/api/v2/timers/", new TimerRouter({config: this.config, robot: this.robot, validator: this.validator}).getRouter()); @@ -126,8 +142,6 @@ class WebServer { this.app.use(express.static(path.join(__dirname, "../../..", "frontend/build"))); - this.app.use("/old_frontend", express.static(path.join(__dirname, "../../..", "old_frontend/lib"))); - this.app.get("/api/v2", (req, res) => { let endpoints = listEndpoints(this.app); let endpointsMap; @@ -147,24 +161,13 @@ class WebServer { res.json(endpointsMap); }); - /* - TODO: MOVE THIS HACK ELSEWHERE! - This is a hack for miio vacuums with a recent miio_client + this.robot.initModelSpecificWebserverRoutes(this.app); - To properly spoof the http_dns request, we need to have this route on port 80 instead of the - miio-implementation specific second webserver on 8079 :/ - */ - if (this.robot instanceof MiioValetudoRobot) { - this.app.get("/gslb", (req, res) => { - //@ts-ignore - this.robot.handleHttpDnsRequest(req, res); - }); - } this.app.use((err, req, res, next) => { if (err instanceof swaggerValidation.InputValidationError) { - Logger.warn("Received request with invalid payload", err.errors); + Logger.warn(`Received "${req.method} "to "${req.originalUrl}" with invalid payload`, err.errors); res.status(400).json({message: "Request payload is invalid.", error: err.errors}); } else { Logger.error("Unhandled WebServer Error", err); @@ -244,6 +247,24 @@ class WebServer { Logger.warn("Failed to load OpenApi spec. Swagger endpoint and payload validation will be unavailable.", e.message); } + + const capabilityRoutePathRegex = /\/api\/v2\/robot\/capabilities\/(?[A-Za-z]+)/; + const supportedCapabilities = Object.keys(this.robot.capabilities); + + Object.keys(spec.paths).forEach(pathName => { + const regexResult = capabilityRoutePathRegex.exec(pathName); + const capabilityName = regexResult?.groups?.capabilityName; + + if (capabilityName !== undefined && !supportedCapabilities.includes(capabilityName)) { + delete(spec.paths[pathName]); + } + }); + + spec.tags = spec.tags.filter(tag => { + return !(tag.name.endsWith("Capability") && !supportedCapabilities.includes(tag.name)); + }); + + this.openApiSpec = spec; } } diff --git a/backend/lib/webserver/capabilityRouters/AutoEmptyDockManualTriggerCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/AutoEmptyDockManualTriggerCapabilityRouter.js index 4b907618..7c0695ac 100644 --- a/backend/lib/webserver/capabilityRouters/AutoEmptyDockManualTriggerCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/AutoEmptyDockManualTriggerCapabilityRouter.js @@ -1,21 +1,17 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class AutoEmptyDockManualTriggerCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action === "trigger") { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "trigger") { try { await this.capability.triggerAutoEmpty(); res.sendStatus(200); } catch (e) { - Logger.warn("Error while triggering auto empty", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing or invalid request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/BasicControlCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/BasicControlCapabilityRouter.js index 19259e55..a18bac0a 100644 --- a/backend/lib/webserver/capabilityRouters/BasicControlCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/BasicControlCapabilityRouter.js @@ -1,9 +1,6 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class BasicControlCapabilityRouter extends CapabilityRouter { - initRoutes() { const methodMap = { "start": () => { @@ -20,23 +17,18 @@ class BasicControlCapabilityRouter extends CapabilityRouter { } }; - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - const method = methodMap[req.body.action]; + this.router.put("/", this.validator, async (req, res) => { + const method = methodMap[req.body.action]; - if (method) { - try { - await method(); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while calling BasicControlCapability Action " + req.body.action, e); - res.status(500).json(e); - } - } else { - res.status(400).send("Invalid action in request body"); + if (method) { + try { + await method(); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing action in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/CapabilityRouter.js b/backend/lib/webserver/capabilityRouters/CapabilityRouter.js index 9fb7acc0..963459b5 100644 --- a/backend/lib/webserver/capabilityRouters/CapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/CapabilityRouter.js @@ -1,6 +1,8 @@ const express = require("express"); +const Logger = require("../../Logger"); const NotImplementedError = require("../../core/NotImplementedError"); +const RobotFirmwareError = require("../../core/RobotFirmwareError"); class CapabilityRouter { /** @@ -30,6 +32,29 @@ class CapabilityRouter { throw new NotImplementedError(); } + /** + * @protected + * @param {any} req + * @param {any} res + * @param {Error} err + */ + sendErrorResponse(req, res, err) { + if (err instanceof RobotFirmwareError) { + Logger.warn(`${this.constructor.name}: Received error from robot while handling route "${req.path}"`, { + body: req.body, + message: err.message + }); + } else { + Logger.warn(`${this.constructor.name}: Error while handling route "${req.path}"`, { + body: req.body, + message: err.message + }); + } + + + res.status(500).json(err.message); + } + getRouter() { return this.router; } diff --git a/backend/lib/webserver/capabilityRouters/CombinedVirtualRestrictionsCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/CombinedVirtualRestrictionsCapabilityRouter.js index 240e00f2..b957ddf9 100644 --- a/backend/lib/webserver/capabilityRouters/CombinedVirtualRestrictionsCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/CombinedVirtualRestrictionsCapabilityRouter.js @@ -1,46 +1,68 @@ const CapabilityRouter = require("./CapabilityRouter"); -const Logger = require("../../Logger"); - const ValetudoRestrictedZone = require("../../entities/core/ValetudoRestrictedZone"); const ValetudoVirtualRestrictions = require("../../entities/core/ValetudoVirtualRestrictions"); const ValetudoVirtualWall = require("../../entities/core/ValetudoVirtualWall"); class CombinedVirtualRestrictionsCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json(await this.capability.getVirtualRestrictions()); + try { + res.json(await this.capability.getVirtualRestrictions()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/", async (req, res) => { - if (req.body) { - if (Array.isArray(req.body.virtualWalls) && Array.isArray(req.body.restrictedZones)) { - const virtualRestrictions = new ValetudoVirtualRestrictions({ - virtualWalls: req.body.virtualWalls.map(requestWall => { - return new ValetudoVirtualWall({ - points: requestWall.points - }); - }), - restrictedZones: req.body.restrictedZones.map(requestZone => { - return new ValetudoRestrictedZone({ - points: requestZone.points, - type: requestZone.type - }); - }) - }); + this.router.put("/", this.validator, async (req, res) => { + if (Array.isArray(req.body.virtualWalls) && Array.isArray(req.body.restrictedZones)) { + const virtualRestrictions = new ValetudoVirtualRestrictions({ + virtualWalls: req.body.virtualWalls.map(requestWall => { + return new ValetudoVirtualWall({ + points: { + pA: { + x: requestWall.points.pA.x, + y: requestWall.points.pA.y + }, + pB: { + x: requestWall.points.pB.x, + y: requestWall.points.pB.y + } + } + }); + }), + restrictedZones: req.body.restrictedZones.map(requestZone => { + return new ValetudoRestrictedZone({ + points: { + pA: { + x: requestZone.points.pA.x, + y: requestZone.points.pA.y + }, + pB: { + x: requestZone.points.pB.x, + y: requestZone.points.pB.y + }, + pC: { + x: requestZone.points.pC.x, + y: requestZone.points.pC.y + }, + pD: { + x: requestZone.points.pD.x, + y: requestZone.points.pD.y + } + }, + type: requestZone.type + }); + }) + }); - try { - await this.capability.setVirtualRestrictions(virtualRestrictions); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while saving virtual restrictions", e); - res.status(500).json(e.message); - } - } else { - res.status(400).send("Missing virtualWalls or restrictedZones property in request body"); + try { + await this.capability.setVirtualRestrictions(virtualRestrictions); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/ConsumableMonitoringCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/ConsumableMonitoringCapabilityRouter.js index 3ee3cb76..b6ab8119 100644 --- a/backend/lib/webserver/capabilityRouters/ConsumableMonitoringCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/ConsumableMonitoringCapabilityRouter.js @@ -1,17 +1,16 @@ -const escapeHtml = require("escape-html"); - -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class ConsumableMonitoringCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json(await this.capability.getConsumables()); + try { + res.json(await this.capability.getConsumables()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/:type/:sub_type?", async (req, res) => { + this.router.put("/:type/:sub_type?", this.validator, async (req, res) => { //This is only required because typescript doesn't understand optional parameters //error TS2551: Property 'sub_type' does not exist on type 'RouteParameters<"/:type/:sub_type?">'. Did you mean 'sub_type?'? const parameters = { @@ -20,20 +19,15 @@ class ConsumableMonitoringCapabilityRouter extends CapabilityRouter { sub_type: req.params.sub_type ?? undefined }; - if (req.body && req.body.action) { - if (req.body.action === "reset") { - try { - await this.capability.resetConsumable(parameters.type, parameters.sub_type); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while resetting consumable " + parameters.type + " " + parameters.sub_type, e); - res.status(500).json(e.message); - } - } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); + if (req.body.action === "reset") { + try { + await this.capability.resetConsumable(parameters.type, parameters.sub_type); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing action in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/DoNotDisturbCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/DoNotDisturbCapabilityRouter.js index d5c41551..f5bfe9f6 100644 --- a/backend/lib/webserver/capabilityRouters/DoNotDisturbCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/DoNotDisturbCapabilityRouter.js @@ -1,27 +1,37 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); const ValetudoDNDConfiguration = require("../../entities/core/ValetudoDNDConfiguration"); class DoNotDisturbCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json(await this.capability.getDndConfiguration()); + try { + res.json(await this.capability.getDndConfiguration()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.start && req.body.end) { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.start && req.body.end) { try { - await this.capability.setDndConfiguration(new ValetudoDNDConfiguration(req.body)); + await this.capability.setDndConfiguration(new ValetudoDNDConfiguration({ + enabled: req.body.enabled, + start: { + hour: req.body.start.hour, + minute: req.body.start.minute, + }, + end: { + hour: req.body.end.hour, + minute: req.body.end.minute, + } + })); res.sendStatus(200); } catch (e) { - Logger.warn("Error while configuring do not disturb setting", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing parameters in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/GoToLocationCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/GoToLocationCapabilityRouter.js index 0dfb121a..7da9d519 100644 --- a/backend/lib/webserver/capabilityRouters/GoToLocationCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/GoToLocationCapabilityRouter.js @@ -1,179 +1,25 @@ -const escapeHtml = require("escape-html"); - const CapabilityRouter = require("./CapabilityRouter"); -const Logger = require("../../Logger"); - const ValetudoGoToLocation = require("../../entities/core/ValetudoGoToLocation"); class GoToLocationCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.get("/presets", (req, res) => { - res.json(this.capability.robot.config.get("goToLocationPresets")); - }); - - this.router.get("/presets/:id", (req, res) => { - const locationPreset = this.capability.robot.config.get("goToLocationPresets")[req.params.id]; - - if (locationPreset) { - res.json(locationPreset); - } else { - res.sendStatus(404); - } - }); - - this.router.put("/presets/:id", async (req, res) => { - const locationPreset = this.capability.robot.config.get("goToLocationPresets")[req.params.id]; - - if (locationPreset && req.body && req.body.action === "goto") { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "goto" && req.body.coordinates !== undefined) { try { - await this.capability.goTo(locationPreset); + await this.capability.goTo(new ValetudoGoToLocation({ + coordinates: { + x: req.body.coordinates.x, + y: req.body.coordinates.y + } + })); res.sendStatus(200); } catch (e) { - Logger.warn("Error while going to goToLocationPreset for preset " + req.params.id, e); - res.status(500).json(e.message); - } - } else { - res.sendStatus(404); - } - }); - - this.router.delete("/presets/:id", (req, res) => { - const goToLocationPresets = this.capability.robot.config.get("goToLocationPresets"); - - if (goToLocationPresets[req.params.id]) { - delete(goToLocationPresets[req.params.id]); - - this.capability.robot.config.set("goToLocationPresets", goToLocationPresets); - - res.sendStatus(200); - } else { - res.sendStatus(404); - } - }); - - this.router.post("/presets/:id", (req, res) => { - const goToLocationPresets = this.capability.robot.config.get("goToLocationPresets"); - - if (goToLocationPresets[req.params.id]) { - if (req.body && req.body.name && req.body.coordinates && req.body.coordinates.x !== undefined && req.body.coordinates.y !== undefined) { - try { - const newPreset = new ValetudoGoToLocation({ - name: req.body.name, - id: req.params.id, - coordinates: req.body.coordinates - }); - - goToLocationPresets[newPreset.id] = newPreset; - - this.capability.robot.config.set("goToLocationPresets", goToLocationPresets); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while saving goToLocationPreset", req.body); - res.status(500).json(e.message); - } - - } - } else { - res.sendStatus(404); - } - }); - - this.router.post("/presets", (req, res) => { - if (req.body && req.body.name && req.body.coordinates && req.body.coordinates.x !== undefined && req.body.coordinates.y !== undefined) { - try { - const goToLocationPresets = this.capability.robot.config.get("goToLocationPresets"); - const newPreset = new ValetudoGoToLocation({ - name: req.body.name, - id: req.body.id, - coordinates: req.body.coordinates - }); - - goToLocationPresets[newPreset.id] = newPreset; - - this.capability.robot.config.set("goToLocationPresets", goToLocationPresets); - res.sendStatus(201); - } catch (e) { - Logger.warn("Error while saving new goToLocationPreset", req.body); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } - } else { res.sendStatus(400); } }); - - //TODO: Remove this after building a new webinterface - - this.router.get("/presets_legacy", (req, res) => { - const presetsFromConfig = Object.values(this.capability.robot.config.get("goToLocationPresets")); - - res.json(presetsFromConfig.map(preset => { - return { - name: preset.name, - id: preset.id, - coordinates: [preset.coordinates.x, preset.coordinates.y] - }; - })); - }); - - - this.router.post("/presets_legacy", (req, res) => { - if (Array.isArray(req.body)) { - const valid = req.body.every(p => { - return p && p.name && Array.isArray(p.coordinates); - }); - - if (valid) { - const presetsArr = req.body.map(preset => { - return new ValetudoGoToLocation({ - name: preset.name, - id: preset.id, - coordinates: { - x: preset.coordinates[0], - y: preset.coordinates[1] - } - }); - }); - - const presets = {}; - - presetsArr.forEach(z => { - presets[z.id] = z; - }); - - - this.capability.robot.config.set("goToLocationPresets", presets); - res.sendStatus(201); - } else { - res.sendStatus(400); - } - } - }); - - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - if (req.body.action === "goto" && req.body.coordinates && req.body.coordinates.x !== undefined && req.body.coordinates.y !== undefined) { - try { - await this.capability.goTo(new ValetudoGoToLocation({ - name: "dynamic", - coordinates: req.body.coordinates - })); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while starting goTo coordinates", { - body: req.body, - e: e - }); - res.status(500).json(e.message); - } - } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); - } - } else { - res.status(400).send("Missing action in request body"); - } - }); } } diff --git a/backend/lib/webserver/capabilityRouters/LocateCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/LocateCapabilityRouter.js index e91bbc12..4d99db79 100644 --- a/backend/lib/webserver/capabilityRouters/LocateCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/LocateCapabilityRouter.js @@ -1,21 +1,17 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class LocateCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action === "locate") { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "locate") { try { await this.capability.locate(); res.sendStatus(200); } catch (e) { - Logger.warn("Error while locating robot", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing or invalid request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/ManualControlCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/ManualControlCapabilityRouter.js index 880d162a..33f8d3fa 100644 --- a/backend/lib/webserver/capabilityRouters/ManualControlCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/ManualControlCapabilityRouter.js @@ -1,57 +1,49 @@ -const escapeHtml = require("escape-html"); - -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class ManualControlCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json({ - enabled: await this.capability.manualControlActive() - }); + try { + res.json({ + enabled: await this.capability.manualControlActive() + }); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - switch (req.body.action) { - case "enable": + this.router.put("/", this.validator, async (req, res) => { + switch (req.body.action) { + case "enable": + try { + await this.capability.enableManualControl(); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); + } + break; + case "disable": + try { + await this.capability.disableManualControl(); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); + } + break; + case "move": + if (req.body.movementCommand) { try { - await this.capability.enableManualControl(); + await this.capability.manualControl(req.body.movementCommand); res.sendStatus(200); } catch (e) { - Logger.warn("Failed to enable manual control", e); - res.status(500).json(e.message); - } - break; - case "disable": - try { - await this.capability.disableManualControl(); - res.sendStatus(200); - } catch (e) { - Logger.warn("Failed to disable manual control", e); - res.status(500).json(e.message); - } - break; - case "move": - if (req.body.movementCommand) { - try { - await this.capability.manualControl(req.body.movementCommand); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while performing manual control movement command " + req.body.movementCommand, e); - res.status(500).json(e.message); - } - } else { - res.status(400).send("Missing movementCommand in request body"); + this.sendErrorResponse(req, res, e); } - break; - default: - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); - } - } else { - res.status(400).send("Missing action in request body"); + } else { + res.sendStatus(400); + } + break; + default: + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MapResetCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MapResetCapabilityRouter.js index 2e23e3c1..9a340774 100644 --- a/backend/lib/webserver/capabilityRouters/MapResetCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/MapResetCapabilityRouter.js @@ -1,26 +1,17 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); -const escapeHtml = require("escape-html"); class MapResetCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - if (req.body.action === "reset") { - try { - await this.capability.reset(); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while executing MapResetCapability", e); - res.status(500).json(e.message); - } - } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "reset") { + try { + await this.capability.reset(); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing action in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MapSegmentEditCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MapSegmentEditCapabilityRouter.js index 7cf9ef56..b8e34a21 100644 --- a/backend/lib/webserver/capabilityRouters/MapSegmentEditCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/MapSegmentEditCapabilityRouter.js @@ -1,63 +1,51 @@ -const escapeHtml = require("escape-html"); - -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); - const ValetudoMapSegment = require("../../entities/core/ValetudoMapSegment"); class MapSegmentEditCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - switch (req.body.action) { - case "join_segments": - if (req.body.segment_a_id && req.body.segment_b_id) { - try { - await this.capability.joinSegments( - new ValetudoMapSegment({id: req.body.segment_a_id}), - new ValetudoMapSegment({id: req.body.segment_b_id}), - ); - - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while joining segments", { - body: req.body, - e: e - }); - res.status(500).json(e.message); - } - } else { - res.status(400).send("Invalid request"); + this.router.put("/", this.validator, async (req, res) => { + switch (req.body.action) { + case "join_segments": + if (req.body.segment_a_id && req.body.segment_b_id) { + try { + await this.capability.joinSegments( + new ValetudoMapSegment({id: req.body.segment_a_id}), + new ValetudoMapSegment({id: req.body.segment_b_id}), + ); + + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } - break; - case "split_segment": - if (req.body.pA && req.body.pB && req.body.segment_id) { - try { - await this.capability.splitSegment( - new ValetudoMapSegment({id: req.body.segment_id}), - req.body.pA, - req.body.pB - ); - - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while splitting segment", { - body: req.body, - e: e - }); - res.status(500).json(e.message); - } - } else { - res.status(400).send("Invalid request"); + } else { + res.sendStatus(400); + } + break; + case "split_segment": + if (req.body.pA && req.body.pB && req.body.segment_id) { + try { + await this.capability.splitSegment( + new ValetudoMapSegment({id: req.body.segment_id}), + { + x: req.body.pA.x, + y: req.body.pA.y, + }, + { + x: req.body.pB.x, + y: req.body.pB.y, + } + ); + + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } - break; - default: - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); - } - } else { - res.status(400).send("Missing action in request body"); + } else { + res.sendStatus(400); + } + break; + default: + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MapSegmentRenameCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MapSegmentRenameCapabilityRouter.js index f9488eff..48d69eb5 100644 --- a/backend/lib/webserver/capabilityRouters/MapSegmentRenameCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/MapSegmentRenameCapabilityRouter.js @@ -1,40 +1,26 @@ -const escapeHtml = require("escape-html"); - -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); - const ValetudoMapSegment = require("../../entities/core/ValetudoMapSegment"); class MapSegmentRenameCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - if (req.body.action === "rename_segment") { - if ( req.body.segment_id && req.body.name !== undefined) { - try { - await this.capability.renameSegment( - new ValetudoMapSegment({id: req.body.segment_id}), - req.body.name - ); + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "rename_segment") { + if ( req.body.segment_id && req.body.name !== undefined) { + try { + await this.capability.renameSegment( + new ValetudoMapSegment({id: req.body.segment_id}), + req.body.name + ); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while renaming segment", { - body: req.body, - e: e - }); - res.status(500).json(e.message); - } - } else { - res.status(400).send("Invalid request"); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); + res.sendStatus(400); } } else { - res.status(400).send("Missing action in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MapSegmentationCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MapSegmentationCapabilityRouter.js index 32558e5b..f7331fed 100644 --- a/backend/lib/webserver/capabilityRouters/MapSegmentationCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/MapSegmentationCapabilityRouter.js @@ -1,55 +1,45 @@ -const escapeHtml = require("escape-html"); - -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); - const ValetudoMapSegment = require("../../entities/core/ValetudoMapSegment"); class MapSegmentationCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json(await this.capability.getSegments()); + try { + res.json(await this.capability.getSegments()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - if (req.body.action === "start_segment_action") { - if (Array.isArray(req.body.segment_ids)) { - try { - const options = {}; + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "start_segment_action") { + if (Array.isArray(req.body.segment_ids)) { + try { + const options = {}; - if (typeof req.body.iterations === "number") { - options.iterations = req.body.iterations; - } - - if (req.body.customOrder === true) { - options.customOrder = true; - } + if (typeof req.body.iterations === "number") { + options.iterations = req.body.iterations; + } - await this.capability.executeSegmentAction(req.body.segment_ids.map(sid => { - return new ValetudoMapSegment({ - id: sid - }); - }), options); + if (req.body.customOrder === true) { + options.customOrder = true; + } - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while starting segment cleaning", { - body: req.body, - e: e + await this.capability.executeSegmentAction(req.body.segment_ids.map(sid => { + return new ValetudoMapSegment({ + id: sid }); - res.status(500).json(e.message); - } - } else { - res.status(400).send("Missing segment_ids"); + }), options); + + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); + res.sendStatus(400); } } else { - res.status(400).send("Missing action in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MapSnapshotCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MapSnapshotCapabilityRouter.js index ef6e09ec..11dc1275 100644 --- a/backend/lib/webserver/capabilityRouters/MapSnapshotCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/MapSnapshotCapabilityRouter.js @@ -1,26 +1,22 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); const ValetudoMapSnapshot = require("../../entities/core/ValetudoMapSnapshot"); class MapSnapshotCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { res.json(await this.capability.getSnapshots()); }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.action === "restore" && req.body.id) { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "restore" && req.body.id !== undefined) { try { await this.capability.restoreSnapshot(new ValetudoMapSnapshot({id: req.body.id})); res.sendStatus(200); } catch (e) { - Logger.warn("Error while restoring map snapshot", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing or invalid request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MappingPassCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MappingPassCapabilityRouter.js index 7a976d38..affa21bd 100644 --- a/backend/lib/webserver/capabilityRouters/MappingPassCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/MappingPassCapabilityRouter.js @@ -1,21 +1,17 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class MappingPassCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action === "start_mapping") { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "start_mapping") { try { await this.capability.startMapping(); res.sendStatus(200); } catch (e) { - Logger.warn("Error while starting mapping", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing or invalid request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/MopDockCleanManualTriggerCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MopDockCleanManualTriggerCapabilityRouter.js new file mode 100644 index 00000000..1617d1de --- /dev/null +++ b/backend/lib/webserver/capabilityRouters/MopDockCleanManualTriggerCapabilityRouter.js @@ -0,0 +1,31 @@ +const CapabilityRouter = require("./CapabilityRouter"); + +class MopDockCleanManualTriggerCapabilityRouter extends CapabilityRouter { + initRoutes() { + const methodMap = { + "start": () => { + return this.capability.startCleaning(); + }, + "stop": () => { + return this.capability.stopCleaning(); + }, + }; + + this.router.put("/", this.validator, async (req, res) => { + const method = methodMap[req.body.action]; + + if (method) { + try { + await method(); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); + } + } else { + res.sendStatus(400); + } + }); + } +} + +module.exports = MopDockCleanManualTriggerCapabilityRouter; diff --git a/backend/lib/webserver/capabilityRouters/MopDockDryManualTriggerCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/MopDockDryManualTriggerCapabilityRouter.js new file mode 100644 index 00000000..39b17688 --- /dev/null +++ b/backend/lib/webserver/capabilityRouters/MopDockDryManualTriggerCapabilityRouter.js @@ -0,0 +1,31 @@ +const CapabilityRouter = require("./CapabilityRouter"); + +class MopDockDryManualTriggerCapabilityRouter extends CapabilityRouter { + initRoutes() { + const methodMap = { + "start": () => { + return this.capability.startDrying(); + }, + "stop": () => { + return this.capability.stopDrying(); + }, + }; + + this.router.put("/", this.validator, async (req, res) => { + const method = methodMap[req.body.action]; + + if (method) { + try { + await method(); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); + } + } else { + res.sendStatus(400); + } + }); + } +} + +module.exports = MopDockDryManualTriggerCapabilityRouter; diff --git a/backend/lib/webserver/capabilityRouters/PendingMapChangeHandlingCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/PendingMapChangeHandlingCapabilityRouter.js index b20a5337..242a5b08 100644 --- a/backend/lib/webserver/capabilityRouters/PendingMapChangeHandlingCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/PendingMapChangeHandlingCapabilityRouter.js @@ -1,5 +1,4 @@ const CapabilityRouter = require("./CapabilityRouter"); -const Logger = require("../../Logger"); class PendingMapChangeHandlingCapabilityRouter extends CapabilityRouter { initRoutes() { @@ -9,11 +8,11 @@ class PendingMapChangeHandlingCapabilityRouter extends CapabilityRouter { pending: await this.capability.hasPendingChange() }); } catch (e) { - res.status(500).send(e.message); + this.sendErrorResponse(req, res, e); } }); - this.router.put("/", async (req, res) => { + this.router.put("/", this.validator, async (req, res) => { if (req.body) { try { switch (req.body.action) { @@ -30,11 +29,10 @@ class PendingMapChangeHandlingCapabilityRouter extends CapabilityRouter { res.sendStatus(200); } catch (e) { - Logger.warn("Error while committing map change", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing parameters in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/PresetSelectionCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/PresetSelectionCapabilityRouter.js index 7ae9abb0..497edb7d 100644 --- a/backend/lib/webserver/capabilityRouters/PresetSelectionCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/PresetSelectionCapabilityRouter.js @@ -1,25 +1,25 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class PresetSelectionCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/presets", (req, res) => { - res.json(this.capability.getPresets()); + try { + res.json(this.capability.getPresets()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); this.router.put("/preset", this.validator, async (req, res) => { - if (req.body && req.body.name) { + if (req.body.name) { try { await this.capability.selectPreset(req.body.name); res.sendStatus(200); } catch (e) { - Logger.warn("Error while setting preset " + req.body.name, e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing name in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/QuirksCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/QuirksCapabilityRouter.js index 8f81bd5e..6075854d 100644 --- a/backend/lib/webserver/capabilityRouters/QuirksCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/QuirksCapabilityRouter.js @@ -1,30 +1,26 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class QuirksCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { try { res.json(await this.capability.getQuirks()); } catch (e) { - res.status(500).send(e.message); + this.sendErrorResponse(req, res, e); } }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.id && req.body.value) { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.id && req.body.value) { try { await this.capability.setQuirkValue(req.body.id, req.body.value); res.sendStatus(200); } catch (e) { - Logger.warn("Error while setting quirk", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing parameters in request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/SensorCalibrationCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/SensorCalibrationCapabilityRouter.js deleted file mode 100644 index 4892d3fa..00000000 --- a/backend/lib/webserver/capabilityRouters/SensorCalibrationCapabilityRouter.js +++ /dev/null @@ -1,42 +0,0 @@ -const escapeHtml = require("escape-html"); - -const Logger = require("../../Logger"); - -const CapabilityRouter = require("./CapabilityRouter"); - -class SensorCalibrationCapabilityRouter extends CapabilityRouter { - - initRoutes() { - this.router.get("/", async (req, res) => { - res.json(await this.capability.getSensors()); - }); - - this.router.put("/:type/:sub_type?", async (req, res) => { - //This is only required because typescript doesn't understand optional parameters - //error TS2551: Property 'sub_type' does not exist on type 'RouteParameters<"/:type/:sub_type?">'. Did you mean 'sub_type?'? - const parameters = { - type: req.params.type, - //@ts-ignore - sub_type: req.params.sub_type ?? undefined - }; - - if (req.body && req.body.action) { - if (req.body.action === "calibrate") { - try { - await this.capability.calibrateSensor(parameters.type, parameters.sub_type); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while calibrating sensor " + parameters.type + " " + parameters.sub_type, e); - res.status(500).json(e.message); - } - } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); - } - } else { - res.status(400).send("Missing action in request body"); - } - }); - } -} - -module.exports = SensorCalibrationCapabilityRouter; diff --git a/backend/lib/webserver/capabilityRouters/SimpleToggleCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/SimpleToggleCapabilityRouter.js index aaaccb5c..2f796ee9 100644 --- a/backend/lib/webserver/capabilityRouters/SimpleToggleCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/SimpleToggleCapabilityRouter.js @@ -1,9 +1,6 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class SimpleToggleCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { try { @@ -11,32 +8,27 @@ class SimpleToggleCapabilityRouter extends CapabilityRouter { enabled: await this.capability.isEnabled() }); } catch (e) { - res.status(500).send(e.message); + this.sendErrorResponse(req, res, e); } }); - this.router.put("/", async (req, res) => { - if (req.body) { - try { - switch (req.body.action) { - case "enable": - await this.capability.enable(); - break; - case "disable": - await this.capability.disable(); - break; - default: - // noinspection ExceptionCaughtLocallyJS - throw new Error("Invalid action"); - } - - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while toggling simple toggle", e); - res.status(500).json(e.message); + this.router.put("/", this.validator, async (req, res) => { + try { + switch (req.body.action) { + case "enable": + await this.capability.enable(); + break; + case "disable": + await this.capability.disable(); + break; + default: + // noinspection ExceptionCaughtLocallyJS + throw new Error("Invalid action"); } - } else { - res.status(400).send("Missing parameters in request body"); + + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } }); } diff --git a/backend/lib/webserver/capabilityRouters/SpeakerTestCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/SpeakerTestCapabilityRouter.js index a6fd48cc..dddd093c 100644 --- a/backend/lib/webserver/capabilityRouters/SpeakerTestCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/SpeakerTestCapabilityRouter.js @@ -1,21 +1,17 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); class SpeakerTestCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.put("/", async (req, res) => { - if (req.body && req.body.action === "play_test_sound") { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "play_test_sound") { try { await this.capability.playTestSound(); res.sendStatus(200); } catch (e) { - Logger.warn("Error while playing speaker test sound", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing or invalid request body"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/SpeakerVolumeControlCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/SpeakerVolumeControlCapabilityRouter.js index dd63dc76..16ef5a78 100644 --- a/backend/lib/webserver/capabilityRouters/SpeakerVolumeControlCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/SpeakerVolumeControlCapabilityRouter.js @@ -1,9 +1,6 @@ const CapabilityRouter = require("./CapabilityRouter"); -const escapeHtml = require("escape-html"); -const Logger = require("../../Logger"); class SpeakerVolumeControlCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { try { @@ -11,35 +8,26 @@ class SpeakerVolumeControlCapabilityRouter extends CapabilityRouter { volume: await this.capability.getVolume() }); } catch (e) { - Logger.warn("Error while fetching speaker volume", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - if (req.body.action === "set_volume") { - if (req.body.value === undefined) { - res.status(400).send("Missing value for set_volume"); - return; - } else if (typeof req.body.value !== "number") { - res.status(400).send("Value for set_volume must be a number"); - return; - } + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "set_volume") { + if (typeof req.body.value !== "number") { + res.sendStatus(400); + return; + } - try { - await this.capability.setVolume(req.body.value); + try { + await this.capability.setVolume(req.body.value); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while setting speaker volume", e); - res.status(500).json(e.message); - } - } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Missing request body or missing action"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/StatisticsCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/StatisticsCapabilityRouter.js index 9ac86d0a..f45cb083 100644 --- a/backend/lib/webserver/capabilityRouters/StatisticsCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/StatisticsCapabilityRouter.js @@ -1,5 +1,4 @@ const CapabilityRouter = require("./CapabilityRouter"); -const Logger = require("../../Logger"); class StatisticsCapabilityRouter extends CapabilityRouter { initRoutes() { @@ -7,8 +6,7 @@ class StatisticsCapabilityRouter extends CapabilityRouter { try { res.json(await this.capability.getStatistics()); } catch (e) { - Logger.warn("Error while fetching statistics", e); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } }); } diff --git a/backend/lib/webserver/capabilityRouters/VoicePackManagementCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/VoicePackManagementCapabilityRouter.js index 145c20d5..3d637b56 100644 --- a/backend/lib/webserver/capabilityRouters/VoicePackManagementCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/VoicePackManagementCapabilityRouter.js @@ -1,17 +1,20 @@ const CapabilityRouter = require("./CapabilityRouter"); class VoicePackManagementCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json({ - "currentLanguage": await this.capability.getCurrentVoiceLanguage(), - "operationStatus": await this.capability.getVoicePackOperationStatus() - }); + try { + res.json({ + "currentLanguage": await this.capability.getCurrentVoiceLanguage(), + "operationStatus": await this.capability.getVoicePackOperationStatus() + }); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/", async (req, res) => { - if (req.body && req.body.action === "download" && req.body.url) { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "download" && req.body.url) { try { await this.capability.downloadVoicePack({ url: req.body.url, @@ -20,10 +23,10 @@ class VoicePackManagementCapabilityRouter extends CapabilityRouter { }); res.sendStatus(200); } catch (e) { - res.status(500).send(e.message); + this.sendErrorResponse(req, res, e); } } else { - res.status(400).send("Invalid request"); + res.sendStatus(400); } }); } diff --git a/backend/lib/webserver/capabilityRouters/WifiConfigurationCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/WifiConfigurationCapabilityRouter.js index dd903047..7a6cc39e 100644 --- a/backend/lib/webserver/capabilityRouters/WifiConfigurationCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/WifiConfigurationCapabilityRouter.js @@ -1,29 +1,217 @@ -const Logger = require("../../Logger"); - const CapabilityRouter = require("./CapabilityRouter"); +const crypto = require("crypto"); +const Logger = require("../../Logger"); const ValetudoWifiConfiguration = require("../../entities/core/ValetudoWifiConfiguration"); class WifiConfigurationCapabilityRouter extends CapabilityRouter { + constructor(options) { + super(options); + this.keyPair = { + type: "rsa", + privateKey: undefined, + publicKey: undefined + }; + } initRoutes() { this.router.get("/", async (req, res) => { - res.json(await this.capability.getWifiStatus()); + try { + res.json(await this.capability.getWifiStatus()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); - this.router.put("/", this.validator, async (req, res) => { - if (req.body) { - try { - await this.capability.setWifiConfiguration(new ValetudoWifiConfiguration(req.body)); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while setting wifi configuration", e); - res.status(500).json(e.message); + /* + Because I have known the internet for a while, I expect that this feature may raise eyebrows for some, + which usually leads to less-than-productive online discussions. + + To combat that, I have prepared this extensive comment to explain what we're doing and why + You can delete that "omg omg they roll their own crypto they're soooo dumb haha" tweet now + + + The situation is as follows: + 1. Provisioning of the robot is usually done over an unencrypted Wi-Fi Access Point provided by the robot. + 2. Sending your Wi-Fi password over HTTP REST over that unencrypted Wi-Fi AP allows a passively sniffing + attacker to capture that provisioning request and thus gain access to your home network + 3. Provisioning is usually only done once, takes very little time and usually happens at home/in a residential + area instead of a public space like a starbucks or an airport, where it would be likely to encounter + a malicious actor + + + Due to 3, the attack surface is actually pretty limited. It is highly unlikely that someone would actually + sniff your Wi-Fi traffic at your house at the exact moment you're provisioning your new robot. + + Furthermore, due to HTTPS currently (2022-08-20) not accounting for setups in which a service doesn't have + a globally unique identity proven by their domain name, just using HTTPS for the provisioning process is not + reasonably possible, as self-signed certificates are annoying to deal with, raise warnings in the browser etc. + Stuff that simply isn't worth the trouble when the risk is as low as it is here to begin with. + + But do we need HTTPS to improve security of this process? I'd argue no. + + What do we get from using HTTPS? + A. Encryption of the transmitted data + B. A way to ensure that whoever we're talking to is actually who we expected them to be + + Given that someone MITM'ing the communication between your robot and the device used to provision it + on the Wi-Fi network provided by the robot is exceptionally unlikely, we don't need B. + + It would surely be nice to have B by utilizing HTTPS, however not only would that come with a worse UX due + to the user having to click through warnings in their browser etc. but it also would not solve B in our + scenario(!), as there is no way of knowing if the certificate presented to you is actually the one issued by + the webserver and wasn't created by someone MITM'ing the connection. + + Therefore, we can solely focus on A: + By harnessing the power of asymmetric cryptography, the user can encrypt their Wi-Fi credentials in a way + that can't be decrypted just by passively sniffing Wi-Fi traffic in the area. + As soon as the robot is provisioned, the encryption of the Wi-Fi network then provides some layer of + protection against that passive sniffing scenario. + + As you can see, this approach offers a real benefit for the user without impacting the UX at all. + It doesn't achieve 100% of what using HTTPS would achieve, however that was never the goal to begin with nor + would've HTTPS worked in this scenario as explained above. + + By understanding that life has nuances and therefore looking at the context and details of a problem at hand + instead of just repeating dogmatic truths over and over again, one can make an informed decision to do + something slightly different from the established best-practices. + + If you're still unhappy and want to do something about this heresy against the gods of cryptography, + consider rallying for an extension of the HTTPS spec to allow for some way of ensuring the identity of + something without requiring a global domain name so that we may one day have proper HTTPS in non-cloud places. + + + Side-note: + Valve does it too ;-) + https://web.archive.org/web/20210108003523/https://owlspace.xyz/cybersec/steam-login/ + */ + this.router.get("/getPublicKeyForProvisioning", async (req, res) => { + const keyPair = await this.getKeyPair(); + + if (keyPair !== null) { + res.json({ + type: keyPair.type, + publicKey: keyPair.publicKey.export({ + type: "spki", + format: "pem" + }) + }); + } else { + res.sendStatus(500); + } + }); + + // Decrypting inside this middleware allows us to continue using the validator middleware further down the chain + this.router.use(async (req, res, next) => { + if (req.body?.encryption === "rsa" && typeof req.body.payload === "string") { + const decryptedPayload = await this.decryptPayload(req.body.payload); + + if (decryptedPayload !== null) { + req.body = decryptedPayload; + + next(); + } else { + res.sendStatus(400); + + return; } } else { - res.status(400).send("Missing request body"); + next(); + } + }); + + this.router.put("/", this.validator, async (req, res) => { + try { + let typeSpecificSettings; + + switch (req.body.credentials.type) { + case ValetudoWifiConfiguration.CREDENTIALS_TYPE.WPA2_PSK: + typeSpecificSettings = { + password: req.body.credentials.typeSpecificSettings.password + }; + break; + default: + typeSpecificSettings = {}; + } + + await this.capability.setWifiConfiguration(new ValetudoWifiConfiguration({ + ssid: req.body.ssid, + credentials: { + type: req.body.credentials.type, + typeSpecificSettings: typeSpecificSettings + } + })); + + res.sendStatus(200); + } catch (e) { + this.sendErrorResponse(req, res, e); } }); } + + /** + * @private + * @returns {Promise<{privateKey: crypto.KeyObject, publicKey: crypto.KeyObject, type: string}|null>} + */ + async getKeyPair() { + if (!this.keyPair.publicKey) { + try { + this.keyPair = await new Promise((resolve, reject) => { + crypto.generateKeyPair( + "rsa", + { + modulusLength: 2048 + }, + (err, publicKey, privateKey) => { + if (err) { + reject(err); + } else { + resolve({ + type: "rsa", + publicKey: publicKey, + privateKey: privateKey + }); + } + } + ); + }); + } catch (err) { + Logger.error("Error while generating KeyPair for WiFi Provisioning", err); + + return null; + } + } + + return this.keyPair; + } + + /** + * @private + * @param {string} payload base64 + * @returns {Promise} + */ + async decryptPayload(payload) { + const keypair = await this.getKeyPair(); + + if (keypair === null) { + return null; + } + + try { + const decryptedPayload = crypto.privateDecrypt( + { + key: this.keyPair.privateKey, + padding: crypto.constants.RSA_PKCS1_PADDING + }, + Buffer.from(payload, "base64") + ).toString("utf-8"); + + return JSON.parse(decryptedPayload); + } catch (err) { + Logger.error("Error while decrypting encrypted wifi provisioning payload", err); + + return null; + } + } } module.exports = WifiConfigurationCapabilityRouter; diff --git a/backend/lib/webserver/capabilityRouters/WifiScanCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/WifiScanCapabilityRouter.js index 88e4e70e..2a0b8646 100644 --- a/backend/lib/webserver/capabilityRouters/WifiScanCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/WifiScanCapabilityRouter.js @@ -1,10 +1,13 @@ const CapabilityRouter = require("./CapabilityRouter"); class WifiScanCapabilityRouter extends CapabilityRouter { - initRoutes() { this.router.get("/", async (req, res) => { - res.json(await this.capability.scan()); + try { + res.json(await this.capability.scan()); + } catch (e) { + this.sendErrorResponse(req, res, e); + } }); } } diff --git a/backend/lib/webserver/capabilityRouters/ZoneCleaningCapabilityRouter.js b/backend/lib/webserver/capabilityRouters/ZoneCleaningCapabilityRouter.js index 43eb96c2..f840fac3 100644 --- a/backend/lib/webserver/capabilityRouters/ZoneCleaningCapabilityRouter.js +++ b/backend/lib/webserver/capabilityRouters/ZoneCleaningCapabilityRouter.js @@ -1,224 +1,47 @@ -const escapeHtml = require("escape-html"); - const CapabilityRouter = require("./CapabilityRouter"); -const Logger = require("../../Logger"); - const ValetudoZone = require("../../entities/core/ValetudoZone"); -const ValetudoZonePreset = require("../../entities/core/ValetudoZonePreset"); class ZoneCleaningCapabilityRouter extends CapabilityRouter { - initRoutes() { - this.router.get("/presets", (req, res) => { - res.json(this.capability.robot.config.get("zonePresets")); - }); - - this.router.get("/presets/:id", (req, res) => { - const zone = this.capability.robot.config.get("zonePresets")[req.params.id]; - - if (zone) { - res.json(zone); - } else { - res.sendStatus(404); - } - }); - - this.router.put("/presets/:id", async (req, res) => { - const zone = this.capability.robot.config.get("zonePresets")[req.params.id]; - - if (zone && req.body && req.body.action === "clean") { + this.router.put("/", this.validator, async (req, res) => { + if (req.body.action === "clean" && Array.isArray(req.body.zones)) { try { - await this.capability.start(zone.zones); + await this.capability.start(req.body.zones.map(z => { + if (!(z.points)) { + throw new Error("Invalid Zone"); + } + + return new ValetudoZone({ + points: { + pA: { + x: z.points.pA?.x, + y: z.points.pA?.y, + }, + pB: { + x: z.points.pB?.x, + y: z.points.pB?.y, + }, + pC: { + x: z.points.pC?.x, + y: z.points.pC?.y, + }, + pD: { + x: z.points.pD?.x, + y: z.points.pD?.y, + }, + }, + iterations: z.iterations + }); + })); res.sendStatus(200); - } catch (e) { - Logger.warn("Error while starting zone cleaning for preset " + req.params.id, e); - res.status(500).json(e.message); - } - } else { - res.sendStatus(404); - } - }); - - this.router.delete("/presets/:id", (req, res) => { - const zoneSettings = this.capability.robot.config.get("zonePresets"); - - if (zoneSettings[req.params.id]) { - delete(zoneSettings[req.params.id]); - - this.capability.robot.config.set("zonePresets", zoneSettings); - - res.sendStatus(200); - } else { - res.sendStatus(404); - } - }); - this.router.post("/presets", (req, res) => { - if (req.body && req.body.name && Array.isArray(req.body.zones) && req.body.zones.length > 0) { - try { - const zoneSettings = this.capability.robot.config.get("zonePresets"); - const newPreset = new ValetudoZonePreset({ - name: req.body.name, - id: req.body.id, - zones: req.body.zones.map(z => { - return new ValetudoZone({ - points: z.points, - iterations: z.iterations - }); - }) - }); - - zoneSettings[newPreset.id] = newPreset; - - this.capability.robot.config.set("zonePresets", zoneSettings); - res.sendStatus(201); } catch (e) { - Logger.warn("Error while saving new zone", req.body); - res.status(500).json(e.message); + this.sendErrorResponse(req, res, e); } } else { res.sendStatus(400); } }); - - //TODO: Remove this after building a new webinterface - - this.router.get("/presets_legacy", (req, res) => { - const presetsFromConfig = Object.values(this.capability.robot.config.get("zonePresets")); - - res.json(presetsFromConfig.map(preset => { - return { - name: preset.name, - id: preset.id, - areas: preset.zones.map(zone => { - return [ - zone.points.pA.x, - zone.points.pA.y, - zone.points.pC.x, - zone.points.pC.y, - zone.iterations - ]; - }) - }; - })); - }); - - - this.router.post("/presets_legacy", (req, res) => { - if (Array.isArray(req.body)) { - const valid = req.body.every(z => { - return z && z.name && Array.isArray(z.areas); - }); - - if (valid) { - const zonePresetsArr = req.body.map(preset => { - return new ValetudoZonePreset({ - name: preset.name, - id: preset.id, - zones: preset.areas.map(zone => { - return new ValetudoZone({ - points: { - pA: { - x: zone[0], - y: zone[1] - }, - pB: { - x: zone[2], - y: zone[1] - }, - pC: { - x: zone[2], - y: zone[3] - }, - pD: { - x: zone[0], - y: zone[3] - }, - }, - iterations: zone[4] - }); - }) - }); - }); - const zonePresets = {}; - - zonePresetsArr.forEach(z => { - zonePresets[z.id] = z; - }); - - - - this.capability.robot.config.set("zonePresets", zonePresets); - res.sendStatus(201); - } else { - res.sendStatus(400); - } - } - }); - - - this.router.post("/presets/:id", (req, res) => { - const zoneSettings = this.capability.robot.config.get("zonePresets"); - - if (zoneSettings[req.params.id]) { - - if (req.body && req.body.name && Array.isArray(req.body.zones) && req.body.zones.length > 0) { - try { - const newPreset = new ValetudoZonePreset({ - name: req.body.name, - id: req.params.id, - zones: req.body.zones.map(z => { - return new ValetudoZone({ - points: z.points, - iterations: z.iterations - }); - }) - }); - - zoneSettings[newPreset.id] = newPreset; - - this.capability.robot.config.set("zonePresets", zoneSettings); - res.sendStatus(200); - } catch (e) { - Logger.warn("Error while saving new zone", req.body); - res.status(500).json(e.message); - } - } - } else { - res.sendStatus(404); - } - }); - - this.router.put("/", async (req, res) => { - if (req.body && req.body.action) { - if (req.body.action === "clean" && Array.isArray(req.body.zones)) { - try { - await this.capability.start(req.body.zones.map(z => { - if (!(z.points)) { //More validation would be nice - throw new Error("Invalid Zone"); - } - - return new ValetudoZone({ - points: z.points, - iterations: z.iterations - }); - })); - res.sendStatus(200); - - } catch (e) { - Logger.warn("Error while starting zone cleaning", { - body: req.body, - e: e - }); - res.status(500).json(e.message); - } - } else { - res.status(400).send(`Invalid action "${escapeHtml(req.body.action)}" in request body`); - } - } else { - res.status(400).send("Missing action in request body"); - } - }); } } diff --git a/backend/lib/webserver/capabilityRouters/doc/CombinedVirtualRestrictionsCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/CombinedVirtualRestrictionsCapabilityRouter.openapi.json index a93e22e4..d052f22c 100644 --- a/backend/lib/webserver/capabilityRouters/doc/CombinedVirtualRestrictionsCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/CombinedVirtualRestrictionsCapabilityRouter.openapi.json @@ -28,6 +28,71 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ValetudoVirtualRestrictions" + }, + "examples": { + "wall_regular_mop":{ + "description": "Set virtual restrictions", + "value": { + "virtualWalls": [ + { + "points": { + "pA": { + "x": 3390, + "y": 3330 + }, + "pB": { + "x": 3538, + "y": 3478 + } + } + } + ], + "restrictedZones": [ + { + "type": "regular", + "points": { + "pA": { + "x": 3175, + "y": 2670 + }, + "pB": { + "x": 3350, + "y": 2670 + }, + "pC": { + "x": 3350, + "y": 2925 + }, + "pD": { + "x": 3175, + "y": 2925 + } + } + }, + { + "type": "mop", + "points": { + "pA": { + "x": 3140, + "y": 3415 + }, + "pB": { + "x": 3290, + "y": 3415 + }, + "pC": { + "x": 3290, + "y": 3565 + }, + "pD": { + "x": 3140, + "y": 3565 + } + } + } + ] + } + } } } } diff --git a/backend/lib/webserver/capabilityRouters/doc/ConsumableMonitoringCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/ConsumableMonitoringCapabilityRouter.openapi.json index f09dd5c1..2fcbafce 100644 --- a/backend/lib/webserver/capabilityRouters/doc/ConsumableMonitoringCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/ConsumableMonitoringCapabilityRouter.openapi.json @@ -15,6 +15,55 @@ "items": { "$ref": "#/components/schemas/ConsumableStateAttribute" } + }, + "examples": { + "getConsumablesStatus": { + "description": "Get the status of the consumables.", + "value": + [ + { + "__class": "ConsumableStateAttribute", + "metaData": {}, + "type": "brush", + "subType": "main", + "remaining": { + "value": 123456, + "unit": "minutes" + } + }, + { + "__class": "ConsumableStateAttribute", + "metaData": {}, + "type": "brush", + "subType": "side_right", + "remaining": { + "value": 1234, + "unit": "minutes" + } + }, + { + "__class": "ConsumableStateAttribute", + "metaData": {}, + "type": "filter", + "subType": "main", + "remaining": { + "value": 5432, + "unit": "minutes" + } + }, + { + "__class": "ConsumableStateAttribute", + "metaData": {}, + "type": "sensor", + "subType": "all", + "remaining": { + "value": 123, + "unit": "minutes" + } + } + ] + + } } } } @@ -158,4 +207,4 @@ } } } -} +} \ No newline at end of file diff --git a/backend/lib/webserver/capabilityRouters/doc/DoNotDisturbCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/DoNotDisturbCapabilityRouter.openapi.json index 7b7c2017..7576cb93 100644 --- a/backend/lib/webserver/capabilityRouters/doc/DoNotDisturbCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/DoNotDisturbCapabilityRouter.openapi.json @@ -12,6 +12,23 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ValetudoDNDConfiguration" + }, + "examples": { + "getTimer": { + "description": "Get the do not disturb timer configuration", + "value": { + "enabled": true, + "start": { + "hour": 22, + "minute": 0 + }, + "end": { + "hour": 8, + "minute": 0 + }, + "metaData": {} + } + } } } } @@ -28,6 +45,23 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ValetudoDNDConfiguration" + }, + "examples": { + "setTimer": { + "description": "Set a do not disturb timer from 22:00 to 06:00", + "value": { + "enabled": true, + "start": { + "hour": 22, + "minute": 0 + }, + "end": { + "hour": 8, + "minute": 0 + }, + "metaData": {} + } + } } } } diff --git a/backend/lib/webserver/capabilityRouters/doc/GoToLocationCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/GoToLocationCapabilityRouter.openapi.json index 3d48e17e..158ad2eb 100644 --- a/backend/lib/webserver/capabilityRouters/doc/GoToLocationCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/GoToLocationCapabilityRouter.openapi.json @@ -1,190 +1,4 @@ { - "/api/v2/robot/capabilities/GoToLocationCapability/presets": { - "get": { - "tags": [ - "GoToLocationCapability" - ], - "summary": "Get available go-to-location presets", - "responses": { - "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "type": "object", - "description": "Describing this structure requires OpenAPI 3.1 support in Swagger UI" - } - } - } - } - } - }, - "post": { - "tags": [ - "GoToLocationCapability" - ], - "summary": "Add new preset", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoGoToLocation" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "400": { - "$ref": "#/components/responses/400" - } - } - } - }, - "/api/v2/robot/capabilities/GoToLocationCapability/presets/{id}": { - "get": { - "tags": [ - "GoToLocationCapability" - ], - "summary": "Get go-to-location preset by ID", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoGoToLocation" - } - } - } - }, - "404": { - "description": "The specified preset ID was not found" - } - } - }, - "put": { - "tags": [ - "GoToLocationCapability" - ], - "summary": "Go to a go-to-location preset", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "additionalProperties": false, - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "goto" - ] - } - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "404": { - "description": "The specified preset ID was not found" - }, - "500": { - "$ref": "#/components/responses/500" - } - } - }, - "post": { - "tags": [ - "GoToLocationCapability" - ], - "summary": "Edit existing preset by ID", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoGoToLocation" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "404": { - "description": "The specified preset ID does not exist." - } - } - }, - "delete": { - "tags": [ - "GoToLocationCapability" - ], - "summary": "Delete go-to-location preset by ID", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "404": { - "description": "The specified preset IDs was not found" - } - } - } - }, "/api/v2/robot/capabilities/GoToLocationCapability": { "put": { "tags": [ diff --git a/backend/lib/webserver/capabilityRouters/doc/MapSegmentEditCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/MapSegmentEditCapabilityRouter.openapi.json index 29f99037..c20cb6b2 100644 --- a/backend/lib/webserver/capabilityRouters/doc/MapSegmentEditCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/MapSegmentEditCapabilityRouter.openapi.json @@ -9,25 +9,17 @@ "content": { "application/json": { "schema": { - "allOf": [ + "oneOf": [ { "type": "object", + "description": "join_segments action", "properties": { "action": { "type": "string", "enum": [ - "join_segments", - "split_segment" + "join_segments" ] - } - } - } - ], - "oneOf": [ - { - "type": "object", - "description": "Provide if action is `join_segments`", - "properties": { + }, "segment_a_id": { "type": "string" }, @@ -38,8 +30,14 @@ }, { "type": "object", - "description": "Provide if action is `split_segment`", + "description": "split_segment action", "properties": { + "action": { + "type": "string", + "enum": [ + "split_segment" + ] + }, "segment_id": { "type": "string" }, @@ -52,6 +50,31 @@ } } ] + }, + "examples": { + "split_segment":{ + "description": "Split a segment along a line", + "value": { + "action": "split_segment", + "segment_id": "1", + "pA": { + "x": 3305, + "y": 2905 + }, + "pB": { + "x": 3305, + "y": 3050 + } + } + }, + "join_segments":{ + "description": "Join two segments", + "value": { + "action": "join_segments", + "segment_a_id": "4", + "segment_b_id": "5" + } + } } } } diff --git a/backend/lib/webserver/capabilityRouters/doc/MopDockCleanManualTriggerCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/MopDockCleanManualTriggerCapabilityRouter.openapi.json new file mode 100644 index 00000000..88deec4c --- /dev/null +++ b/backend/lib/webserver/capabilityRouters/doc/MopDockCleanManualTriggerCapabilityRouter.openapi.json @@ -0,0 +1,58 @@ +{ + "/api/v2/robot/capabilities/MopDockCleanManualTriggerCapability": { + "put": { + "tags": [ + "MopDockCleanManualTriggerCapability" + ], + "summary": "Mop Dock Clean Manual trigger", + "description": "Start and Stop cleaning of mop pads", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "Mop Dock clean action to perform", + "enum": [ + "start", + "stop" + ] + } + } + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/200" + }, + "400": { + "$ref": "#/components/responses/400" + } + } + } + }, + "/api/v2/robot/capabilities/MopDockCleanManualTriggerCapability/properties": { + "get": { + "tags": [ + "MopDockCleanManualTriggerCapability" + ], + "summary": "Get various capability-related properties", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } + } +} diff --git a/backend/lib/webserver/capabilityRouters/doc/MopDockDryManualTriggerCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/MopDockDryManualTriggerCapabilityRouter.openapi.json new file mode 100644 index 00000000..7bbb4c3c --- /dev/null +++ b/backend/lib/webserver/capabilityRouters/doc/MopDockDryManualTriggerCapabilityRouter.openapi.json @@ -0,0 +1,58 @@ +{ + "/api/v2/robot/capabilities/MopDockDryManualTriggerCapability": { + "put": { + "tags": [ + "MopDockDryManualTriggerCapability" + ], + "summary": "Mop Dock Dry Manual trigger", + "description": "Start and Stop drying of mop pads", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "Mop Dock dry action to perform", + "enum": [ + "start", + "stop" + ] + } + } + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/200" + }, + "400": { + "$ref": "#/components/responses/400" + } + } + } + }, + "/api/v2/robot/capabilities/MopDockDryManualTriggerCapability/properties": { + "get": { + "tags": [ + "MopDockDryManualTriggerCapability" + ], + "summary": "Get various capability-related properties", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } + } +} diff --git a/backend/lib/webserver/capabilityRouters/doc/PresetSelectionCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/PresetSelectionCapabilityRouter.openapi.json index 608af9fa..e08ba6cb 100644 --- a/backend/lib/webserver/capabilityRouters/doc/PresetSelectionCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/PresetSelectionCapabilityRouter.openapi.json @@ -41,6 +41,14 @@ "description": "Preset name retrieved from the same capability" } } + }, + "examples": { + "medium":{ + "description": "Set fan speed to medium", + "value": { + "name": "medium" + } + } } } } @@ -117,6 +125,14 @@ "description": "Preset name retrieved from the same capability" } } + }, + "examples": { + "medium":{ + "description": "Set water usage to medium", + "value": { + "name": "medium" + } + } } } } @@ -150,5 +166,89 @@ } } } + }, + "/api/v2/robot/capabilities/OperationModeControlCapability/presets": { + "get": { + "tags": [ + "OperationModeControlCapability" + ], + "summary": "Get available presets", + "parameters": [], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "/api/v2/robot/capabilities/OperationModeControlCapability/preset": { + "put": { + "tags": [ + "OperationModeControlCapability" + ], + "summary": "Set preset value", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Preset name retrieved from the same capability" + } + } + }, + "examples": { + "mop":{ + "description": "Set operation mode to mop only", + "value": { + "name": "mop" + } + } + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/200" + }, + "400": { + "$ref": "#/components/responses/400" + } + } + } + }, + "/api/v2/robot/capabilities/OperationModeControlCapability/properties": { + "get": { + "tags": [ + "OperationModeControlCapability" + ], + "summary": "Get various capability-related properties", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } } } diff --git a/backend/lib/webserver/capabilityRouters/doc/SensorCalibrationCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/SensorCalibrationCapabilityRouter.openapi.json deleted file mode 100644 index 09ad4d9b..00000000 --- a/backend/lib/webserver/capabilityRouters/doc/SensorCalibrationCapabilityRouter.openapi.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "/api/v2/robot/capabilities/SensorCalibrationCapability": { - "get": { - "tags": [ - "SensorCalibrationCapability" - ], - "summary": "Get available sensors settings", - "responses": { - "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ValetudoSensor" - } - } - } - } - } - } - } - }, - "/api/v2/robot/capabilities/SensorCalibrationCapability/{type}": { - "put": { - "tags": [ - "SensorCalibrationCapability" - ], - "summary": "Calibrate sensor", - "parameters": [ - { - "in": "path", - "name": "type", - "description": "Sensor type", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "action": { - "type": "string", - "enum": [ - "calibrate" - ] - } - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "400": { - "$ref": "#/components/responses/400" - } - } - } - }, - "/api/v2/robot/capabilities/SensorCalibrationCapability/{type}/{subType}": { - "put": { - "tags": [ - "SensorCalibrationCapability" - ], - "summary": "Calibrate sensor", - "parameters": [ - { - "in": "path", - "name": "type", - "description": "Sensor type", - "required": true, - "schema": { - "type": "string" - } - }, - { - "in": "path", - "name": "subType", - "description": "Sensor sub-type", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "action": { - "type": "string", - "enum": [ - "calibrate" - ] - } - } - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "400": { - "$ref": "#/components/responses/400" - } - } - } - } -} diff --git a/backend/lib/webserver/capabilityRouters/doc/VoicePackManagementCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/VoicePackManagementCapabilityRouter.openapi.json index 438739ec..27da2fd9 100644 --- a/backend/lib/webserver/capabilityRouters/doc/VoicePackManagementCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/VoicePackManagementCapabilityRouter.openapi.json @@ -54,6 +54,17 @@ "type": "string" } } + }, + "examples": { + "custom":{ + "description": "Install a custom voice pack", + "value": { + "action": "download", + "url": "http://host_or_ip/custom.tar.gz", + "language": "cu", + "hash": "md5md5md5md5md5md5md5md5md5md5md" + } + } } } } diff --git a/backend/lib/webserver/capabilityRouters/doc/WifiConfigurationCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/WifiConfigurationCapabilityRouter.openapi.json index ddaed3b3..9dba77dc 100644 --- a/backend/lib/webserver/capabilityRouters/doc/WifiConfigurationCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/WifiConfigurationCapabilityRouter.openapi.json @@ -26,8 +26,30 @@ "requestBody": { "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoWifiConfiguration" + "schema": { + "oneOf": [ + {"$ref": "#/components/schemas/ValetudoWifiConfiguration"}, + { + "type": "object", + "additionalProperties": false, + "properties": { + "encryption": { + "type": "string", + "enum": [ + "rsa" + ] + }, + "payload": { + "type": "string", + "description": "Base64 stringified ValetudoWifiConfiguration encrypted with the publicKey provided by /getPublicKeyForProvisioning" + } + }, + "required": [ + "encryption", + "payload" + ] + } + ] }, "examples": { "configure wifi": { @@ -59,6 +81,37 @@ } } }, + "/api/v2/robot/capabilities/WifiConfigurationCapability/getPublicKeyForProvisioning": { + "get": { + "tags": [ + "WifiConfigurationCapability" + ], + "summary": "Get the current public-key to encrypt the provisioning payload", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "rsa" + ] + }, + "publicKey": { + "type": "string" + } + } + } + } + } + } + } + } + }, "/api/v2/robot/capabilities/WifiConfigurationCapability/properties": { "get": { "tags": [ @@ -71,7 +124,12 @@ "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "provisionedReconfigurationSupported": { + "type": "boolean" + } + } } } } diff --git a/backend/lib/webserver/capabilityRouters/doc/ZoneCleaningCapabilityRouter.openapi.json b/backend/lib/webserver/capabilityRouters/doc/ZoneCleaningCapabilityRouter.openapi.json index 5d54e2ff..44727476 100644 --- a/backend/lib/webserver/capabilityRouters/doc/ZoneCleaningCapabilityRouter.openapi.json +++ b/backend/lib/webserver/capabilityRouters/doc/ZoneCleaningCapabilityRouter.openapi.json @@ -1,186 +1,4 @@ { - "/api/v2/robot/capabilities/ZoneCleaningCapability/presets": { - "get": { - "tags": [ - "ZoneCleaningCapability" - ], - "summary": "Get available zone presets", - "responses": { - "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "type": "object", - "description": "Describing this structure requires OpenAPI 3.1 support in Swagger UI" - } - } - } - } - } - }, - "post": { - "tags": [ - "ZoneCleaningCapability" - ], - "summary": "Add new preset", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoZonePreset" - } - } - } - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "400": { - "$ref": "#/components/responses/400" - } - } - } - }, - "/api/v2/robot/capabilities/ZoneCleaningCapability/presets/{id}": { - "get": { - "tags": [ - "ZoneCleaningCapability" - ], - "summary": "Get zone preset by ID", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoZonePreset" - } - } - } - }, - "404": { - "description": "One or more specified zone preset IDs were not found" - } - } - }, - "put": { - "tags": [ - "ZoneCleaningCapability" - ], - "summary": "Clean zone preset by ID", - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "action": { - "type": "string", - "enum": [ - "clean" - ] - } - } - } - } - } - }, - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "404": { - "description": "The specified zone preset IDs was not found" - } - } - }, - "delete": { - "tags": [ - "ZoneCleaningCapability" - ], - "summary": "Delete zone preset by ID", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "$ref": "#/components/responses/200" - }, - "404": { - "description": "The specified zone preset IDs was not found" - } - } - }, - "post": { - "tags": [ - "ZoneCleaningCapability" - ], - "summary": "Edit existing preset by ID", - "parameters": [ - { - "in": "path", - "name": "id", - "required": true, - "description": "Preset UUID", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ValetudoZonePreset" - } - } - } - }, - "responses": { - "201": { - "$ref": "#/components/responses/201" - }, - "400": { - "$ref": "#/components/responses/400" - }, - "404": { - "description": "The specified zone ID does not exist." - } - } - } - }, "/api/v2/robot/capabilities/ZoneCleaningCapability": { "put": { "tags": [ @@ -207,6 +25,37 @@ } } } + }, + "examples": { + "spot":{ + "description": "Clean a small spot", + "value": { + "action": "clean", + "zones": [ + { + "iterations": 1, + "points": { + "pA": { + "x": 2720, + "y": 3655 + }, + "pB": { + "x": 2850, + "y": 3655 + }, + "pC": { + "x": 2850, + "y": 3705 + }, + "pD": { + "x": 2720, + "y": 3705 + } + } + } + ] + } + } } } } diff --git a/backend/lib/webserver/capabilityRouters/index.js b/backend/lib/webserver/capabilityRouters/index.js index 9c3840b0..c12ec9c7 100644 --- a/backend/lib/webserver/capabilityRouters/index.js +++ b/backend/lib/webserver/capabilityRouters/index.js @@ -13,10 +13,11 @@ module.exports = { MapSegmentationCapabilityRouter: require("./MapSegmentationCapabilityRouter"), MapSnapshotCapabilityRouter: require("./MapSnapshotCapabilityRouter"), MappingPassCapabilityRouter: require("./MappingPassCapabilityRouter"), + MopDockCleanManualTriggerCapabilityRouter: require("./MopDockCleanManualTriggerCapabilityRouter"), + MopDockDryManualTriggerCapabilityRouter: require("./MopDockDryManualTriggerCapabilityRouter"), PendingMapChangeHandlingCapabilityRouter: require("./PendingMapChangeHandlingCapabilityRouter"), PresetSelectionCapabilityRouter: require("./PresetSelectionCapabilityRouter"), QuirksCapabilityRouter: require("./QuirksCapabilityRouter"), - SensorCalibrationCapabilityRouter: require("./SensorCalibrationCapabilityRouter"), SimpleToggleCapabilityRouter: require("./SimpleToggleCapabilityRouter"), SpeakerTestCapabilityRouter: require("./SpeakerTestCapabilityRouter"), SpeakerVolumeControlCapabilityRouter: require("./SpeakerVolumeControlCapabilityRouter"), @@ -24,5 +25,5 @@ module.exports = { VoicePackManagementCapabilityRouter: require("./VoicePackManagementCapabilityRouter"), WifiConfigurationCapabilityRouter: require("./WifiConfigurationCapabilityRouter"), WifiScanCapabilityRouter: require("./WifiScanCapabilityRouter"), - ZoneCleaningCapabilityRouter: require("./ZoneCleaningCapabilityRouter") + ZoneCleaningCapabilityRouter: require("./ZoneCleaningCapabilityRouter"), }; diff --git a/backend/lib/webserver/doc/MQTTRouter.openapi.json b/backend/lib/webserver/doc/MQTTRouter.openapi.json new file mode 100644 index 00000000..1e01706a --- /dev/null +++ b/backend/lib/webserver/doc/MQTTRouter.openapi.json @@ -0,0 +1,145 @@ +{ + "/api/v2/mqtt/status": { + "get": { + "tags": [ + "MQTT" + ], + "summary": "Get MQTTController status", + "responses": { + "200": { + "description": "The MQTTControllers current status.", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "properties": { + "state": { + "type": "string", + "enum": [ + "init", + "ready", + "disconnected", + "lost", + "alert" + ] + }, + "stats": { + "type": "object", + "additionalProperties": false, + "properties": { + "messages": { + "type": "object", + "additionalProperties": false, + "properties": { + "count": { + "type": "object", + "additionalProperties": false, + "properties": { + "received": { + "type": "number" + }, + "sent": { + "type": "number" + } + } + }, + "bytes": { + "type": "object", + "additionalProperties": false, + "properties": { + "received": { + "type": "number" + }, + "sent": { + "type": "number" + } + } + } + } + }, + "connection": { + "type": "object", + "additionalProperties": false, + "properties": { + "connects": { + "type": "number" + }, + "disconnects": { + "type": "number" + }, + "reconnects": { + "type": "number" + }, + "errors": { + "type": "number" + } + } + } + } + } + } + } + } + } + } + } + } + }, + "/api/v2/mqtt/properties": { + "get": { + "tags": [ + "MQTT" + ], + "summary": "Get MQTT properties such as the default config values", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "properties": { + "defaults": { + "type": "object", + "additionalProperties": false, + "properties": { + "identity": { + "type": "object", + "additionalProperties": false, + "properties": { + "friendlyName": { + "type": "string" + }, + "identifier": { + "type": "string" + } + } + }, + "customizations": { + "type": "object", + "additionalProperties": false, + "properties": { + "topicPrefix": { + "type": "string" + } + } + } + } + }, + "optionalExposableCapabilities": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + } +} diff --git a/backend/lib/webserver/doc/NTPClientRouter.openapi.json b/backend/lib/webserver/doc/NTPClientRouter.openapi.json index 8008b8c3..1918108a 100644 --- a/backend/lib/webserver/doc/NTPClientRouter.openapi.json +++ b/backend/lib/webserver/doc/NTPClientRouter.openapi.json @@ -61,13 +61,25 @@ "application/json": { "schema": { "$ref": "#/components/schemas/NTPClientConfigDTO" + }, + "examples": { + "custom":{ + "description": "Set custom NTP server", + "value": { + "enabled": true, + "server": "ntp_host_or_ip", + "port": 123, + "interval": 7200000, + "timeout": 10000 + } + } } } } }, "responses": { - "202": { - "$ref": "#/components/responses/202" + "200": { + "$ref": "#/components/responses/200" } } } diff --git a/backend/lib/webserver/doc/NetworkAdvertisementManagerRouter.openapi.json b/backend/lib/webserver/doc/NetworkAdvertisementManagerRouter.openapi.json new file mode 100644 index 00000000..012adf0d --- /dev/null +++ b/backend/lib/webserver/doc/NetworkAdvertisementManagerRouter.openapi.json @@ -0,0 +1,71 @@ +{ + "/api/v2/networkadvertisement/config": { + "get": { + "tags": [ + "NetworkAdvertisement" + ], + "summary": "Get NetworkAdvertisementManager configuration", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NetworkAdvertisementConfigDTO" + } + } + } + } + } + }, + "put": { + "tags": [ + "NetworkAdvertisement" + ], + "summary": "Update NetworkAdvertisementManager configuration", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NetworkAdvertisementConfigDTO" + } + } + } + }, + "responses": { + "200": { + "$ref": "#/components/responses/200" + } + } + } + }, + "/api/v2/networkadvertisement/properties": { + "get": { + "tags": [ + "NetworkAdvertisement" + ], + "summary": "Get NetworkAdvertisement properties", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": false, + "properties": { + "port": { + "type": "number" + }, + "zeroconfHostname": { + "type": "string" + } + } + } + } + } + } + } + } + } +} diff --git a/backend/lib/webserver/doc/RobotRouter.openapi.json b/backend/lib/webserver/doc/RobotRouter.openapi.json index f2d2cf89..981424fb 100644 --- a/backend/lib/webserver/doc/RobotRouter.openapi.json +++ b/backend/lib/webserver/doc/RobotRouter.openapi.json @@ -19,6 +19,18 @@ "modelName": { "type": "string" }, + "modelDetails": { + "type": "object", + "properties": { + "supportedAttachments": { + "type": "array", + "description": "Attachments that are detected and reported by the robot", + "items": { + "$ref": "#/components/schemas/AttachmentStateAttributeType" + } + } + } + }, "implementation": { "type": "string", "description": "Valetudo robot implementation in use" diff --git a/backend/lib/webserver/doc/TimerRouter.openapi.json b/backend/lib/webserver/doc/TimerRouter.openapi.json index f988ec27..8322ba1e 100644 --- a/backend/lib/webserver/doc/TimerRouter.openapi.json +++ b/backend/lib/webserver/doc/TimerRouter.openapi.json @@ -63,44 +63,14 @@ } } } - }, - "zone_cleanup": { - "description": "A timer scheduling a cleanup of a zone preset every sunday at 11:10 UTC", - "value": { - "enabled": true, - "dow": [0], - "hour": 11, - "minute": 10, - "action": { - "type": "zone_cleanup", - "params": { - "zone_id": "338b8c37-8ecd-48b4-b3d2-e03fd74d2e25" - } - } - } - }, - "goto_location": { - "description": "A timer scheduling a goto preset every tuesday at 4AM UTC", - "value": { - "enabled": true, - "dow": [2], - "hour": 4, - "minute": 0, - "action": { - "type": "goto_location", - "params": { - "goto_id": "c04a24bd-67fc-4ca8-9dbe-2d867fb71147" - } - } - } } } } } }, "responses": { - "201": { - "$ref": "#/components/responses/201" + "200": { + "$ref": "#/components/responses/200" }, "400": { "$ref": "#/components/responses/400" @@ -166,7 +136,7 @@ } } }, - "post": { + "put": { "tags": [ "Timers" ], @@ -192,8 +162,8 @@ } }, "responses": { - "201": { - "$ref": "#/components/responses/201" + "200": { + "$ref": "#/components/responses/200" }, "400": { "$ref": "#/components/responses/400" @@ -225,9 +195,7 @@ "type": "string", "enum": [ "full_cleanup", - "zone_cleanup", - "segment_cleanup", - "goto_location" + "segment_cleanup" ] } } diff --git a/backend/lib/webserver/doc/ValetudoEventRouter.openapi.json b/backend/lib/webserver/doc/ValetudoEventRouter.openapi.json index 47457e7f..4cf19593 100644 --- a/backend/lib/webserver/doc/ValetudoEventRouter.openapi.json +++ b/backend/lib/webserver/doc/ValetudoEventRouter.openapi.json @@ -105,8 +105,8 @@ } } }, - "400": { - "$ref": "#/components/responses/400" + "500": { + "$ref": "#/components/responses/500" }, "404": { "$ref": "#/components/responses/404" diff --git a/backend/lib/webserver/doc/ValetudoRouter.openapi.json b/backend/lib/webserver/doc/ValetudoRouter.openapi.json index 8e426036..a6d61815 100644 --- a/backend/lib/webserver/doc/ValetudoRouter.openapi.json +++ b/backend/lib/webserver/doc/ValetudoRouter.openapi.json @@ -15,6 +15,9 @@ "properties": { "embedded": { "type": "boolean" + }, + "systemId": { + "type": "string" } } } @@ -152,8 +155,8 @@ }, "description": "Log level retrieved from GET presets", "responses": { - "202": { - "$ref": "#/components/responses/202" + "200": { + "$ref": "#/components/responses/200" } } } @@ -191,59 +194,9 @@ } } }, - "responses": { - "202": { - "$ref": "#/components/responses/202" - } - } - } - }, - "/api/v2/valetudo/config/interfaces/mqtt/properties": { - "get": { - "tags": [ - "Valetudo" - ], - "summary": "Get MQTT config properties such as the default values", "responses": { "200": { - "description": "Ok", - "content": { - "application/json": { - "schema": { - "type": "object", - "additionalProperties": false, - "properties": { - "defaults": { - "type": "object", - "additionalProperties": false, - "properties": { - "identity": { - "type": "object", - "additionalProperties": false, - "properties": { - "friendlyName": { - "type": "string" - }, - "identifier": { - "type": "string" - } - } - }, - "customizations": { - "type": "object", - "additionalProperties": false, - "properties": { - "topicPrefix": { - "type": "string" - } - } - } - } - } - } - } - } - } + "$ref": "#/components/responses/200" } } } @@ -282,8 +235,8 @@ } }, "responses": { - "201": { - "$ref": "#/components/responses/201" + "200": { + "$ref": "#/components/responses/200" }, "400": { "$ref": "#/components/responses/400" diff --git a/backend/lib/webserver/middlewares/ExternalAccessCheckMiddleware.js b/backend/lib/webserver/middlewares/ExternalAccessCheckMiddleware.js index ae1a504a..a756b317 100644 --- a/backend/lib/webserver/middlewares/ExternalAccessCheckMiddleware.js +++ b/backend/lib/webserver/middlewares/ExternalAccessCheckMiddleware.js @@ -1,9 +1,9 @@ +const hashlru = require("hashlru"); const isInSubnet = require("is-in-subnet"); const Logger = require("../../Logger"); -const QuickLRU = require("quick-lru"); -const Tools = require("../../Tools"); +const Tools = require("../../utils/Tools"); -const IPAccessLRU = new QuickLRU({ maxSize: 15 }); +const IPAccessLRU = hashlru(15); /** * @@ -17,7 +17,7 @@ module.exports = function checkExternalAccess(req, res, next) { } else { Logger.warn(`Blocked external request to ${req.url} from ${req.ip}`); - res.status(401).send("External access to Valetudo is blocked."); + res.status(418).send("External access to Valetudo is blocked."); } }; diff --git a/backend/lib/webserver/middlewares/VersionMiddleware.js b/backend/lib/webserver/middlewares/VersionMiddleware.js index 0152fe91..77f5a14b 100644 --- a/backend/lib/webserver/middlewares/VersionMiddleware.js +++ b/backend/lib/webserver/middlewares/VersionMiddleware.js @@ -1,4 +1,4 @@ -const Tools = require("../../Tools"); +const Tools = require("../../utils/Tools"); const version = Tools.GET_VALETUDO_VERSION(); const commitId = Tools.GET_COMMIT_ID(); diff --git a/backend/lib/webserver/middlewares/sse/SSEMiddleware.js b/backend/lib/webserver/middlewares/sse/SSEMiddleware.js index 274a10df..3f47a06e 100644 --- a/backend/lib/webserver/middlewares/sse/SSEMiddleware.js +++ b/backend/lib/webserver/middlewares/sse/SSEMiddleware.js @@ -18,7 +18,7 @@ module.exports = function(options) { */ return function SSEMiddleware(req, res, next) { if (options.hub.clients.size >= options.maxClients) { - Logger.warn(`More than ${options.maxClients} SSE clients are connected to the ${options.hub.name} SSE Hub. Terminating the oldest connection.`); + Logger.debug(`More than ${options.maxClients} SSE clients are connected to the ${options.hub.name} SSE Hub. Terminating the oldest connection.`); //Sets are iterated in insertion order. Therefore, to disconnect the oldest connection, //we just take the first value @@ -34,7 +34,7 @@ module.exports = function(options) { }, terminate() { res.end(); - res.socket.destroy(); + res.socket?.destroy(); } }; @@ -78,10 +78,10 @@ module.exports = function(options) { It does take quite a while until this value increases above 0 for some reason. Likely due to other buffers elsewhere */ - if (res.socket.writableLength > 0) { - Logger.warn(`Stale SSE connection to the ${options.hub.name} SSE Hub detected. Terminating.`); + if (res.socket?.writableLength > 0) { + Logger.debug(`Stale SSE connection to the ${options.hub.name} SSE Hub detected. Terminating.`); - res.socket.destroy(); + res.socket?.destroy(); return false; } else { diff --git a/backend/package.json b/backend/package.json index e8642739..b611b7b4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,13 +5,12 @@ "bin": "index.js", "license": "Apache-2.0", "engines": { - "node": ">=15" + "node": ">=16" }, "pkg": { "assets": [ "../.git/HEAD", "../.git/refs/heads/master", - "../old_frontend/lib", "../frontend/build", "../package.json", "../node_modules/swagger-ui-dist/swagger-ui.css", @@ -21,59 +20,57 @@ "scripts": { "start": "node index.js", "start:dev": "cross-env VALETUDO_CONFIG_PATH=../local/valetudo_config.json npm run start", - "lint": "eslint .", - "lint_fix": "eslint . --fix", + "lint": "eslint -c .automated.eslintrc.json .", + "lint_fix": "eslint -c .automated.eslintrc.json . --fix", + "lint_pedantic": "eslint -c .pedantic.eslintrc.json .", "ts-check": "tsc --noEmit", "test": "mocha \"test/**/*_spec.js\"", "prepare_commit": "npm run lint_fix && npm run ts-check && npm run test", "build": "npm run build_armv7 && npm run build_aarch64 && npm run build_armv7_lowmem", - "build_armv7": "cross-env PKG_CACHE_PATH=../build_dependencies/pkg pkg --targets node16-linuxstatic-armv7 --compress Brotli --no-bytecode --public-packages \"*\" --options \"expose-gc,max-heap-size=38\" . --output ../build/armv7/valetudo", - "build_aarch64": "cross-env PKG_CACHE_PATH=../build_dependencies/pkg pkg --targets node16-linuxstatic-arm64 --compress Brotli --no-bytecode --public-packages \"*\" --options \"expose-gc,max-heap-size=64\" . --output ../build/aarch64/valetudo", - "build_armv7_lowmem": "cross-env PKG_CACHE_PATH=../build_dependencies/pkg pkg --targets node16-linuxstatic-armv7 --compress Brotli --no-bytecode --public-packages \"*\" --options \"expose-gc,max-heap-size=34,optimize-for-size,lite-mode,no-regexp-tier-up,no-expose-wasm\" . --output ../build/armv7/valetudo-lowmem" + "build_armv7": "cross-env PKG_CACHE_PATH=../build_dependencies/pkg pkg --targets node18-linuxstatic-armv7 --compress Brotli --no-bytecode --public-packages \"*\" --options \"expose-gc,max-heap-size=38\" . --output ../build/armv7/valetudo", + "build_aarch64": "cross-env PKG_CACHE_PATH=../build_dependencies/pkg pkg --targets node18-linuxstatic-arm64 --compress Brotli --no-bytecode --public-packages \"*\" --options \"expose-gc,max-heap-size=64\" . --output ../build/aarch64/valetudo", + "build_armv7_lowmem": "cross-env PKG_CACHE_PATH=../build_dependencies/pkg pkg --targets node18-linuxstatic-armv7 --compress Brotli --no-bytecode --public-packages \"*\" --options \"expose-gc,max-heap-size=34,optimize-for-size,lite-mode,no-regexp-tier-up,no-expose-wasm\" . --output ../build/armv7/valetudo-lowmem" }, "author": "", "dependencies": { "@agnoc/core": "~0.16.0-next.7", "@destinationstransfers/ntp": "2.0.0", - "ajv": "8.8.2", - "async-mqtt": "2.6.1", - "axios": "0.24.0", - "body-parser": "1.19.0", - "bonjour-service": "git+https://npm@github.com/Hypfer/bonjour-service#113d63c3a07f739001198545d2a9c1043e9a5b0b", + "ajv": "8.11.0", + "async-mqtt": "2.6.3", + "axios": "0.27.2", + "bonjour-service": "1.0.14", "compression": "1.7.4", - "crc": "3.8.0", - "escape-html": "1.0.3", - "express": "4.17.2", + "crc": "4.1.1", + "express": "4.18.2", "express-basic-auth": "1.2.1", "express-dynamic-middleware": "1.0.0", "express-list-endpoints": "6.0.0", - "express-rate-limit": "5.5.1", + "express-rate-limit": "6.6.0", + "hashlru": "git+https://npm@github.com/Hypfer/hashlru#3.0.0", "is-in-subnet": "4.0.1", - "jstoxml": "2.2.7", - "mqtt": "4.2.8", + "jstoxml": "3.2.5", + "mqtt": "4.3.7", "nested-object-assign": "1.0.4", "nested-property": "4.0.0", - "node-ssdp": "4.0.1", - "openapi-validator-middleware": "3.2.4", - "quick-lru": "5.1.1", + "openapi-validator-middleware": "3.2.6", "semaphore": "1.1.0", - "swagger-ui-express": "4.3.0", - "uuid": "8.3.2", + "swagger-ui-express": "4.5.0", + "uuid": "9.0.0", "zoo-ids": "2.0.7" }, "devDependencies": { "@types/compression": "1.7.2", - "@types/express": "4.17.13", + "@types/express": "4.17.14", "@types/express-list-endpoints": "6.0.0", - "@types/jstoxml": "2.0.1", - "@types/mocha": "7.0.2", - "@types/node": "16.11.1", + "@types/jstoxml": "2.0.2", + "@types/mocha": "10.0.0", + "@types/node": "18.8.4", "@types/node-ssdp": "4.0.1", "@types/semaphore": "1.1.1", - "@types/uuid": "8.3.3", + "@types/uuid": "8.3.4", "cross-env": "7.0.3", - "mocha": "7.1.1", - "pkg": "5.3.2", + "mocha": "10.0.0", + "pkg": "5.7.0", "should": "13.2.3" } } diff --git a/backend/test/lib/miio/MiioSocket_spec.js b/backend/test/lib/miio/MiioSocket_spec.js new file mode 100644 index 00000000..dabc7757 --- /dev/null +++ b/backend/test/lib/miio/MiioSocket_spec.js @@ -0,0 +1,30 @@ +const should = require("should"); + +const MiioSocket = require("../../../lib/miio/MiioSocket"); + +should.config.checkProtoEql = false; + +describe("MiioSocket", function () { + it("Should generate MessageIds correctly", async function() { + //Jan 1970 means no synced time => 1 msgId per second + MiioSocket.calculateMsgId(new Date("1970-01-01T00:00:01.000Z")).should.equal(1); + + // Up until 1970-01-02, IDs are collision-free to allow the ntp sync to take some time + MiioSocket.calculateMsgId(new Date("1970-01-01T23:59:59.000Z")).should.equal(86399); + MiioSocket.calculateMsgId(new Date("1970-01-02T00:00:00.000Z")).should.equal(86400); + + MiioSocket.calculateMsgId(new Date("1970-01-31T23:59:59.000Z")).should.equal(2678399); + MiioSocket.calculateMsgId(new Date("1970-02-01T00:00:00.000Z")).should.equal(2678400); + + // >= Feb 1970 means synced time => 1 msgId every 10ms + MiioSocket.calculateMsgId(new Date("1970-02-01T00:00:01.000Z")).should.equal(267926500); + + + //wrapping occurs every ~5965 hours + MiioSocket.calculateMsgId(new Date("1972-09-21T03:58:09.870Z")).should.equal(2147483646); + MiioSocket.calculateMsgId(new Date("1972-09-21T03:58:09.880Z")).should.equal(86400); + + MiioSocket.calculateMsgId(new Date("1973-05-27T16:57:42.340Z")).should.equal(2147483646); + MiioSocket.calculateMsgId(new Date("1973-05-27T16:57:42.350Z")).should.equal(86400); + }); +}); diff --git a/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability_spec.js b/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability_spec.js index 0911c441..7f6f2a30 100644 --- a/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability_spec.js +++ b/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability_spec.js @@ -1,4 +1,5 @@ const fs = require("fs"); +const path = require("path"); const should = require("should"); const LinuxWifiConfigurationCapability = require("../../../../../lib/robots/common/linuxCapabilities/LinuxWifiConfigurationCapability"); @@ -12,8 +13,8 @@ describe("LinuxWifiConfigurationCapability", function () { }); it("Should parse iw connected output correctly", async function() { - let data = fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/iw_3.4_connected.txt").toString(); - let expected = JSON.parse(fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/iw_3.4_connected.json").toString()); + let data = fs.readFileSync(path.join(__dirname, "/res/iw_3.4_connected.txt")).toString(); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/iw_3.4_connected.json")).toString()); let actual = capability.parseIwStdout(data); @@ -21,8 +22,8 @@ describe("LinuxWifiConfigurationCapability", function () { }); it("Should parse iw not connected output correctly", async function() { - let data = fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/iw_3.4_not_connected.txt").toString(); - let expected = JSON.parse(fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/iw_3.4_not_connected.json").toString()); + let data = fs.readFileSync(path.join(__dirname, "/res/iw_3.4_not_connected.txt")).toString(); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/iw_3.4_not_connected.json")).toString()); let actual = capability.parseIwStdout(data); @@ -31,7 +32,7 @@ describe("LinuxWifiConfigurationCapability", function () { it("Should parse no output correctly", async function() { let data = ""; - let expected = JSON.parse(fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/no_output.json").toString()); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/no_output.json")).toString()); let actual = capability.parseIwStdout(data); diff --git a/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiScanCapability_spec.js b/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiScanCapability_spec.js index 78dd7fb7..7cb0bbaf 100644 --- a/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiScanCapability_spec.js +++ b/backend/test/lib/robots/common/linuxCapabilities/LinuxWifiScanCapability_spec.js @@ -1,4 +1,5 @@ const fs = require("fs"); +const path = require("path"); const should = require("should"); const LinuxWifiScanCapability = require("../../../../../lib/robots/common/linuxCapabilities/LinuxWifiScanCapability"); @@ -12,8 +13,8 @@ describe("LinuxWifiScanCapability", function () { }); it("Should parse iw scan output correctly", async function() { - let data = fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/iw_3.4_scan.txt").toString(); - let expected = JSON.parse(fs.readFileSync("./test/lib/robots/common/linuxCapabilities/res/iw_3.4_scan.json").toString()); + let data = fs.readFileSync(path.join(__dirname, "/res/iw_3.4_scan.txt")).toString(); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/iw_3.4_scan.json")).toString()); let actual = capability.parseScanData(data); diff --git a/backend/test/lib/robots/dreame/DreameMapParser_spec.js b/backend/test/lib/robots/dreame/DreameMapParser_spec.js index 1d85806e..acdf2bcc 100644 --- a/backend/test/lib/robots/dreame/DreameMapParser_spec.js +++ b/backend/test/lib/robots/dreame/DreameMapParser_spec.js @@ -1,4 +1,5 @@ const fs = require("fs").promises; +const path = require("path"); const should = require("should"); const DreameMapParser = require("../../../../lib/robots/dreame/DreameMapParser"); @@ -8,10 +9,10 @@ should.config.checkProtoEql = false; describe("DreameMapParser", function () { it("Should parse D9 FW 1058 no-segment map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/d9_1058_no_segments.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/d9_1058_no_segments.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/d9_1058_no_segments.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/d9_1058_no_segments.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(data); + let actual = await DreameMapParser.PARSE(data); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -34,10 +35,10 @@ describe("DreameMapParser", function () { it("Should parse D9 FW 1058 segment map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/d9_1058_with_segments.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/d9_1058_with_segments.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/d9_1058_with_segments.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/d9_1058_with_segments.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(data); + let actual = await DreameMapParser.PARSE(data); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -59,10 +60,10 @@ describe("DreameMapParser", function () { }); it("Should pre-process & parse D9 FW 1058 \"custom named segment\" map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/d9_1058_with_custom_named_segments.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/d9_1058_with_custom_named_segments.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/d9_1058_with_custom_named_segments.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/d9_1058_with_custom_named_segments.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -84,10 +85,10 @@ describe("DreameMapParser", function () { }); it("Should pre-process & parse D9 FW 1093 \"huge\" map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/d9_1093_huge.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/d9_1093_huge.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/d9_1093_huge.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/d9_1093_huge.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -109,10 +110,10 @@ describe("DreameMapParser", function () { }); it("Should pre-process & parse Z10 FW 1056 map with virtual restrictions correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/z10_1056_virtual_restrictions.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/z10_1056_virtual_restrictions.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/z10_1056_virtual_restrictions.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/z10_1056_virtual_restrictions.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -134,10 +135,10 @@ describe("DreameMapParser", function () { }); it("Should pre-process & parse Z10 FW 1056 map with paths correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/z10_1056_paths.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/z10_1056_paths.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/z10_1056_paths.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/z10_1056_paths.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -158,11 +159,19 @@ describe("DreameMapParser", function () { actual.should.deepEqual(expected); }); + it("Should preprocess & not parse Z10 FW 1156 super minimal map", async function() { + let data = await fs.readFile(path.join(__dirname, "/res/map/z10_1156_super_minimal.bin")); + + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); + + should.equal(actual, null); + }); + it("Should pre-process & parse 1C FW 1096 \"zoned-cleanup in progress\" map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_zonedcleanup.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_zonedcleanup.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/1c_1096_zonedcleanup.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/1c_1096_zonedcleanup.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -184,10 +193,10 @@ describe("DreameMapParser", function () { }); it("Should pre-process & parse 1C FW 1096 \"full cleanup in progress\" map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_fullcleanup.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_fullcleanup.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/1c_1096_fullcleanup.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/1c_1096_fullcleanup.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -209,10 +218,10 @@ describe("DreameMapParser", function () { }); it("Should pre-process & parse 1C FW 1096 \"area cleanup in progress\" map correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_areacleanup.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_areacleanup.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/1c_1096_areacleanup.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/1c_1096_areacleanup.json"), { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); @@ -235,9 +244,81 @@ describe("DreameMapParser", function () { it("Should pre-process & parse 1C FW 1096 map with virtual wall & a no-go zone correctly", async function() { - let data = await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_virtualwall_and_forbidden_zone.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/dreame/res/map/1c_1096_virtualwall_and_forbidden_zone.json", { encoding: "utf-8" })); - let actual = DreameMapParser.PARSE(DreameMapParser.PREPROCESS(data)); + let data = await fs.readFile(path.join(__dirname, "/res/map/1c_1096_virtualwall_and_forbidden_zone.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/1c_1096_virtualwall_and_forbidden_zone.json"), { encoding: "utf-8" })); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); + + if (actual.metaData?.nonce) { + delete(actual.metaData.nonce); + } + + actual.layers.length.should.equal(expected.layers.length, "layerCount"); + + actual.layers.forEach((layer, i) => { + actual.layers[i].should.deepEqual(expected.layers[i]); + }); + + actual.entities.length.should.equal(expected.entities.length, "entitiesCount"); + + actual.entities.forEach((layer, i) => { + actual.entities[i].should.deepEqual(expected.entities[i]); + }); + + actual.should.deepEqual(expected); + }); + + it("Should pre-process & parse L10S Ultra FW 1058 map with goto target correctly", async function() { + let data = await fs.readFile(path.join(__dirname, "/res/map/l10su_1058_goto_target.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/l10su_1058_goto_target.json"), { encoding: "utf-8" })); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); + + if (actual.metaData?.nonce) { + delete(actual.metaData.nonce); + } + + actual.layers.length.should.equal(expected.layers.length, "layerCount"); + + actual.layers.forEach((layer, i) => { + actual.layers[i].should.deepEqual(expected.layers[i]); + }); + + actual.entities.length.should.equal(expected.entities.length, "entitiesCount"); + + actual.entities.forEach((layer, i) => { + actual.entities[i].should.deepEqual(expected.entities[i]); + }); + + actual.should.deepEqual(expected); + }); + + it("Should pre-process & parse L10S Ultra FW 1121 map with new path correctly", async function() { + let data = await fs.readFile(path.join(__dirname, "/res/map/l10su_1121_new_path.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/l10su_1121_new_path.json"), { encoding: "utf-8" })); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); + + if (actual.metaData?.nonce) { + delete(actual.metaData.nonce); + } + + actual.layers.length.should.equal(expected.layers.length, "layerCount"); + + actual.layers.forEach((layer, i) => { + actual.layers[i].should.deepEqual(expected.layers[i]); + }); + + actual.entities.length.should.equal(expected.entities.length, "entitiesCount"); + + actual.entities.forEach((layer, i) => { + actual.entities[i].should.deepEqual(expected.entities[i]); + }); + + actual.should.deepEqual(expected); + }); + + it("Should pre-process & parse L10S Ultra FW 1121 map with carpet correctly", async function() { + let data = await fs.readFile(path.join(__dirname, "/res/map/l10su_1121_carpet.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/l10su_1121_carpet.json"), { encoding: "utf-8" })); + let actual = await DreameMapParser.PARSE(await DreameMapParser.PREPROCESS(data)); if (actual.metaData?.nonce) { delete(actual.metaData.nonce); diff --git a/backend/test/lib/robots/dreame/DreameUtils_spec.js b/backend/test/lib/robots/dreame/DreameUtils_spec.js new file mode 100644 index 00000000..e7afeabc --- /dev/null +++ b/backend/test/lib/robots/dreame/DreameUtils_spec.js @@ -0,0 +1,44 @@ +const should = require("should"); + +const DreameUtils = require("../../../../lib/robots/dreame/DreameUtils"); + +should.config.checkProtoEql = false; + +describe("DreameUtils", function () { + + it("Should deserialize mop dock settings", async function() { + const actual = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(197889); + + actual.should.deepEqual({ + "operationMode": 1, + "padCleaningFrequency": 5, + "waterGrade": 3, + }); + + const actual2 = DreameUtils.DESERIALIZE_MOP_DOCK_SETTINGS(133632); + + actual2.should.deepEqual({ + "operationMode": 0, + "padCleaningFrequency": 10, + "waterGrade": 2, + }); + }); + + it("Should serialize mop dock settings", async function() { + const actual = DreameUtils.SERIALIZE_MOP_DOCK_SETTINGS({ + "operationMode": 1, + "padCleaningFrequency": 5, + "waterGrade": 3, + }); + + actual.should.equal(197889); + + const actual2 = DreameUtils.SERIALIZE_MOP_DOCK_SETTINGS({ + "operationMode": 0, + "padCleaningFrequency": 10, + "waterGrade": 2, + }); + + actual2.should.equal(133632); + }); +}); diff --git a/backend/test/lib/robots/dreame/res/map/1c_1096_areacleanup.json b/backend/test/lib/robots/dreame/res/map/1c_1096_areacleanup.json index 51df1dd6..d9abfd92 100644 --- a/backend/test/lib/robots/dreame/res/map/1c_1096_areacleanup.json +++ b/backend/test/lib/robots/dreame/res/map/1c_1096_areacleanup.json @@ -287,7 +287,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "rism", "area": 17125 @@ -468,7 +468,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "rism", "area": 27575 @@ -604,7 +604,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": true, "source": "rism", "area": 236950 diff --git a/backend/test/lib/robots/dreame/res/map/1c_1096_fullcleanup.json b/backend/test/lib/robots/dreame/res/map/1c_1096_fullcleanup.json index 6542026d..78d98834 100644 --- a/backend/test/lib/robots/dreame/res/map/1c_1096_fullcleanup.json +++ b/backend/test/lib/robots/dreame/res/map/1c_1096_fullcleanup.json @@ -278,7 +278,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "rism", "area": 17125 @@ -459,7 +459,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "rism", "area": 27575 @@ -595,7 +595,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "rism", "area": 236950 diff --git a/backend/test/lib/robots/dreame/res/map/1c_1096_virtualwall_and_forbidden_zone.json b/backend/test/lib/robots/dreame/res/map/1c_1096_virtualwall_and_forbidden_zone.json index 361aeeff..941fd51c 100644 --- a/backend/test/lib/robots/dreame/res/map/1c_1096_virtualwall_and_forbidden_zone.json +++ b/backend/test/lib/robots/dreame/res/map/1c_1096_virtualwall_and_forbidden_zone.json @@ -164,7 +164,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "rism", "area": 17125 @@ -345,7 +345,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "rism", "area": 27575 @@ -481,7 +481,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "rism", "area": 236950 diff --git a/backend/test/lib/robots/dreame/res/map/1c_1096_zonedcleanup.json b/backend/test/lib/robots/dreame/res/map/1c_1096_zonedcleanup.json index 5dd93371..af65cd19 100644 --- a/backend/test/lib/robots/dreame/res/map/1c_1096_zonedcleanup.json +++ b/backend/test/lib/robots/dreame/res/map/1c_1096_zonedcleanup.json @@ -134,7 +134,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "rism", "area": 17125 @@ -315,7 +315,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "rism", "area": 27575 @@ -451,7 +451,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "rism", "area": 236950 diff --git a/backend/test/lib/robots/dreame/res/map/d9_1058_with_custom_named_segments.json b/backend/test/lib/robots/dreame/res/map/d9_1058_with_custom_named_segments.json index 38cbcfc0..e90917b4 100644 --- a/backend/test/lib/robots/dreame/res/map/d9_1058_with_custom_named_segments.json +++ b/backend/test/lib/robots/dreame/res/map/d9_1058_with_custom_named_segments.json @@ -2539,7 +2539,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "regular", "area": 84775 @@ -2879,7 +2879,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "regular", "name": "Bad", @@ -3013,7 +3013,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "regular", "name": "Flur", @@ -3201,7 +3201,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 4, + "segmentId": "4", "active": false, "source": "regular", "area": 81400 @@ -3721,7 +3721,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 5, + "segmentId": "5", "active": false, "source": "regular", "area": 50175 @@ -4001,7 +4001,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 6, + "segmentId": "6", "active": true, "source": "regular", "area": 97050 diff --git a/backend/test/lib/robots/dreame/res/map/d9_1058_with_segments.json b/backend/test/lib/robots/dreame/res/map/d9_1058_with_segments.json index c18a25f6..8c7d70fe 100644 --- a/backend/test/lib/robots/dreame/res/map/d9_1058_with_segments.json +++ b/backend/test/lib/robots/dreame/res/map/d9_1058_with_segments.json @@ -2725,7 +2725,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "regular", "area": 24475 @@ -2954,7 +2954,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "regular", "area": 359975 diff --git a/backend/test/lib/robots/dreame/res/map/d9_1093_huge.json b/backend/test/lib/robots/dreame/res/map/d9_1093_huge.json index f9d2559c..3d72cca6 100644 --- a/backend/test/lib/robots/dreame/res/map/d9_1093_huge.json +++ b/backend/test/lib/robots/dreame/res/map/d9_1093_huge.json @@ -12572,7 +12572,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "regular", "area": 191500 @@ -13002,7 +13002,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "regular", "area": 133025 @@ -13408,7 +13408,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "regular", "area": 260725 @@ -14330,7 +14330,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 4, + "segmentId": "4", "active": false, "source": "regular", "area": 287425 @@ -15354,7 +15354,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 5, + "segmentId": "5", "active": false, "source": "regular", "area": 38475 @@ -15592,7 +15592,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 6, + "segmentId": "6", "active": false, "source": "regular", "area": 180225 @@ -16244,7 +16244,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 7, + "segmentId": "7", "active": false, "source": "regular", "area": 35475 @@ -16449,7 +16449,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 8, + "segmentId": "8", "active": false, "source": "regular", "area": 235075 @@ -17218,7 +17218,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 9, + "segmentId": "9", "active": false, "source": "regular", "area": 180025 @@ -17828,7 +17828,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 10, + "segmentId": "10", "active": false, "source": "regular", "area": 126125 @@ -18468,7 +18468,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 11, + "segmentId": "11", "active": false, "source": "regular", "area": 400775 @@ -19771,7 +19771,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 12, + "segmentId": "12", "active": false, "source": "regular", "area": 112375 @@ -20246,7 +20246,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 13, + "segmentId": "13", "active": false, "source": "regular", "area": 208400 @@ -21027,7 +21027,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 14, + "segmentId": "14", "active": false, "source": "regular", "area": 107700 diff --git a/backend/test/lib/robots/dreame/res/map/d9_1093_multi_map.json b/backend/test/lib/robots/dreame/res/map/d9_1093_multi_map.json index 6a549fc5..38fa0eaa 100644 --- a/backend/test/lib/robots/dreame/res/map/d9_1093_multi_map.json +++ b/backend/test/lib/robots/dreame/res/map/d9_1093_multi_map.json @@ -2803,7 +2803,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "rism", "area": 27225 @@ -5005,7 +5005,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "rism", "area": 53400 @@ -9301,7 +9301,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "rism", "name": "Flur", @@ -13116,7 +13116,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 4, + "segmentId": "4", "active": false, "source": "rism", "area": 105500 @@ -21580,7 +21580,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 5, + "segmentId": "5", "active": false, "source": "rism", "area": 99100 @@ -29532,7 +29532,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 6, + "segmentId": "6", "active": false, "source": "rism", "area": 94775 @@ -37138,7 +37138,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 7, + "segmentId": "7", "active": false, "source": "rism", "area": 12725 diff --git a/backend/test/lib/robots/dreame/res/map/l10su_1058_goto_target.bin b/backend/test/lib/robots/dreame/res/map/l10su_1058_goto_target.bin new file mode 100644 index 00000000..54cc20c1 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/l10su_1058_goto_target.bin @@ -0,0 +1 @@ +eF7tmsmO6tp6x0tRImWQwR3sJ6hxWXKPfaQMaIzBGEzfXR0hwBhswA2YNrrKLI-QJ8lr5EkyziQq6cZeNtheNl01e9c5qt_RheW1Pn_f_-_VQHH3Pzz901Pxv_7vP__eePr7v7v_4U___fQfT3_5X_F_nn4NrzeB7_j1JItzrv5yiw9wEyp-AfiOKzjRPwL8m93X21YcXkHoewhXT-D1xyPpY8mAGeeZ32fGCXukWpxYfZhHHlYsmWfmAR4olkCsfoz788dz_WwzroK4ihC385_2VmTHnO_9iWYAMRFhbub3PPjHRWDId_gVzZye_rkZAr4j4KuagZp38OodhV_LjIu_t67ORKzfve8NZs4z7gJLvclFeR6vQJbfeozHzbiEr2GtN7lD431mnvw4p_X65L49bMblrWa8ibyl0RUFjASBSbe48n0zJ09vMhPmITPePggEXee6mRCn4SQzT-ELeNDnvNgeNHOb04Z5_Rgz0T0RagcAL8D0n8FM0IIVX-GGJo8kC0k3hpbrNTMRwOl1XlTnzqAJK75CkqYYcY0faOYkJOomaIXV3iBJU4y4xmQzIR42E406XTx9opmER3-BjzLz0DeAG5o8QmYCwgFx3msGXL0-ZMVdqhENSYSEg8ZlM-Az3-PdZgAhoXeRJCoKbOYyoeH7zZwkR6N8M76pe229xr4BnL-JwB2fYuY8NwlRwY86YTNX3IHesAo30GsEfbFGMj_JDNwBERb-6v8ZFpqveCOZTzMTmYhbZiJT41-c3t2m23Jf3mjGJSwyytkMHOY-12iMF-h23mfmCfxN6e6kDzMDCoRVRvH2AFje0bALZm5-_wxkeI8SfFgFZmKNZN5m5oxrJ9rxuJmI7nN1d-DcF2skc82MR0jpHSTvmStmXt1FFTbjT7g7EvSdGqeeZK6Y8YuFpd7mbD-aJd7jA3RGvgeAvQEWW6gPer9A0h3RahGtt_HNQJ8qoCvS45Mgz_tLPmoQer9A0h3RalGtdwC2EaTcdXivGYC7-kJX0PsFPsVMiFOWi2aiqk9AXn6dGdfOueVnCbdhbij8EVJ2I_RTzAT8ucz4pyxoR_IG3FD44-uYOe0gtx3JG3BD4Q_XxAl4JMptM49-bF7kJCiS3q0QSLjAvWZCbk6hcLWPMuMTcxNTeLkjNnIZ302sGCznncTyQzLiPGAGnrxYMVjNO4nlj5ZP4F4zT1_ADLQdQr-x-NxrBnbi9sDFYDXvBM7vETIT03ThG8DluFAXXAZW8xbcZ39qQvk9fB2unpimCzMTi0sALvYRZsAfYKc2lN8jZCbGBTP3ABf7EDNeqnAb4prO09jVoGTgYh9nBvx_UbE96XFN54U9cw9wsY8zA_4QgNP7XF1mXu_tbwBx4Gqv8I8WHqdvGPfhpwK_XiRy1Yx_fF-dvmQSyiVNTkLYQ0BGr-kMQuGRmySo_BQz0XqBYIf456bLg1ZAmgSVP8FM4lCUZIsXAfMYT_5FzLyFePJvM7d4zMyrv2weJZ488c_NhLCHeMzMjyQz8Z4Y8eRPSXOTGPYAt83c1HozICn5B88MOHw_wkyM-B3x5Anz8i4zbtWgbjxRWNJD5_GvMRP-AAx_WnpJY5Iu4_1Dp0uOTwkjfLyZC_iW4O6HiNyeoPKnmfkI_lRmIiSo_MOaSRL55zZzPnjewieb8fdM6HSMEjcDRzzCTzGT6APwhzIDuOzlD2fGX1_xZQaW3j9CXFiO9_HpZoA2IBsWGTPiA8fdz08x400ALPILmHn4C855McEif72ZV_df18Cd1zltDFjkrzYDZuXBqbko8heb8YMfchMSCRMMRXi7macH1wzAVQL3XSIk8pJ6iNPx9zhvMvPI3MBSbwPM_MsbeMvv3y5X7ooahZXewXvMPPCUz0RvimaA8sFSbwNWDCz0Hvz1GSl_B9fMRIGV3gWs8k68k-OCmCsiL4-EgUXeC6zyTnwzydoudLtcHgGAYVji_cAq7-TqzFzh-h3uKoQFPgKs8k7ebObynnkF_5z4zs-UZGCVd_JGM9cOAO_T611uYJV38lYz1z6ivV0IC3wEWOV1Xp_ODVD6nx_k1ten93l5zMzrp5uB5T1GROwtXC3g_fTjOCz2Fmcz0Oo6d8PyHgOWe_X7gG_mLOCNZhwHcNcpISzvftwVCst1iDg6t0H_K_gm924z8a5TQljiVSI7LMmMk_CiGeDVj_Jqhx9xQHKvi3-aQX0fZCa2qoCZm4SWfkSXT3KvCzDyYWYgvC0IAUuPE5iJyLpNUvzHmQklumtOAMEJlCTuUX6dmciW8e96guU9xtvNwHsmlMjdAbD2GAlm3js9H2UmlMbLdSfQXbC8x7hpBq5-gVCad_CpZj5O5n18rpnQ6M_g20zAt5lP49tMQMRMzM0f2EzCJ1149CfwkWZ-Od9mAr7NfBrfZgK-zXwa32YCvs18Gt9mAoCZc-MXc_n3y_v4WmZgdQ9y_t3tT2HmlOCPb-Y1WKVfwsy7CP2W_hXMvI-zlW8zX4w_lZmQm28zX4xvM1-W82cOPPDT-LdnW11O1vZwaQ6W6-ffMJqmUIbGcAylmZfnpa3Kz789U5MhTWDYeCSTQ-L55XnsRKIvz8p66dzhRK2G4NpeObENknihMRHBCAp9QTCKdeKH6sAYOUXGi8nzb3_9HXQom5Wu2pvVZLAbOi19-vwbHh1wQv9KECnqBcEpnHrBXsgXnHYaCAEuKRR9wVEU_f3lrzgLulHnlXjBT1Gk8-q4eWG8GAZ0Ys4r4-QKZSLRUwyCYaCc--oGOSa88qlIlJsYIUmnk3bqISAxhbuJnRhX1--eRWNjj4yVPFmtXSsInnKTgUCvzTj_cxNiNKjivIDWqRt3G16818Rcte4ICcSDS6_p3gukhWqEbg-yhe45ZwvKJyVzb4vI8sLZU7en2y3gPn4vq9cEIYEoEgUCgAzQDo2BJxx-2nDCQLw7EkiAKrndZ8FeKzYXA1yOTAeo6bbdLMHTBV3-k3J1hUf8gdMNNFgQIJPXJN1V5o6kgkuvCbIGIyDzaQSawnM20AzqhLKd64QkQ3VCDkIlo2aSBLjeIib9mfO2mt8-z4e7F7zH7bZO0-HtMSDfa2Ip_wbfJAFevWSgHV4S4UJuOzrBQUVgBeRxnXlNUNKf-eCg0Sc7cKaADUu6KwecKd6lW9Q9TrwN_OKcPG43OCBSzpkCDg5PpHsSeDG0FwMeuxNDgxiQOIhBPKm4uw_dwyn87NzzwjmhgGlw8oAjyz1T_A0BDqJAUwosVtch60in3ecMnoF7ypHesWMaqm6rumI8_-ac7eAKrHaMIBg3IfOCOtP5-99enlfGyLAHS0N2DlqccK7VNTiCnXfnWH-e5FP2spLf4Mdea2Z3NkpPlhHW4EdlGUe1Y4ad9nJTVTTaq_FunVvklxY5UhdUMW-zu2aqsCIme3VXqElCv8DUW8t5Pbc40FOkWBO4FtJF1HrORvLzbl3bF46K0twqRzZ_QNRtg6sNBkIVETvbqp5bHA9WXSLzbZYrYtPUYWSt5pgiZXJldSgjeC9b5cgU11rV0qVxg5jrYnewzJZKGikKDaNbT9X5TrtRHJEdOtPNWO1BqcGZ7VWRUfSVmuU4crhDJ2Zrq1Ek1VFl3JYFMttaaIjITWptvjxWZYqzjLmRmuCHKTIzK9wB57Q8ls-vU0uBaZoLqoBaB7ZU5EW-KZfzVv5oUHSbsTeaShO62q3ORoxe09hCWiLQY96qNrNTe19t7MeLIidQW1TV89llemcSO4Wiy0pFVY6KXChVpv3jXNvnzUOqp3OHUrW-XY3RVN1SpmnLLNON4Vht9Ax7blbQ0ryk49kiVR-OD3LRqMwNfrzZ7InMEJO0VF1KH9ft5a6BN6qC3Gp0Nu18rcZni7tVK7VoWPXeii63mC2-R1tLxsxW-HI93yNbFCnQh11NqPBcqyfsrTJZ7hKTJT-ctyhjUG4PWy0CJbrDfKPXkacmcqg0tx1O2C7E44FFsks0P5uXFrspxWd7fcbObyardImQOyY23yJ0ltw1tIogpBe8zHSrWa7ImXq2YS7lRl9Op_VpvStlCsVD3dI7y_S03Gu1p7OmlNGFmZovpeqzXYubTWflUnaMDEtlVNotyy0QY8-cPPkZRuPFY4bP97h2yjh2rJqc0RVVbiy7fT4zrvMlqbRLm8RUM5xn02lrXa4-bfJWtmpp0-Ngui8sskWpWz4e0Mq0ucj2tBXWHc5LcruYHZP1ea80oftYZqqZ2bGuHMzxfnWwBnNNas05c6rnilyKUtZUnq-w6Z5g7HISP6_qy5HeSpn4eM2yYrE97XDZcl9tdi0q08tMc67nnLRvsZQuVnJUChmmenhpwlsLydof1sZ2Y5G7SbVo4RkyTeZnclWUq8asuemU-xV-eKzN5PZKtXLMqi4zKyvd1NrV7qEt80R9W5qNzWxzYVNU2-irU91eF61eH8U3lfauOetzx1Ej02a26qIk1lSaly1uibHD3mFTwGdpbSngS11cTDOtjMakpHE1ZWO55mJm02ibxNmJbDQ3u8wYt1VUamR2RVOT7GW9Z2mr6Thb2hOTRrZ0NLTtokzRNYPlBdJMkUVyV9OrKKpPU5WmvKtL1WymipYXtpbKMHulnyfLh5xRGKj8sN4WJkdVY3LmjMlaO6whr7lxIVMmB-lquyQg6_liUiRn1kIjZ4u0LOeqPMkJtXV1yw2VwirTUQrSUdfG6fKuwy062HBjF3PsNsP1is1ZluKYXt_sYO1RVqnsitqsJDPDTs4yZgaVbkza-bHIN9aV6YCjhpg5Iyq9tlXWpgsBU4q0nBXmTZvFyMJML9b3M4OTaYnl-OxyzJWHwrjWn5L6SJUKm3K5xIizfhXdqbnZrpyRevlZoSscLdokMqsS5SyHcVlgjg0e5QpNyZBmenveysp0vcnrub3WmfcpaadpmfKeF_hClZ7yTq2J3Fo3cxIiMuJRmudmeme-wsq5Ct-083tGL_O7IzUebqVDt6q0lqiFE9yyUqxWu1yq2Ecbtcx6vzfrCF3UR4d2s1SbLxs9qYebgrQQVYVfFOjeUt4WdblOdNKjht2pYKhVV5vSvGCqI3SFbqxmsZVTjmtU6xjd0povcdvlrjdsDcvlYUuZNQS5RtGb5mFW26ZsrlTbdRvbdY1gebNu7Nza-eJczC1ms0x_t-vO1kJ7lp3pvIj0FnT60NlmZuQALxePRrM51RGN6RZTk2xjwRfsoVE7GAuklzOnpNqTGEtdinu12sJ39HDcGua2JcNUBxm1QnLjTUk58vWyOOIzisw2UUqe1vnBWJdmhXJ6c1B7JDMV-4ItVIm2LXUFQasv0J6-aKcw3jTSPIYc57jB8NP5kpWUtZyuNZqSVsUn86ITW9NpZdPmWljBQDluYGnOI8xlMlW6fKR1Q0Co3o7TJnoFl6bF3jpd1saooSKjiiAyoyVb3QvStquncjUyOxmtdrY6RlZsxSCcFcNte1kB3fXSMk9R9WltiTTWTR1T6Cpv7hv7doPdbXMVfaviSLOQGlRFHSlvF5jNstJqyU6aB4XAMWbSl5bEZse2kJwlK6I2StVZHCFkYr0pVFLb0QZlqlV5IG_twVhZ09YIV8TDWMPlVV8RU2VtYSH77UA36TU7q-2OxdS4tDS6CyHDmkp-3zWc3dMb8Ual2u_zG7PWZ3Mb7FDpm3izuRwubRLn89hyL4hyd99tlzW5Us6yhUWruzHmJZuaHdI9ItMfYpvNZoKroiSlS9oBs9LTHYd1utNO17TbB1GmBhs2tSk0BxN0mht3kVYNJQo1rDsS8Uwf2VCDyhrN6cq6LY-bzcq4Kcj5FdbGidJRRw_bPkUaqzyr70szW-TxOSYOVuX8dDPRjFSroSitiV1Ir9mWZbH7OcNgZC9PsysBOxpj3Va2m_5opK1UvXTQmocF4swfYwsmtdjzG2a_lqrieqqb9Yy90IsDuyYo3f44w0w61U5fbGjqiNMFWhzNS4xBzClhyZKj7qJPUH0zX9muM0wWaywbhIn3V_XOKiUaPGbyXa1Bbw8bkZHGRKejDxS9xOociYzsgdJfMqNtfyxK2pFBGvkRTm_NvigPNgNMc-bN-UY1GhETYjPqDkVxJY7WVp-QS21atFA2z9ZXVteyVyJGrkSnMcrhhxlZoHU5M1BqwlZPsQW2siIy3L8-_-3_AS7pi28= \ No newline at end of file diff --git a/backend/test/lib/robots/dreame/res/map/l10su_1058_goto_target.json b/backend/test/lib/robots/dreame/res/map/l10su_1058_goto_target.json new file mode 100644 index 00000000..fc20a601 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/l10su_1058_goto_target.json @@ -0,0 +1,4089 @@ +{ + "__class": "ValetudoMap", + "metaData": { + "version": 2 + }, + "size": { + "x": 6554, + "y": 6554 + }, + "pixelSize": 5, + "layers": [ + { + "__class": "MapLayer", + "metaData": { + "segmentId": "1", + "active": false, + "source": "regular", + "area": 39575 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 686, + "max": 747, + "mid": 717, + "avg": 716 + }, + "y": { + "min": 654, + "max": 690, + "mid": 672, + "avg": 673 + }, + "pixelCount": 1583 + }, + "compressedPixels": [ + 687, + 654, + 16, + 686, + 655, + 17, + 686, + 656, + 17, + 686, + 657, + 17, + 686, + 658, + 17, + 686, + 659, + 17, + 686, + 660, + 17, + 686, + 661, + 20, + 686, + 662, + 45, + 733, + 662, + 11, + 686, + 663, + 45, + 733, + 663, + 11, + 686, + 664, + 60, + 686, + 665, + 60, + 686, + 666, + 60, + 686, + 667, + 45, + 733, + 667, + 11, + 686, + 668, + 45, + 733, + 668, + 11, + 746, + 668, + 2, + 686, + 669, + 58, + 746, + 669, + 2, + 686, + 670, + 62, + 686, + 671, + 62, + 687, + 672, + 61, + 688, + 673, + 60, + 689, + 674, + 59, + 688, + 675, + 60, + 688, + 676, + 60, + 690, + 677, + 58, + 692, + 678, + 56, + 695, + 679, + 53, + 696, + 680, + 50, + 695, + 681, + 51, + 696, + 682, + 50, + 696, + 683, + 10, + 708, + 683, + 38, + 696, + 684, + 10, + 723, + 684, + 23, + 697, + 685, + 9, + 723, + 685, + 23, + 700, + 686, + 6, + 723, + 686, + 23, + 701, + 687, + 5, + 723, + 687, + 23, + 702, + 688, + 4, + 723, + 688, + 23, + 705, + 689, + 1, + 723, + 689, + 23, + 727, + 690, + 16 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "2", + "active": false, + "source": "regular", + "area": 57425 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 605, + "max": 681, + "mid": 643, + "avg": 642 + }, + "y": { + "min": 629, + "max": 672, + "mid": 651, + "avg": 653 + }, + "pixelCount": 2297 + }, + "compressedPixels": [ + 673, + 629, + 9, + 673, + 630, + 9, + 672, + 631, + 10, + 672, + 632, + 10, + 671, + 633, + 11, + 671, + 634, + 11, + 671, + 635, + 11, + 671, + 636, + 1, + 673, + 636, + 9, + 610, + 637, + 61, + 674, + 637, + 8, + 610, + 638, + 63, + 675, + 638, + 7, + 610, + 639, + 63, + 675, + 639, + 7, + 611, + 640, + 62, + 678, + 640, + 4, + 611, + 641, + 62, + 678, + 641, + 4, + 611, + 642, + 62, + 611, + 643, + 62, + 611, + 644, + 62, + 611, + 645, + 62, + 611, + 646, + 62, + 611, + 647, + 62, + 611, + 648, + 62, + 611, + 649, + 62, + 611, + 650, + 62, + 611, + 651, + 62, + 611, + 652, + 62, + 611, + 653, + 62, + 611, + 654, + 62, + 611, + 655, + 62, + 611, + 656, + 62, + 611, + 657, + 62, + 611, + 658, + 62, + 611, + 659, + 62, + 611, + 660, + 62, + 611, + 661, + 62, + 611, + 662, + 62, + 611, + 663, + 62, + 606, + 664, + 67, + 606, + 665, + 47, + 654, + 665, + 19, + 607, + 666, + 20, + 629, + 666, + 24, + 656, + 666, + 2, + 660, + 666, + 13, + 607, + 667, + 20, + 629, + 667, + 24, + 660, + 667, + 13, + 605, + 668, + 48, + 660, + 668, + 12, + 605, + 669, + 48, + 662, + 669, + 10, + 605, + 670, + 48, + 605, + 671, + 48, + 605, + 672, + 48 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "3", + "active": false, + "source": "regular", + "area": 24000 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 748, + "max": 802, + "mid": 775, + "avg": 775 + }, + "y": { + "min": 663, + "max": 682, + "mid": 673, + "avg": 673 + }, + "pixelCount": 960 + }, + "compressedPixels": [ + 762, + 663, + 33, + 796, + 663, + 4, + 761, + 664, + 34, + 796, + 664, + 4, + 761, + 665, + 39, + 767, + 666, + 34, + 748, + 667, + 15, + 767, + 667, + 34, + 748, + 668, + 15, + 767, + 668, + 1, + 770, + 668, + 10, + 782, + 668, + 7, + 791, + 668, + 3, + 797, + 668, + 4, + 748, + 669, + 15, + 767, + 669, + 1, + 770, + 669, + 10, + 782, + 669, + 7, + 791, + 669, + 1, + 797, + 669, + 3, + 748, + 670, + 15, + 765, + 670, + 28, + 797, + 670, + 3, + 748, + 671, + 45, + 797, + 671, + 4, + 748, + 672, + 45, + 796, + 672, + 7, + 748, + 673, + 46, + 796, + 673, + 7, + 748, + 674, + 55, + 748, + 675, + 55, + 748, + 676, + 55, + 748, + 677, + 55, + 748, + 678, + 55, + 748, + 679, + 55, + 751, + 680, + 52, + 751, + 681, + 52, + 751, + 682, + 52 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "4", + "active": false, + "source": "regular", + "area": 78325 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 712, + "max": 802, + "mid": 757, + "avg": 747 + }, + "y": { + "min": 691, + "max": 760, + "mid": 726, + "avg": 729 + }, + "pixelCount": 3133 + }, + "compressedPixels": [ + 727, + 691, + 16, + 727, + 692, + 16, + 727, + 693, + 16, + 727, + 694, + 16, + 727, + 695, + 19, + 727, + 696, + 19, + 727, + 697, + 19, + 727, + 698, + 19, + 727, + 699, + 19, + 727, + 700, + 19, + 727, + 701, + 19, + 729, + 702, + 17, + 729, + 703, + 17, + 729, + 704, + 17, + 727, + 705, + 19, + 727, + 706, + 19, + 727, + 707, + 19, + 727, + 708, + 19, + 727, + 709, + 19, + 727, + 710, + 19, + 727, + 711, + 19, + 724, + 712, + 67, + 799, + 712, + 2, + 724, + 713, + 67, + 797, + 713, + 1, + 799, + 713, + 3, + 724, + 714, + 67, + 798, + 714, + 5, + 724, + 715, + 67, + 796, + 715, + 7, + 724, + 716, + 68, + 796, + 716, + 7, + 724, + 717, + 79, + 724, + 718, + 79, + 724, + 719, + 79, + 724, + 720, + 79, + 724, + 721, + 78, + 724, + 722, + 71, + 722, + 723, + 61, + 784, + 723, + 1, + 792, + 723, + 3, + 722, + 724, + 61, + 791, + 724, + 4, + 722, + 725, + 61, + 791, + 725, + 4, + 722, + 726, + 51, + 775, + 726, + 8, + 791, + 726, + 4, + 722, + 727, + 49, + 793, + 727, + 2, + 722, + 728, + 49, + 774, + 728, + 2, + 793, + 728, + 2, + 722, + 729, + 47, + 772, + 729, + 4, + 791, + 729, + 4, + 722, + 730, + 46, + 772, + 730, + 5, + 791, + 730, + 4, + 722, + 731, + 46, + 771, + 731, + 6, + 791, + 731, + 4, + 716, + 732, + 35, + 755, + 732, + 13, + 771, + 732, + 7, + 791, + 732, + 4, + 716, + 733, + 26, + 755, + 733, + 12, + 771, + 733, + 7, + 791, + 733, + 4, + 716, + 734, + 26, + 750, + 734, + 1, + 755, + 734, + 12, + 771, + 734, + 7, + 792, + 734, + 3, + 712, + 735, + 30, + 750, + 735, + 18, + 771, + 735, + 6, + 791, + 735, + 4, + 712, + 736, + 30, + 750, + 736, + 18, + 771, + 736, + 7, + 791, + 736, + 4, + 712, + 737, + 30, + 750, + 737, + 18, + 771, + 737, + 7, + 712, + 738, + 28, + 750, + 738, + 13, + 712, + 739, + 28, + 750, + 739, + 12, + 712, + 740, + 28, + 750, + 740, + 12, + 764, + 740, + 4, + 712, + 741, + 28, + 750, + 741, + 12, + 763, + 741, + 7, + 712, + 742, + 28, + 750, + 742, + 12, + 763, + 742, + 7, + 771, + 742, + 1, + 712, + 743, + 28, + 750, + 743, + 12, + 763, + 743, + 9, + 712, + 744, + 28, + 749, + 744, + 12, + 763, + 744, + 9, + 712, + 745, + 15, + 729, + 745, + 11, + 741, + 745, + 21, + 763, + 745, + 9, + 712, + 746, + 15, + 729, + 746, + 11, + 741, + 746, + 21, + 766, + 746, + 1, + 768, + 746, + 4, + 712, + 747, + 15, + 728, + 747, + 12, + 741, + 747, + 22, + 767, + 747, + 5, + 712, + 748, + 60, + 712, + 749, + 48, + 761, + 749, + 11, + 712, + 750, + 44, + 761, + 750, + 11, + 712, + 751, + 44, + 712, + 752, + 44, + 712, + 753, + 44, + 712, + 754, + 44, + 712, + 755, + 44, + 712, + 756, + 44, + 712, + 757, + 44, + 712, + 758, + 1, + 716, + 758, + 36, + 755, + 758, + 1, + 716, + 759, + 36, + 718, + 760, + 33 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "5", + "active": false, + "source": "regular", + "area": 175900 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 600, + "max": 706, + "mid": 653, + "avg": 657 + }, + "y": { + "min": 673, + "max": 759, + "mid": 716, + "avg": 714 + }, + "pixelCount": 7036 + }, + "compressedPixels": [ + 605, + 673, + 48, + 605, + 674, + 48, + 656, + 674, + 11, + 669, + 674, + 12, + 605, + 675, + 49, + 656, + 675, + 11, + 669, + 675, + 12, + 683, + 675, + 1, + 605, + 676, + 49, + 655, + 676, + 29, + 687, + 676, + 1, + 606, + 677, + 21, + 629, + 677, + 25, + 655, + 677, + 30, + 686, + 677, + 4, + 605, + 678, + 22, + 629, + 678, + 25, + 655, + 678, + 37, + 605, + 679, + 48, + 656, + 679, + 11, + 669, + 679, + 26, + 603, + 680, + 50, + 656, + 680, + 11, + 669, + 680, + 12, + 683, + 680, + 13, + 601, + 681, + 53, + 655, + 681, + 26, + 683, + 681, + 12, + 601, + 682, + 52, + 655, + 682, + 41, + 601, + 683, + 51, + 656, + 683, + 40, + 600, + 684, + 44, + 645, + 684, + 6, + 653, + 684, + 43, + 600, + 685, + 45, + 647, + 685, + 3, + 652, + 685, + 45, + 600, + 686, + 47, + 649, + 686, + 1, + 652, + 686, + 46, + 600, + 687, + 48, + 651, + 687, + 46, + 600, + 688, + 96, + 600, + 689, + 96, + 600, + 690, + 97, + 600, + 691, + 99, + 600, + 692, + 94, + 696, + 692, + 4, + 600, + 693, + 94, + 696, + 693, + 5, + 600, + 694, + 106, + 600, + 695, + 106, + 600, + 696, + 107, + 600, + 697, + 94, + 696, + 697, + 11, + 600, + 698, + 26, + 633, + 698, + 61, + 696, + 698, + 11, + 600, + 699, + 3, + 604, + 699, + 10, + 633, + 699, + 42, + 676, + 699, + 1, + 678, + 699, + 3, + 682, + 699, + 23, + 600, + 700, + 2, + 606, + 700, + 8, + 633, + 700, + 11, + 645, + 700, + 44, + 691, + 700, + 16, + 606, + 701, + 8, + 633, + 701, + 6, + 641, + 701, + 48, + 691, + 701, + 16, + 606, + 702, + 8, + 633, + 702, + 6, + 641, + 702, + 31, + 674, + 702, + 33, + 606, + 703, + 8, + 633, + 703, + 21, + 656, + 703, + 16, + 674, + 703, + 33, + 606, + 704, + 8, + 633, + 704, + 18, + 652, + 704, + 2, + 656, + 704, + 51, + 606, + 705, + 8, + 633, + 705, + 74, + 606, + 706, + 8, + 633, + 706, + 74, + 606, + 707, + 8, + 633, + 707, + 22, + 656, + 707, + 46, + 704, + 707, + 3, + 606, + 708, + 8, + 634, + 708, + 21, + 656, + 708, + 46, + 705, + 708, + 2, + 621, + 709, + 27, + 658, + 709, + 49, + 621, + 710, + 6, + 629, + 710, + 19, + 658, + 710, + 49, + 621, + 711, + 6, + 629, + 711, + 19, + 651, + 711, + 4, + 658, + 711, + 49, + 621, + 712, + 27, + 650, + 712, + 7, + 658, + 712, + 49, + 621, + 713, + 27, + 649, + 713, + 7, + 658, + 713, + 49, + 621, + 714, + 6, + 629, + 714, + 19, + 649, + 714, + 8, + 658, + 714, + 49, + 621, + 715, + 6, + 629, + 715, + 2, + 633, + 715, + 15, + 649, + 715, + 8, + 658, + 715, + 13, + 673, + 715, + 34, + 621, + 716, + 9, + 633, + 716, + 15, + 650, + 716, + 7, + 658, + 716, + 13, + 673, + 716, + 15, + 690, + 716, + 17, + 621, + 717, + 9, + 631, + 717, + 17, + 649, + 717, + 8, + 658, + 717, + 30, + 690, + 717, + 16, + 615, + 718, + 33, + 649, + 718, + 8, + 658, + 718, + 30, + 689, + 718, + 2, + 693, + 718, + 14, + 615, + 719, + 33, + 649, + 719, + 8, + 658, + 719, + 33, + 693, + 719, + 14, + 615, + 720, + 16, + 632, + 720, + 16, + 649, + 720, + 8, + 658, + 720, + 42, + 702, + 720, + 5, + 615, + 721, + 33, + 658, + 721, + 31, + 690, + 721, + 9, + 701, + 721, + 6, + 615, + 722, + 33, + 658, + 722, + 30, + 689, + 722, + 10, + 700, + 722, + 7, + 615, + 723, + 33, + 649, + 723, + 7, + 658, + 723, + 30, + 689, + 723, + 10, + 700, + 723, + 7, + 615, + 724, + 33, + 649, + 724, + 7, + 658, + 724, + 30, + 689, + 724, + 10, + 700, + 724, + 7, + 615, + 725, + 33, + 649, + 725, + 7, + 658, + 725, + 30, + 689, + 725, + 10, + 700, + 725, + 7, + 615, + 726, + 19, + 637, + 726, + 11, + 650, + 726, + 7, + 658, + 726, + 30, + 689, + 726, + 10, + 700, + 726, + 7, + 612, + 727, + 23, + 638, + 727, + 11, + 650, + 727, + 7, + 658, + 727, + 30, + 689, + 727, + 10, + 700, + 727, + 7, + 612, + 728, + 18, + 631, + 728, + 3, + 639, + 728, + 10, + 650, + 728, + 7, + 658, + 728, + 30, + 689, + 728, + 10, + 700, + 728, + 7, + 613, + 729, + 3, + 619, + 729, + 10, + 631, + 729, + 2, + 639, + 729, + 10, + 650, + 729, + 7, + 658, + 729, + 30, + 689, + 729, + 10, + 700, + 729, + 7, + 615, + 730, + 1, + 619, + 730, + 9, + 640, + 730, + 8, + 650, + 730, + 7, + 658, + 730, + 30, + 689, + 730, + 10, + 700, + 730, + 7, + 619, + 731, + 9, + 640, + 731, + 8, + 649, + 731, + 8, + 658, + 731, + 30, + 689, + 731, + 10, + 700, + 731, + 7, + 619, + 732, + 9, + 640, + 732, + 8, + 649, + 732, + 8, + 658, + 732, + 30, + 689, + 732, + 10, + 700, + 732, + 7, + 619, + 733, + 9, + 633, + 733, + 1, + 635, + 733, + 1, + 640, + 733, + 8, + 650, + 733, + 3, + 655, + 733, + 2, + 658, + 733, + 30, + 689, + 733, + 10, + 700, + 733, + 7, + 619, + 734, + 10, + 632, + 734, + 5, + 640, + 734, + 8, + 650, + 734, + 3, + 655, + 734, + 2, + 658, + 734, + 30, + 689, + 734, + 10, + 700, + 734, + 7, + 619, + 735, + 9, + 632, + 735, + 4, + 640, + 735, + 8, + 649, + 735, + 8, + 658, + 735, + 30, + 689, + 735, + 10, + 700, + 735, + 7, + 618, + 736, + 10, + 633, + 736, + 4, + 639, + 736, + 9, + 649, + 736, + 8, + 658, + 736, + 30, + 689, + 736, + 10, + 700, + 736, + 7, + 613, + 737, + 1, + 618, + 737, + 12, + 632, + 737, + 6, + 639, + 737, + 8, + 649, + 737, + 8, + 658, + 737, + 30, + 689, + 737, + 10, + 700, + 737, + 7, + 613, + 738, + 33, + 649, + 738, + 8, + 658, + 738, + 30, + 689, + 738, + 10, + 700, + 738, + 7, + 613, + 739, + 33, + 649, + 739, + 8, + 658, + 739, + 4, + 669, + 739, + 19, + 689, + 739, + 10, + 700, + 739, + 7, + 612, + 740, + 36, + 649, + 740, + 8, + 669, + 740, + 30, + 700, + 740, + 7, + 612, + 741, + 36, + 649, + 741, + 8, + 659, + 741, + 9, + 669, + 741, + 30, + 700, + 741, + 7, + 612, + 742, + 36, + 649, + 742, + 9, + 659, + 742, + 9, + 669, + 742, + 30, + 700, + 742, + 7, + 612, + 743, + 36, + 649, + 743, + 9, + 659, + 743, + 9, + 669, + 743, + 19, + 690, + 743, + 9, + 700, + 743, + 7, + 612, + 744, + 36, + 649, + 744, + 9, + 659, + 744, + 9, + 669, + 744, + 19, + 690, + 744, + 9, + 700, + 744, + 7, + 612, + 745, + 36, + 651, + 745, + 4, + 657, + 745, + 1, + 659, + 745, + 9, + 669, + 745, + 30, + 700, + 745, + 7, + 612, + 746, + 36, + 651, + 746, + 4, + 657, + 746, + 1, + 659, + 746, + 9, + 669, + 746, + 30, + 700, + 746, + 7, + 612, + 747, + 2, + 618, + 747, + 40, + 659, + 747, + 9, + 669, + 747, + 30, + 700, + 747, + 7, + 618, + 748, + 33, + 653, + 748, + 1, + 655, + 748, + 3, + 659, + 748, + 9, + 669, + 748, + 19, + 689, + 748, + 3, + 694, + 748, + 5, + 701, + 748, + 6, + 618, + 749, + 34, + 654, + 749, + 4, + 659, + 749, + 31, + 691, + 749, + 1, + 694, + 749, + 6, + 703, + 749, + 4, + 619, + 750, + 29, + 649, + 750, + 2, + 654, + 750, + 4, + 659, + 750, + 48, + 619, + 751, + 28, + 655, + 751, + 3, + 665, + 751, + 23, + 689, + 751, + 16, + 619, + 752, + 28, + 654, + 752, + 4, + 665, + 752, + 39, + 706, + 752, + 1, + 619, + 753, + 28, + 681, + 753, + 26, + 619, + 754, + 28, + 682, + 754, + 4, + 695, + 754, + 8, + 615, + 755, + 3, + 619, + 755, + 28, + 691, + 755, + 16, + 614, + 756, + 33, + 690, + 756, + 17, + 614, + 757, + 32, + 691, + 757, + 16, + 614, + 758, + 30, + 645, + 758, + 1, + 691, + 758, + 16, + 693, + 759, + 11 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "area": 35775 + }, + "type": "wall", + "pixels": [], + "dimensions": { + "x": { + "min": 599, + "max": 803, + "mid": 701, + "avg": 702 + }, + "y": { + "min": 636, + "max": 761, + "mid": 699, + "avg": 703 + }, + "pixelCount": 1431 + }, + "compressedPixels": [ + 609, + 636, + 64, + 607, + 637, + 3, + 672, + 637, + 2, + 606, + 638, + 2, + 673, + 638, + 2, + 606, + 639, + 1, + 674, + 639, + 1, + 606, + 640, + 2, + 674, + 640, + 1, + 605, + 641, + 3, + 674, + 641, + 1, + 605, + 642, + 1, + 674, + 642, + 1, + 605, + 643, + 1, + 674, + 643, + 1, + 605, + 644, + 1, + 674, + 644, + 1, + 605, + 645, + 1, + 608, + 645, + 2, + 674, + 645, + 1, + 605, + 646, + 1, + 608, + 646, + 2, + 674, + 646, + 1, + 674, + 647, + 1, + 674, + 648, + 1, + 674, + 649, + 1, + 607, + 650, + 3, + 674, + 650, + 1, + 607, + 651, + 1, + 674, + 651, + 1, + 607, + 652, + 1, + 674, + 652, + 1, + 607, + 653, + 1, + 674, + 653, + 1, + 685, + 653, + 19, + 607, + 654, + 1, + 674, + 654, + 1, + 685, + 654, + 1, + 703, + 654, + 1, + 607, + 655, + 1, + 674, + 655, + 1, + 685, + 655, + 1, + 703, + 655, + 1, + 607, + 656, + 1, + 674, + 656, + 1, + 685, + 656, + 1, + 703, + 656, + 1, + 607, + 657, + 1, + 674, + 657, + 1, + 685, + 657, + 1, + 703, + 657, + 1, + 607, + 658, + 1, + 674, + 658, + 1, + 685, + 658, + 1, + 703, + 658, + 1, + 607, + 659, + 3, + 674, + 659, + 1, + 685, + 659, + 1, + 703, + 659, + 1, + 609, + 660, + 1, + 674, + 660, + 1, + 685, + 660, + 1, + 703, + 660, + 10, + 674, + 661, + 1, + 685, + 661, + 1, + 712, + 661, + 23, + 739, + 661, + 2, + 750, + 661, + 45, + 796, + 661, + 6, + 674, + 662, + 1, + 685, + 662, + 1, + 745, + 662, + 2, + 750, + 662, + 1, + 761, + 662, + 1, + 780, + 662, + 2, + 790, + 662, + 1, + 794, + 662, + 3, + 801, + 662, + 1, + 608, + 663, + 2, + 674, + 663, + 1, + 685, + 663, + 1, + 746, + 663, + 1, + 750, + 663, + 1, + 761, + 663, + 1, + 795, + 663, + 1, + 801, + 663, + 1, + 608, + 664, + 2, + 674, + 664, + 1, + 685, + 664, + 1, + 750, + 664, + 1, + 795, + 664, + 1, + 801, + 664, + 1, + 606, + 665, + 3, + 674, + 665, + 1, + 685, + 665, + 1, + 746, + 665, + 2, + 750, + 665, + 2, + 801, + 665, + 1, + 604, + 666, + 2, + 653, + 666, + 1, + 674, + 666, + 1, + 685, + 666, + 1, + 746, + 666, + 14, + 801, + 666, + 2, + 604, + 667, + 1, + 653, + 667, + 2, + 658, + 667, + 1, + 674, + 667, + 1, + 685, + 667, + 1, + 764, + 667, + 1, + 802, + 667, + 1, + 604, + 668, + 2, + 627, + 668, + 1, + 653, + 668, + 6, + 674, + 668, + 1, + 685, + 668, + 1, + 768, + 668, + 1, + 780, + 668, + 2, + 790, + 668, + 1, + 794, + 668, + 3, + 801, + 668, + 2, + 604, + 669, + 1, + 653, + 669, + 1, + 658, + 669, + 1, + 673, + 669, + 2, + 685, + 669, + 1, + 768, + 669, + 2, + 780, + 669, + 2, + 790, + 669, + 1, + 794, + 669, + 1, + 796, + 669, + 1, + 800, + 669, + 2, + 603, + 670, + 2, + 653, + 670, + 1, + 658, + 670, + 1, + 673, + 670, + 1, + 685, + 670, + 1, + 794, + 670, + 1, + 801, + 670, + 3, + 603, + 671, + 1, + 653, + 671, + 1, + 658, + 671, + 16, + 685, + 671, + 1, + 794, + 671, + 1, + 803, + 671, + 1, + 603, + 672, + 1, + 653, + 672, + 1, + 685, + 672, + 1, + 794, + 672, + 2, + 803, + 672, + 1, + 603, + 673, + 1, + 653, + 673, + 29, + 686, + 673, + 2, + 794, + 673, + 2, + 803, + 673, + 1, + 603, + 674, + 1, + 653, + 674, + 2, + 667, + 674, + 2, + 681, + 674, + 4, + 687, + 674, + 1, + 803, + 674, + 1, + 603, + 675, + 1, + 654, + 675, + 1, + 667, + 675, + 2, + 681, + 675, + 2, + 684, + 675, + 1, + 686, + 675, + 2, + 803, + 675, + 1, + 603, + 676, + 1, + 684, + 676, + 3, + 803, + 676, + 1, + 603, + 677, + 1, + 685, + 677, + 1, + 803, + 677, + 1, + 603, + 678, + 2, + 627, + 678, + 2, + 803, + 678, + 1, + 603, + 679, + 2, + 803, + 679, + 1, + 599, + 680, + 5, + 654, + 680, + 1, + 667, + 680, + 2, + 746, + 680, + 5, + 803, + 680, + 1, + 599, + 681, + 1, + 681, + 681, + 1, + 746, + 681, + 1, + 750, + 681, + 1, + 803, + 681, + 1, + 599, + 682, + 1, + 746, + 682, + 1, + 750, + 682, + 1, + 803, + 682, + 1, + 599, + 683, + 1, + 746, + 683, + 1, + 750, + 683, + 54, + 599, + 684, + 1, + 706, + 684, + 2, + 709, + 684, + 14, + 746, + 684, + 1, + 599, + 685, + 1, + 706, + 685, + 2, + 722, + 685, + 1, + 746, + 685, + 1, + 599, + 686, + 1, + 698, + 686, + 2, + 722, + 686, + 1, + 746, + 686, + 1, + 599, + 687, + 1, + 697, + 687, + 4, + 706, + 687, + 1, + 722, + 687, + 1, + 746, + 687, + 1, + 599, + 688, + 1, + 697, + 688, + 1, + 700, + 688, + 2, + 706, + 688, + 1, + 722, + 688, + 1, + 746, + 688, + 1, + 599, + 689, + 1, + 696, + 689, + 3, + 701, + 689, + 4, + 706, + 689, + 1, + 722, + 689, + 1, + 746, + 689, + 1, + 599, + 690, + 1, + 698, + 690, + 2, + 704, + 690, + 3, + 722, + 690, + 5, + 743, + 690, + 4, + 599, + 691, + 1, + 699, + 691, + 2, + 726, + 691, + 1, + 743, + 691, + 1, + 599, + 692, + 1, + 700, + 692, + 2, + 726, + 692, + 1, + 743, + 692, + 1, + 599, + 693, + 1, + 701, + 693, + 6, + 726, + 693, + 1, + 743, + 693, + 2, + 599, + 694, + 1, + 706, + 694, + 2, + 726, + 694, + 1, + 744, + 694, + 3, + 599, + 695, + 1, + 707, + 695, + 1, + 726, + 695, + 1, + 746, + 695, + 1, + 599, + 696, + 1, + 707, + 696, + 1, + 726, + 696, + 1, + 746, + 696, + 1, + 599, + 697, + 1, + 707, + 697, + 1, + 726, + 697, + 1, + 746, + 697, + 1, + 599, + 698, + 1, + 694, + 698, + 1, + 707, + 698, + 1, + 726, + 698, + 1, + 746, + 698, + 1, + 599, + 699, + 1, + 630, + 699, + 1, + 705, + 699, + 3, + 726, + 699, + 1, + 746, + 699, + 1, + 599, + 700, + 1, + 624, + 700, + 8, + 689, + 700, + 1, + 707, + 700, + 1, + 726, + 700, + 1, + 746, + 700, + 1, + 599, + 701, + 1, + 602, + 701, + 3, + 619, + 701, + 6, + 631, + 701, + 1, + 689, + 701, + 1, + 707, + 701, + 1, + 726, + 701, + 1, + 746, + 701, + 1, + 599, + 702, + 4, + 604, + 702, + 1, + 614, + 702, + 6, + 631, + 702, + 1, + 707, + 702, + 1, + 726, + 702, + 1, + 746, + 702, + 1, + 604, + 703, + 2, + 614, + 703, + 1, + 631, + 703, + 1, + 707, + 703, + 1, + 726, + 703, + 1, + 746, + 703, + 1, + 604, + 704, + 2, + 614, + 704, + 1, + 631, + 704, + 1, + 707, + 704, + 1, + 726, + 704, + 1, + 746, + 704, + 1, + 604, + 705, + 1, + 614, + 705, + 1, + 631, + 705, + 2, + 707, + 705, + 1, + 726, + 705, + 1, + 746, + 705, + 1, + 604, + 706, + 1, + 614, + 706, + 1, + 628, + 706, + 5, + 707, + 706, + 1, + 725, + 706, + 2, + 746, + 706, + 1, + 604, + 707, + 1, + 614, + 707, + 1, + 626, + 707, + 3, + 707, + 707, + 1, + 725, + 707, + 1, + 746, + 707, + 1, + 604, + 708, + 2, + 614, + 708, + 1, + 620, + 708, + 7, + 707, + 708, + 1, + 725, + 708, + 1, + 746, + 708, + 1, + 797, + 708, + 3, + 605, + 709, + 10, + 619, + 709, + 2, + 707, + 709, + 1, + 725, + 709, + 1, + 746, + 709, + 1, + 795, + 709, + 3, + 799, + 709, + 1, + 619, + 710, + 1, + 648, + 710, + 9, + 707, + 710, + 1, + 723, + 710, + 3, + 746, + 710, + 1, + 799, + 710, + 2, + 619, + 711, + 2, + 648, + 711, + 3, + 655, + 711, + 2, + 707, + 711, + 1, + 723, + 711, + 1, + 725, + 711, + 1, + 746, + 711, + 46, + 795, + 711, + 1, + 800, + 711, + 3, + 619, + 712, + 1, + 649, + 712, + 1, + 707, + 712, + 1, + 723, + 712, + 1, + 791, + 712, + 1, + 802, + 712, + 2, + 619, + 713, + 1, + 707, + 713, + 1, + 723, + 713, + 1, + 791, + 713, + 1, + 803, + 713, + 1, + 619, + 714, + 2, + 707, + 714, + 1, + 723, + 714, + 1, + 791, + 714, + 1, + 803, + 714, + 1, + 620, + 715, + 1, + 707, + 715, + 1, + 723, + 715, + 1, + 791, + 715, + 2, + 795, + 715, + 1, + 803, + 715, + 1, + 620, + 716, + 1, + 707, + 716, + 1, + 723, + 716, + 1, + 792, + 716, + 4, + 803, + 716, + 1, + 614, + 717, + 7, + 707, + 717, + 1, + 723, + 717, + 1, + 803, + 717, + 1, + 614, + 718, + 1, + 707, + 718, + 1, + 723, + 718, + 1, + 803, + 718, + 1, + 614, + 719, + 1, + 707, + 719, + 1, + 723, + 719, + 1, + 803, + 719, + 1, + 614, + 720, + 1, + 707, + 720, + 1, + 723, + 720, + 1, + 803, + 720, + 1, + 614, + 721, + 1, + 707, + 721, + 1, + 723, + 721, + 1, + 802, + 721, + 2, + 613, + 722, + 1, + 648, + 722, + 1, + 652, + 722, + 2, + 707, + 722, + 1, + 721, + 722, + 3, + 795, + 722, + 8, + 613, + 723, + 1, + 648, + 723, + 1, + 707, + 723, + 1, + 721, + 723, + 1, + 783, + 723, + 1, + 786, + 723, + 6, + 795, + 723, + 1, + 613, + 724, + 1, + 707, + 724, + 1, + 721, + 724, + 1, + 783, + 724, + 4, + 789, + 724, + 1, + 795, + 724, + 1, + 613, + 725, + 1, + 648, + 725, + 1, + 707, + 725, + 1, + 721, + 725, + 1, + 783, + 725, + 1, + 795, + 725, + 1, + 611, + 726, + 1, + 613, + 726, + 1, + 648, + 726, + 1, + 707, + 726, + 1, + 721, + 726, + 1, + 783, + 726, + 1, + 795, + 726, + 1, + 611, + 727, + 1, + 707, + 727, + 1, + 721, + 727, + 1, + 777, + 727, + 2, + 782, + 727, + 2, + 791, + 727, + 1, + 795, + 727, + 1, + 611, + 728, + 1, + 649, + 728, + 1, + 707, + 728, + 1, + 721, + 728, + 1, + 777, + 728, + 6, + 795, + 728, + 1, + 611, + 729, + 1, + 649, + 729, + 1, + 707, + 729, + 1, + 721, + 729, + 1, + 777, + 729, + 1, + 795, + 729, + 1, + 611, + 730, + 1, + 707, + 730, + 1, + 721, + 730, + 1, + 777, + 730, + 2, + 795, + 730, + 1, + 611, + 731, + 7, + 707, + 731, + 1, + 715, + 731, + 7, + 778, + 731, + 1, + 795, + 731, + 1, + 707, + 732, + 1, + 715, + 732, + 1, + 752, + 732, + 3, + 778, + 732, + 1, + 795, + 732, + 1, + 617, + 733, + 2, + 707, + 733, + 1, + 711, + 733, + 3, + 715, + 733, + 1, + 742, + 733, + 11, + 754, + 733, + 1, + 778, + 733, + 1, + 795, + 733, + 1, + 617, + 734, + 2, + 707, + 734, + 1, + 711, + 734, + 1, + 713, + 734, + 3, + 742, + 734, + 1, + 749, + 734, + 1, + 752, + 734, + 3, + 778, + 734, + 1, + 795, + 734, + 1, + 612, + 735, + 1, + 707, + 735, + 1, + 711, + 735, + 1, + 742, + 735, + 1, + 749, + 735, + 1, + 778, + 735, + 1, + 788, + 735, + 1, + 795, + 735, + 1, + 611, + 736, + 2, + 617, + 736, + 1, + 648, + 736, + 1, + 707, + 736, + 1, + 711, + 736, + 1, + 742, + 736, + 1, + 749, + 736, + 1, + 778, + 736, + 1, + 788, + 736, + 1, + 795, + 736, + 1, + 611, + 737, + 1, + 707, + 737, + 1, + 711, + 737, + 1, + 742, + 737, + 1, + 749, + 737, + 1, + 778, + 737, + 1, + 788, + 737, + 2, + 795, + 737, + 1, + 611, + 738, + 1, + 647, + 738, + 2, + 707, + 738, + 1, + 711, + 738, + 1, + 740, + 738, + 3, + 749, + 738, + 1, + 772, + 738, + 7, + 789, + 738, + 7, + 611, + 739, + 1, + 647, + 739, + 2, + 707, + 739, + 1, + 711, + 739, + 1, + 740, + 739, + 2, + 749, + 739, + 1, + 772, + 739, + 1, + 611, + 740, + 1, + 707, + 740, + 1, + 711, + 740, + 1, + 741, + 740, + 1, + 749, + 740, + 1, + 772, + 740, + 1, + 611, + 741, + 1, + 707, + 741, + 1, + 711, + 741, + 1, + 740, + 741, + 2, + 749, + 741, + 1, + 772, + 741, + 1, + 611, + 742, + 1, + 707, + 742, + 1, + 711, + 742, + 1, + 740, + 742, + 1, + 749, + 742, + 1, + 772, + 742, + 1, + 611, + 743, + 1, + 707, + 743, + 1, + 711, + 743, + 1, + 740, + 743, + 2, + 748, + 743, + 2, + 772, + 743, + 1, + 611, + 744, + 1, + 707, + 744, + 1, + 711, + 744, + 1, + 741, + 744, + 8, + 772, + 744, + 1, + 611, + 745, + 1, + 655, + 745, + 2, + 707, + 745, + 1, + 711, + 745, + 1, + 727, + 745, + 2, + 740, + 745, + 1, + 772, + 745, + 1, + 611, + 746, + 1, + 649, + 746, + 2, + 655, + 746, + 2, + 707, + 746, + 1, + 711, + 746, + 1, + 727, + 746, + 2, + 740, + 746, + 1, + 772, + 746, + 1, + 611, + 747, + 1, + 707, + 747, + 1, + 711, + 747, + 1, + 740, + 747, + 1, + 772, + 747, + 1, + 611, + 748, + 1, + 707, + 748, + 1, + 711, + 748, + 1, + 772, + 748, + 1, + 611, + 749, + 2, + 692, + 749, + 2, + 707, + 749, + 1, + 711, + 749, + 1, + 772, + 749, + 1, + 612, + 750, + 6, + 652, + 750, + 2, + 707, + 750, + 1, + 711, + 750, + 1, + 756, + 750, + 5, + 772, + 750, + 1, + 617, + 751, + 1, + 648, + 751, + 1, + 651, + 751, + 4, + 707, + 751, + 1, + 711, + 751, + 1, + 756, + 751, + 1, + 760, + 751, + 13, + 617, + 752, + 1, + 648, + 752, + 4, + 653, + 752, + 1, + 659, + 752, + 6, + 705, + 752, + 1, + 707, + 752, + 1, + 711, + 752, + 1, + 756, + 752, + 1, + 617, + 753, + 1, + 648, + 753, + 1, + 653, + 753, + 2, + 659, + 753, + 1, + 664, + 753, + 1, + 707, + 753, + 1, + 711, + 753, + 1, + 756, + 753, + 1, + 611, + 754, + 2, + 617, + 754, + 1, + 647, + 754, + 2, + 654, + 754, + 6, + 664, + 754, + 18, + 693, + 754, + 1, + 704, + 754, + 1, + 707, + 754, + 1, + 711, + 754, + 1, + 756, + 754, + 1, + 611, + 755, + 1, + 647, + 755, + 2, + 681, + 755, + 1, + 707, + 755, + 1, + 711, + 755, + 1, + 756, + 755, + 1, + 611, + 756, + 1, + 648, + 756, + 1, + 681, + 756, + 9, + 707, + 756, + 1, + 711, + 756, + 1, + 756, + 756, + 1, + 611, + 757, + 2, + 647, + 757, + 2, + 690, + 757, + 1, + 707, + 757, + 1, + 711, + 757, + 1, + 756, + 757, + 1, + 612, + 758, + 2, + 646, + 758, + 2, + 690, + 758, + 1, + 707, + 758, + 1, + 711, + 758, + 1, + 713, + 758, + 3, + 752, + 758, + 3, + 756, + 758, + 1, + 613, + 759, + 5, + 646, + 759, + 1, + 690, + 759, + 2, + 706, + 759, + 2, + 711, + 759, + 3, + 715, + 759, + 1, + 752, + 759, + 1, + 754, + 759, + 3, + 617, + 760, + 30, + 691, + 760, + 16, + 715, + 760, + 1, + 752, + 760, + 1, + 715, + 761, + 38 + ] + } + ], + "entities": [ + { + "__class": "PointMapEntity", + "metaData": { + "angle": 7 + }, + "points": [ + 3141, + 3288 + ], + "type": "robot_position" + }, + { + "__class": "PointMapEntity", + "metaData": { + "angle": 2 + }, + "points": [ + 3279, + 3329 + ], + "type": "charger_location" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3281, + 3271, + 3146, + 3287 + ], + "type": "path" + }, + { + "__class": "PointMapEntity", + "metaData": {}, + "points": [ + 3143, + 3289 + ], + "type": "go_to_target" + } + ] +} \ No newline at end of file diff --git a/backend/test/lib/robots/dreame/res/map/l10su_1121_carpet.bin b/backend/test/lib/robots/dreame/res/map/l10su_1121_carpet.bin new file mode 100644 index 00000000..8c4c8192 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/l10su_1121_carpet.bin @@ -0,0 +1 @@ +eF7tmluP4kiahlOjkWYu5qKknYu-HOXtJi2fDS3NBeZ8JrE5tlqWbQwYG2OMjYFRa3_D_rD9JXu9dynNRoQBHzAkkFXZ1VK_pUrCn8MR7-P44rOTqj89_fefKtTTf_67__Tv_4J_iKf_efr16cv_1f_36TfQ202KX_WbK9nb25cb9GGY0Nxngifj_a8LXPD3k45Xo7HixpP0wIRRvf0AhH6cCYz9A2K6XSGUAAeAPMV9Jwoy3zNbXG_XYMDJN_gRv-iyYjAABwZ9q_9xXUeg-JB3yGdJhjnq9vHPWAKYuPczfS2YCytz1PvjH7bYU3jHQJJTmvksxwU6fB6Cx4Yff3-yy_Jz6PrSvDf-m8_gEx0ODgH__A3rgvRRGF-3wBychponBWsB9BRqh2G-oD-nVThEIgFIg5byMM9juspyhAnsnW8NX_F4eGVuWpwjDCxsJ3P36iaYUC7FTF-Uf4dvTrMQDCzTSBGfN-ntKQ4Q1iG34k5vUhTmPagjBKoQSA_QXN8zaGluXY5jP-ACfcBLIzBfIusU5TwSBDB3FYTDYsbtR-V3eR8Hdjj0OjHBOU575gAT4EQOjscR3QUTN54kHzYwfUkh2hjMwTCEQgq8ByePEYRwSrZvAAO7nQxeVBjm-AnniMEAm4H1U0pFeA4JAxV3fEWfBnNMs4sw4dw7loB7SJ5uhPEVOL2kd2EOAJE0OwlF0d_fDwwkCDVPfg81Dy3eA_sF6vNgfIKA6QIMih5h7qS5Dyb83pWgd2AOb2e3w9y7NMkwidHA6SW9A3Oud2DuXZlEmuSHaOD0kh6CORpGMP62CZeFsNd3leQ7FjuwBU4v6RrMyf8x4Q62TzThlQl0H9PbD09nS3EPTAjgfZjYjvFtBzBJNL7CMFfo_OhVmIMCp5d0BSZUy9DKHI8Co_42uYATgYkH4orYT94yF2BuXJkvCXsmCea8l5-LYa_xQFxh-_DrMph7UaF3maA0H1L5dOwHz5sIBiri88LKwG7xTgkwcKy7YM509sVL5NDXBRg0wYX7Dn0FClWBU4czGPSF4m0wbxdgYmn2IAzkidg9hb_4VJGVORzAU2GzqG84ENPJPro_ZzmGFDiFJk9uwwqdP34eJ_CFYGIFIKoA5qgvEDNsFna7CQauy1tyBQicQpOB8aTWGcxhGug27jcBJuj05XxhrsKgW3Z0DFnCtdlvoZ-B05DZSDMhmAwTrExYR5RI7F6Yk_OLVTkB5lTYEtfoKsy55auC1qGCUWDhC40aVtz_OVDCdwAhggdgQiuD0M7x0PIdukEaBHQc5TuCSbB-XZAmnFq3plmy_B6B05DZRIJQMwnmZDJoJuvY4evCoFodOIUmTwoHz5vnMO8iJCsA8KeNjBvoBhigHw5fUR5NfgWY4744r9YJgjBxRcb2dRsMuvRkNYwQKGH7xGAO38Ec_IVhUDjcOv449T5XAs8tMHDfhK0-CIPWJuzwHsVRoM5oboO59CtARP7rAwTxfybCnGhiaRZaIz9yqHzxLIzSxMePez_TzTAQ4vga5tOcTRaC-YCuw5w_XEK6Ayaq86SOrUywL852T-LKHC4-sZzD-IoThPR1YU7OHhGECys-vq8oTPSXgBNM8r6_pvhksWr2iPwafTtMbJ2-LsyDDEf5Jezt8B9Y4uP7Ctk_S7kjzAP_rhmf7HYY32zsMAwQbscUAMRRvvrKHC0eN3viE-SK0Jh-8_BNWVyfBRP7nuZjMGf15aATwlmSwRCMnR6EJ6M3sJ3P5r_RQJ4jE3J1j-AwX-CynI_u6xwhEPqPZ_DSrwFzXtCON_sewQIQuigKeh3mpLjXd5Xg8vxR8wAMsh86Olk9nXxLSLFAD-yYSzAnnGMBSOh2l2Iwh-AVpHf-2SxZCS7DBe2A9G1gYqciivu8SeeDx2BQJfi9w4QT7bNhQOjs-X9L3p0PfnjUhPPss2F-OPtC47ZH6PngT9ES8DuH-f5WBhmNB_4e-QLnEDnTN6hmQf09H-g-mNDj9_ypej54_F3zsTeAk2LPksCJf-Z2GF_hSKiNjpPenuJJ9kGYuM2DDv9k9nbhoRkzmqQ3iBP5winBpf_aHML5ljCXFDJ9VeG1SlyZ-Jvmt4CBSRaPhXS-H851y_5HS3NcGbR9vgXMO3oPJvF8okkfBu2c3wrmvTRLgknKsnMYv-o8qHdgLp2OO72kw1eZh8qYoADmo8vy9C5M0i_OUHHTl4RgLnAg-QXgU2DgDY3HkOJ-r-kayyeuzAWSH-6CucyCku_Pf_7LX_4c6GI-3qKLdn-4xhJJs-DfnZKEvCVuGgiSpHi_23XBLwxfYbl5z_gwvu24yQssZ_1u1wXD6N0sHgwpbvmK4FCJJj8N5vJbma-442tCGyPB5Kel2XuKG76iiyZD_iOK97td3xwmbNKvAycFpyIKKsbditu8TXHLlxUyedF-VAjmbw_onTf9i4pbDitaqeNW39eHYB7BifiNKvoQjTu9QR-BeSTX3mL_3SR0EH8jiFt9X28PkfwNwjxUBd6iv-1feaGJO71JcZc36gCTTHMhDHTFfVhxk7cq7vJGHWESbSdHod6DQefjFm9X3OWNejTN4u5DekPP_A-gfDrMlS0PCwpY64sP-BsUd3mjHoa5XACOmRt3eIfiLm_UozBX3jc-znInzKmUH6b-6516913wQyz3wjydGmjquNn39J3BIJpTUvz1TpwjzFl6HfV1YY63Plk-zMkAsBK3e13HjRG67AMwkQ0GD-JugYKdAVunXQLjb-hNLnQ3H4OJhCI0XxcGjBeFCTVRThx6HScP-zrq8nodqlksFlIU5i409G1TVBDmXT0OA0_dAnO0E3H7jmIJ69-3uPVzRWAuOk9QEuYFmODnrYrBxE1fUHjPwO0ct3efEmGO_qKH1_UgTOSqUKo9hPU4TKwAxGDOaUJZh-qY34pclbxvbtfXggkPg4Y6Gj_Jr8V-8_D3U2HuUHgYNNS5kmKfChM--wn6hjAJ2fON9QdMoO8c5ukpHrmm7xwm-Ul_Sd8ZzLn188hlfWcwcXsg0eKBK4rCnCl89hOUsAwPw_zmOme5S98ZTMLS3KHvDCZu7z79XmBu2jp_wHwzXYa5Sb8XmJsqwx8w30y3OL6iP2C-lW7KpSv6nmA-yvJdwdz0LLmm7wnmowvzfcF8WPERP1__epY0ceLapua4tiqaqvf8088_k2mCfklRGPiJv1AvhH_IsvQLgWHYC05j2C8vP5MkDJM0-Mm-EC8kjg5hLwp08vswfh8YhH0Y1AcNHPRJ4RQ4nSIIECVBpxSeRsdw4DToxdCoF4HDKAWCDOgGTsNDHAZhp4MnloBRBvzIAOtMBh7B0cAYcMZffnl5Xjja-PmnZ1qVZEylaJykJvLzy7O2VgxVMo3l9Pknx3bVl2dTskE_W_mHqZjyP0AXZfL8Ew4-YL-16oCT__oVhG1t_fwT8fLswO7g2NEW6tqRFpa4ACdwhqEpgmEyTBpPg4vdtbNcqDk4xvNPGLCzXAYHnoM-1osx-hyv0QdYoqXryEt7rNpr0V2rYKKff4nF4bqlCHijUzS8k34bssP7gsNbkoI3B7WOYQLdadTfb-LwpsMzFAPHQId-E17rr0MwR-jyYLTQNafRgumTBoOXRWz53eHihXzDCWDi-KP6TdQlMEVhyACygdqhc4d8IU_t-ICBeXgmsBCbCYZPhv0WzKrwNkJb6DARHA5uIYSN9grMVLSP4PwZFIYzwMw_9EI5DhI27fdBuw_trjQYKzQS3EJ-H38f-FsEdgpzhnrBgVMU3G1oC6GB0eqddhAgsVUDJNO_ntcKSr4J_PgVhJfy0hEnmqkulpa49jRHmR0S2NGWpigp6AMkvqOtHU1BY2Q9dQ2ynVclG_ZmMgS4gDM0czxammpedVQFZDxJYhSIg0MJ9iJweFTUti1bU0043hLsDoIlWQzGl4ax9PqSYTz_RIO7kAax0pJ3bEmbzsBgLJuGkzSljTaVHLAWeAYggkhn6aBjUIzg-LyztMAIGAs8gUMBLF7WXrom2HlpEoOj9orltiGZJtxuGZwBkdxMsqdoCNThZJhAhpExDxljKBKNWlqaU2jTB4eejkNQGQoOEdgkCRz2OdoCKU_A265ItqU6omWr67WIKgvILr-mYGSaeTk0aRY_NHEsA5MTNXEsfWyC23dskgT7y2lgQ92oBipfsqToM7BY4kTSjONU6L6BhedsVdLbS810CqYkG_C2HgohTAltPRNtdSFppqgaYEltTdGcHegD7wG6vuEajtaQrOPVIL6AIXEhWaJiOmg82AbVbXycHITWhrRAfdbaHk76I7hQBr1_xmChiD68PAm04P0GMAq4iT-zP8KEx39Eu47MgE3HvpA0-UJi5AtNZ14oCuzo58l6gaaKVllinFxQYR1AuxJtQ78K-rWOJfwzaGumKLiz_SbawKim-k8_eMZvns6waGeiIVDzOEuk2AYzxqYJjRtYQ8FDJ9gMrkGzxgyEGEJeAgvQUMSZ_8xG5Q-2YoWYRHXNL8SoHS7EoXOo7Z8Lj3Yoq6dL_L6HBgFBArsUqnSoScQLcehZubAl8HTG_Mc1WPBntcg6i7TbIrBhf-boo-o0peG8p7_W8P6OIDfZBd_ZFApZb5_jXQ7DGs2mM27a23y2sukUTHzWbnTXaYrJNdL0eIKPqjUHy2UGndF-3GvnvJ5IZYrdmUrWqZWWqtFT0TAboqilFtxArO3losOmNuJO7DWIScvM1-1qmxu5TJbxxvRYznLCgFaqbIOoDkmx9zpkhdGmaWQLm22xlE-VSpuVpjfdV1lp60Kzsyx26kVhW2b2XDrH8CmOGacsfmc1tYm2IJhG0WNGc6zGlep4K7OpclVVLeSmRIvJvIoChg2mZHG3HhPzurUq4e3JbFvWe9K0s6ySynydaWppnshZpswvB5uhTrem3VyrYPI81aqbw4mgmfpGHLbGpd6ywPF0nR8Yu1WxqJXTFbvfmeenjtnfKfo2lSmqzYKD5RuLipPTtlyx7-qLtmGapjsuZMgut94Np_J28LpcGnwpr1axhp52FkWFXyt9QdOZ0tKTOUbaM73X0norr1SNKckjz1MFh8MNIcdQet8s8vVZzlm0-zlKmFuk1KuwnDzp9AqVFr3umLUq3ef5VzrFD7otayqs6bUw2lGs2coVmtx-KHWcXJXeDCXaYR1DoLcpRTdz2g7f8xY_tOpW6lWvGKMyPtXGI45smIvBVNjUyzO8bVdbrjAu2bnVoM9nhOau4YpL3OHnzeKgPh3tsdRObSwwgUrpPLfJFM3hWKj2NJKx3Snf9JbNaolC3NuF63IpoyPppqbqOu3lTLBQhWWzZprTqjRse3JJUCoU39uq6flu1OyM2-tNrWRZA3NW6VbStq6k05OsWzCG1ZSINfB8cdvf2J0etjM7WjHVb07JnFDYyXSzkS87ulutbua9SYvCW0zxtbvqUjWOr8I-w1WXbgqLnl6ca5OZbM24lKlZBNZdavNG2WvPq3qxta2uernyJl2VK-291VSXPJ7qu-yq6OVppkZ5E2_XWFAdvKBboFG0mOErtnSLeVzwTKFJtbY6mWtlDTtn4KXG3NVHebfX0LGyUqxhXn1W3VbxRnrGzYtNoVDrzAytQBmcmyrluel-ZzJKqbKTO82dZdRzPFF_zfEbS-atRrff8GRr7FSHk-FCs5Rhk1pUuml-WqKrWkMgaiRFzaeC09k0eIpXeEUuyoN5sSVtvQaV60xJTZKE3GhZVSdZfNtvr9lVh9IGJYEpV1YZoQf2y7a1a7SVer0zcWmlwOpCZ56uUfwwK9CDwnbCK25qR-wb7Tw2q3fsrlrpNsAaLzvttsGlMW7LacTqtTtbpDlqN-wovOXw5ZQqFnvj5Yh217t-d7op4Ll1i5yW4bx1aaoUGEVprRne1GY8XaZ1XST4Fd7S-qmmolJ8F3A0OKdWJmZjbcwtu5X8vOoUDLppj_gCmV4UaKMz3eVZc2QJ03F67NmNflfZve7seVv2CLzQLc0Fzi2Y4M-ex6xtqrnAJLZVIvs4tyzUuOUU3YPajinvLLVAOzZrNGhWN8fpviPS5OsIJ1yeJNrORqnsrWF-vmu3p24hXyu_2nSBFzP1MrdtY5jZ1lojfgSqwXQ8brnFzkKXmJFiWINUnV8VK1lqJ3N5q8hu63KrOShbm4Je3ZUn9cVatDLZLLxnY7baT9tasYA7M34MTixEc9wzZiB3JbOy72Z0qmM0MElcj2YpYgvir5qwLhZ2Cql5BQbb9cm9J8-qzSo-XdqCMFgJnrqpkK3X9ATeN3vbZNn-QjMtXSDZVG-vWi5Tkliyw2eVUbMCngk0WWwvzGGpXPckGeQkqfWGpkAtlHWx4eachtTJbvE8yCdvOqxPumy6y7E83-OGWCmvcK0V2WVne7YvmEx-1pL7-WlzLnM5l1U2eXNnF9hsTcr3dpNpurqbdGrzQXtb0SleUgkVE5ZOnupVRWNSqM83FTPPd_LgMV2reHJnOXQtd5nXmq2NI7Q66_FWMia8YLO8JGhVzKzRsyK20YZuXWNS4sbkXvMTy1juOadkaWxZZlqtPL6ojtJDIpeWZ31T8Fqv43Wxsq5tlfmwnlkXa6NmlmqS6ybYV1rL7lWd6YbwupaO5aekOjN4yh021cW8usvq6XVtKBDNaavAqr3FYFIc790CxtF1QdLcBmsp1ZaY0XJrvJEXWsw2Nx56SrbGttieSGe4YqG-35P7qacIYr04HDW3ea1axGSXG4G9sSwJXj1XtfIajsuZ2liprVf9_LCTrYD64rWtqUI4jZzOoBi76tUzG1IpL22yLs2yK8_RdIJP70ZZatQc5RVz1pG5kplivKpHD5uzwtgcrKaV0XqitgSuIjvDfldtS5OVhnsrNqNvDQvsp33Gy2qbPZPrLxvlyoYtvnLkclYXqotymdUm_XWXqBf7xcVk_Wphs-Y6zXfVIT9KZbgWa2J0NmUymmDRXd1pLF7VRdUY2pN0z8YxBivNLKfRA8_oRbmTl-cFo2xS2itm1_NZe-BqBkGKnVYLLEhWzHCFLklxVYF2SyZtz4Zattoq1VLtHCgkG2u_EtJ5dYSPG-R0pU7a-h5YEoWNMCrzbXKqW0VDyAzyE9noFNOeLYBt6hFmXWFEbuPs-stRa2C3BK3Y4gpye6Rvm-JIlndre7XwRsQIb2btCVMQJt6mD4xu9akMtla96jZxuQYe7jyjCnwqw5RH9oInpgTZpV0qU1o2SoXUiFHm3VI5N2nQrQ6Tz83aenrMKAvZbXdWeW7WtlihUZt6Q4HNKxnbllL0q1eZj8wq0cpmZWW6LNC9YS8tyxXhlWwzlKEzrMKOGJXrLkogf10JS2W6WKumZCZcg3jNKQ03288rzBKMKfew6pbYMOAZCl4C8S47VUuTllgnKXki2FamZJOYLLq2K5ZlnBH7w7Rq7zNM15BEkqVeK2QbcJRn7Ia1wN-Ml9pRQ5V1vPTEJOm0Wt6SKXFWHwyWmYWMU4pAqINGZpEZ1eWmOGhnGiSVUfu55nq_4uRxQ-0OmwwvNncpdyRX9Y2U3aoGP8wYe5lKiTmV1eW9uWiWFdZt57ujdo6oVjO0uqjXDYvDG-xqztOat8ZNspKdr4uOnNmsF_Z4TAjDFtOoC8WZwmX0jlHCZ5JMvLqkmUlv6hnwRjqrFMQ5w7upymy2aW_37f7GrfeY1AIrm0Ktk_IMg9DbvVRrxAj9jUFtbGYyK6WcrZeWqyrpdOYq325ajNym2zV-jI3rjNthVRtfUg0jPZgpg8yEWrTz-fbAJsYKU64S4kYWiH1-oKpdncB1Y0iBXx9nwpbt7-fgV1HHLVf03WbVAQ-HPVZnutUyU69P2_nUnhFylEUtOqWdqnkMZxpTzKgyRDufTtutST1f6ehpr-zVBsxrf9zatqQVPcYz2V6zgqWl8jhDd9pzIU8ObNGddFYZg8o0Ns6eEO0VRbg7zJHabZJ83RNkM9XukBOCJcRUY6CT5SXw7LJj8Diw8uNid2IsXKbjqi6920tpusrse7uNKguDqWmNu5LoaePxTFL2maJe3Hb0QmoiUoI7KRHu9J__fP71_wHIRpVr \ No newline at end of file diff --git a/backend/test/lib/robots/dreame/res/map/l10su_1121_carpet.json b/backend/test/lib/robots/dreame/res/map/l10su_1121_carpet.json new file mode 100644 index 00000000..fd69d5a8 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/l10su_1121_carpet.json @@ -0,0 +1,4202 @@ +{ + "__class": "ValetudoMap", + "metaData": { + "version": 2 + }, + "size": { + "x": 6554, + "y": 6554 + }, + "pixelSize": 5, + "layers": [ + { + "__class": "MapLayer", + "metaData": { + "segmentId": "1", + "active": false, + "source": "regular", + "area": 38475 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 687, + "max": 747, + "mid": 717, + "avg": 717 + }, + "y": { + "min": 654, + "max": 690, + "mid": 672, + "avg": 673 + }, + "pixelCount": 1539 + }, + "compressedPixels": [ + 687, + 654, + 16, + 687, + 655, + 16, + 687, + 656, + 16, + 687, + 657, + 16, + 687, + 658, + 16, + 687, + 659, + 16, + 687, + 660, + 14, + 687, + 661, + 14, + 687, + 662, + 14, + 702, + 662, + 29, + 733, + 662, + 11, + 687, + 663, + 14, + 702, + 663, + 29, + 733, + 663, + 11, + 687, + 664, + 14, + 702, + 664, + 44, + 687, + 665, + 7, + 696, + 665, + 4, + 702, + 665, + 44, + 687, + 666, + 7, + 702, + 666, + 44, + 687, + 667, + 13, + 701, + 667, + 45, + 687, + 668, + 44, + 733, + 668, + 11, + 746, + 668, + 2, + 687, + 669, + 44, + 733, + 669, + 11, + 746, + 669, + 2, + 687, + 670, + 61, + 687, + 671, + 61, + 687, + 672, + 61, + 688, + 673, + 60, + 689, + 674, + 59, + 689, + 675, + 59, + 688, + 676, + 60, + 690, + 677, + 58, + 692, + 678, + 56, + 695, + 679, + 53, + 696, + 680, + 50, + 695, + 681, + 51, + 696, + 682, + 50, + 696, + 683, + 10, + 709, + 683, + 37, + 696, + 684, + 10, + 723, + 684, + 23, + 697, + 685, + 9, + 722, + 685, + 24, + 701, + 686, + 5, + 724, + 686, + 22, + 701, + 687, + 5, + 723, + 687, + 23, + 702, + 688, + 4, + 723, + 688, + 23, + 724, + 689, + 22, + 728, + 690, + 15 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "2", + "active": false, + "source": "regular", + "area": 52375 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 605, + "max": 672, + "mid": 639, + "avg": 640 + }, + "y": { + "min": 638, + "max": 672, + "mid": 655, + "avg": 655 + }, + "pixelCount": 2095 + }, + "compressedPixels": [ + 609, + 638, + 64, + 609, + 639, + 64, + 610, + 640, + 63, + 611, + 641, + 62, + 611, + 642, + 62, + 611, + 643, + 62, + 611, + 644, + 25, + 638, + 644, + 35, + 611, + 645, + 25, + 638, + 645, + 35, + 611, + 646, + 62, + 611, + 647, + 25, + 637, + 647, + 36, + 611, + 648, + 25, + 637, + 648, + 36, + 611, + 649, + 62, + 613, + 650, + 60, + 611, + 651, + 62, + 612, + 652, + 17, + 630, + 652, + 43, + 611, + 653, + 18, + 630, + 653, + 43, + 613, + 654, + 16, + 631, + 654, + 42, + 611, + 655, + 18, + 631, + 655, + 42, + 611, + 656, + 16, + 629, + 656, + 44, + 611, + 657, + 62, + 611, + 658, + 62, + 611, + 659, + 62, + 611, + 660, + 62, + 611, + 661, + 62, + 611, + 662, + 62, + 611, + 663, + 9, + 621, + 663, + 52, + 611, + 664, + 62, + 607, + 665, + 2, + 610, + 665, + 43, + 655, + 665, + 18, + 607, + 666, + 20, + 629, + 666, + 24, + 656, + 666, + 2, + 660, + 666, + 13, + 607, + 667, + 20, + 629, + 667, + 24, + 660, + 667, + 13, + 607, + 668, + 46, + 660, + 668, + 12, + 607, + 669, + 46, + 662, + 669, + 10, + 605, + 670, + 1, + 607, + 670, + 46, + 605, + 671, + 48, + 605, + 672, + 48 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "3", + "active": false, + "source": "regular", + "area": 25775 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 748, + "max": 802, + "mid": 775, + "avg": 776 + }, + "y": { + "min": 662, + "max": 683, + "mid": 673, + "avg": 673 + }, + "pixelCount": 1031 + }, + "compressedPixels": [ + 762, + 662, + 17, + 782, + 662, + 8, + 791, + 662, + 3, + 795, + 662, + 5, + 762, + 663, + 17, + 782, + 663, + 8, + 791, + 663, + 3, + 795, + 663, + 5, + 761, + 664, + 39, + 761, + 665, + 39, + 767, + 666, + 34, + 767, + 667, + 34, + 748, + 668, + 15, + 767, + 668, + 1, + 770, + 668, + 8, + 780, + 668, + 9, + 791, + 668, + 1, + 797, + 668, + 4, + 748, + 669, + 15, + 767, + 669, + 1, + 770, + 669, + 8, + 780, + 669, + 1, + 782, + 669, + 7, + 791, + 669, + 1, + 797, + 669, + 3, + 748, + 670, + 16, + 765, + 670, + 29, + 797, + 670, + 3, + 748, + 671, + 46, + 797, + 671, + 4, + 748, + 672, + 46, + 796, + 672, + 7, + 748, + 673, + 46, + 796, + 673, + 7, + 748, + 674, + 55, + 748, + 675, + 55, + 748, + 676, + 55, + 748, + 677, + 55, + 748, + 678, + 55, + 748, + 679, + 55, + 748, + 680, + 55, + 751, + 681, + 52, + 751, + 682, + 52, + 751, + 683, + 52 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "4", + "active": false, + "source": "regular", + "area": 79300 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 712, + "max": 802, + "mid": 757, + "avg": 747 + }, + "y": { + "min": 691, + "max": 760, + "mid": 726, + "avg": 729 + }, + "pixelCount": 3172 + }, + "compressedPixels": [ + 728, + 691, + 15, + 728, + 692, + 15, + 728, + 693, + 15, + 728, + 694, + 15, + 728, + 695, + 18, + 728, + 696, + 18, + 728, + 697, + 18, + 727, + 698, + 19, + 727, + 699, + 19, + 727, + 700, + 19, + 727, + 701, + 19, + 729, + 702, + 17, + 729, + 703, + 17, + 729, + 704, + 17, + 727, + 705, + 19, + 727, + 706, + 19, + 727, + 707, + 19, + 727, + 708, + 19, + 727, + 709, + 19, + 727, + 710, + 19, + 797, + 710, + 2, + 727, + 711, + 19, + 796, + 711, + 3, + 726, + 712, + 65, + 796, + 712, + 5, + 724, + 713, + 67, + 796, + 713, + 6, + 724, + 714, + 67, + 798, + 714, + 5, + 724, + 715, + 67, + 797, + 715, + 6, + 724, + 716, + 68, + 796, + 716, + 7, + 724, + 717, + 79, + 724, + 718, + 79, + 724, + 719, + 79, + 724, + 720, + 79, + 724, + 721, + 78, + 724, + 722, + 76, + 722, + 723, + 61, + 722, + 724, + 61, + 722, + 725, + 61, + 791, + 725, + 4, + 722, + 726, + 61, + 791, + 726, + 4, + 722, + 727, + 56, + 779, + 727, + 2, + 793, + 727, + 2, + 722, + 728, + 55, + 793, + 728, + 2, + 722, + 729, + 55, + 791, + 729, + 4, + 722, + 730, + 55, + 791, + 730, + 4, + 722, + 731, + 55, + 791, + 731, + 4, + 716, + 732, + 35, + 755, + 732, + 23, + 791, + 732, + 4, + 716, + 733, + 26, + 755, + 733, + 23, + 791, + 733, + 4, + 716, + 734, + 26, + 750, + 734, + 2, + 755, + 734, + 23, + 792, + 734, + 3, + 712, + 735, + 30, + 750, + 735, + 28, + 791, + 735, + 4, + 712, + 736, + 30, + 750, + 736, + 28, + 791, + 736, + 4, + 712, + 737, + 30, + 750, + 737, + 28, + 712, + 738, + 29, + 750, + 738, + 21, + 712, + 739, + 28, + 750, + 739, + 12, + 712, + 740, + 28, + 750, + 740, + 11, + 763, + 740, + 5, + 712, + 741, + 28, + 750, + 741, + 11, + 763, + 741, + 6, + 712, + 742, + 28, + 750, + 742, + 11, + 763, + 742, + 5, + 712, + 743, + 28, + 750, + 743, + 11, + 763, + 743, + 5, + 712, + 744, + 28, + 750, + 744, + 11, + 763, + 744, + 6, + 712, + 745, + 15, + 729, + 745, + 11, + 741, + 745, + 20, + 763, + 745, + 6, + 712, + 746, + 15, + 729, + 746, + 11, + 741, + 746, + 21, + 712, + 747, + 28, + 741, + 747, + 21, + 767, + 747, + 5, + 712, + 748, + 60, + 712, + 749, + 48, + 761, + 749, + 11, + 712, + 750, + 44, + 761, + 750, + 10, + 712, + 751, + 44, + 761, + 751, + 3, + 712, + 752, + 44, + 761, + 752, + 2, + 712, + 753, + 44, + 712, + 754, + 44, + 712, + 755, + 44, + 712, + 756, + 44, + 712, + 757, + 44, + 712, + 758, + 2, + 715, + 758, + 37, + 755, + 758, + 1, + 716, + 759, + 36, + 716, + 760, + 36 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "5", + "active": false, + "source": "regular", + "area": 93225 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 654, + "max": 706, + "mid": 680, + "avg": 679 + }, + "y": { + "min": 674, + "max": 759, + "mid": 717, + "avg": 716 + }, + "pixelCount": 3729 + }, + "compressedPixels": [ + 656, + 674, + 11, + 669, + 674, + 12, + 655, + 675, + 12, + 669, + 675, + 12, + 654, + 676, + 27, + 682, + 676, + 2, + 687, + 676, + 1, + 654, + 677, + 31, + 686, + 677, + 4, + 654, + 678, + 38, + 656, + 679, + 11, + 669, + 679, + 26, + 656, + 680, + 11, + 669, + 680, + 12, + 683, + 680, + 13, + 654, + 681, + 27, + 683, + 681, + 12, + 654, + 682, + 28, + 683, + 682, + 13, + 654, + 683, + 42, + 654, + 684, + 42, + 654, + 685, + 43, + 654, + 686, + 44, + 654, + 687, + 43, + 654, + 688, + 42, + 654, + 689, + 12, + 668, + 689, + 28, + 654, + 690, + 11, + 667, + 690, + 30, + 654, + 691, + 11, + 667, + 691, + 31, + 654, + 692, + 40, + 696, + 692, + 3, + 654, + 693, + 40, + 696, + 693, + 4, + 654, + 694, + 31, + 687, + 694, + 18, + 655, + 695, + 30, + 687, + 695, + 19, + 655, + 696, + 34, + 690, + 696, + 16, + 654, + 697, + 40, + 696, + 697, + 10, + 654, + 698, + 35, + 690, + 698, + 1, + 692, + 698, + 2, + 696, + 698, + 9, + 706, + 698, + 1, + 654, + 699, + 17, + 678, + 699, + 11, + 690, + 699, + 15, + 654, + 700, + 17, + 672, + 700, + 6, + 691, + 700, + 16, + 654, + 701, + 17, + 672, + 701, + 17, + 691, + 701, + 16, + 654, + 702, + 13, + 669, + 702, + 2, + 672, + 702, + 35, + 654, + 703, + 13, + 669, + 703, + 2, + 672, + 703, + 35, + 656, + 704, + 15, + 672, + 704, + 35, + 654, + 705, + 53, + 654, + 706, + 53, + 655, + 707, + 52, + 654, + 708, + 1, + 656, + 708, + 51, + 658, + 709, + 49, + 658, + 710, + 13, + 673, + 710, + 34, + 654, + 711, + 1, + 658, + 711, + 13, + 673, + 711, + 34, + 654, + 712, + 3, + 658, + 712, + 49, + 654, + 713, + 3, + 658, + 713, + 49, + 654, + 714, + 2, + 658, + 714, + 49, + 654, + 715, + 3, + 658, + 715, + 49, + 654, + 716, + 3, + 658, + 716, + 49, + 654, + 717, + 51, + 654, + 718, + 51, + 654, + 719, + 37, + 703, + 719, + 4, + 654, + 720, + 35, + 696, + 720, + 3, + 702, + 720, + 5, + 656, + 721, + 9, + 667, + 721, + 21, + 690, + 721, + 9, + 700, + 721, + 7, + 657, + 722, + 8, + 667, + 722, + 21, + 690, + 722, + 9, + 700, + 722, + 7, + 656, + 723, + 11, + 677, + 723, + 11, + 689, + 723, + 10, + 700, + 723, + 7, + 654, + 724, + 13, + 677, + 724, + 11, + 689, + 724, + 10, + 700, + 724, + 7, + 654, + 725, + 13, + 668, + 725, + 9, + 678, + 725, + 10, + 689, + 725, + 10, + 700, + 725, + 7, + 654, + 726, + 13, + 668, + 726, + 9, + 679, + 726, + 9, + 689, + 726, + 10, + 700, + 726, + 7, + 654, + 727, + 13, + 668, + 727, + 9, + 679, + 727, + 9, + 689, + 727, + 10, + 700, + 727, + 7, + 654, + 728, + 13, + 669, + 728, + 8, + 679, + 728, + 9, + 689, + 728, + 10, + 700, + 728, + 7, + 654, + 729, + 13, + 668, + 729, + 10, + 679, + 729, + 9, + 689, + 729, + 10, + 700, + 729, + 7, + 654, + 730, + 13, + 669, + 730, + 9, + 679, + 730, + 9, + 689, + 730, + 10, + 700, + 730, + 7, + 654, + 731, + 13, + 669, + 731, + 7, + 689, + 731, + 10, + 700, + 731, + 7, + 654, + 732, + 13, + 669, + 732, + 19, + 689, + 732, + 10, + 700, + 732, + 7, + 654, + 733, + 13, + 669, + 733, + 19, + 689, + 733, + 10, + 700, + 733, + 7, + 654, + 734, + 3, + 658, + 734, + 9, + 674, + 734, + 14, + 689, + 734, + 10, + 700, + 734, + 7, + 654, + 735, + 22, + 677, + 735, + 11, + 689, + 735, + 10, + 700, + 735, + 7, + 654, + 736, + 34, + 689, + 736, + 10, + 700, + 736, + 7, + 654, + 737, + 22, + 677, + 737, + 11, + 689, + 737, + 10, + 700, + 737, + 7, + 654, + 738, + 34, + 689, + 738, + 10, + 700, + 738, + 7, + 654, + 739, + 34, + 689, + 739, + 10, + 700, + 739, + 7, + 654, + 740, + 34, + 689, + 740, + 10, + 700, + 740, + 7, + 654, + 741, + 3, + 658, + 741, + 30, + 689, + 741, + 10, + 700, + 741, + 7, + 654, + 742, + 34, + 689, + 742, + 10, + 700, + 742, + 7, + 654, + 743, + 34, + 689, + 743, + 10, + 700, + 743, + 7, + 654, + 744, + 34, + 689, + 744, + 10, + 700, + 744, + 7, + 654, + 745, + 1, + 657, + 745, + 31, + 689, + 745, + 10, + 700, + 745, + 7, + 654, + 746, + 1, + 657, + 746, + 31, + 689, + 746, + 10, + 700, + 746, + 7, + 654, + 747, + 34, + 689, + 747, + 10, + 701, + 747, + 6, + 656, + 748, + 32, + 689, + 748, + 3, + 694, + 748, + 5, + 701, + 748, + 6, + 654, + 749, + 38, + 694, + 749, + 6, + 703, + 749, + 4, + 654, + 750, + 53, + 655, + 751, + 4, + 665, + 751, + 40, + 654, + 752, + 5, + 665, + 752, + 23, + 689, + 752, + 15, + 680, + 753, + 13, + 694, + 753, + 11, + 682, + 754, + 4, + 695, + 754, + 8, + 691, + 755, + 13, + 690, + 756, + 17, + 691, + 757, + 16, + 691, + 758, + 14, + 693, + 759, + 10 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "6", + "active": false, + "source": "regular", + "area": 81625 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 600, + "max": 653, + "mid": 627, + "avg": 631 + }, + "y": { + "min": 673, + "max": 758, + "mid": 716, + "avg": 712 + }, + "pixelCount": 3265 + }, + "compressedPixels": [ + 605, + 673, + 48, + 605, + 674, + 48, + 605, + 675, + 48, + 605, + 676, + 48, + 607, + 677, + 20, + 629, + 677, + 24, + 606, + 678, + 21, + 629, + 678, + 24, + 605, + 679, + 48, + 605, + 680, + 48, + 601, + 681, + 1, + 603, + 681, + 51, + 601, + 682, + 53, + 600, + 683, + 54, + 600, + 684, + 54, + 600, + 685, + 54, + 600, + 686, + 24, + 627, + 686, + 27, + 600, + 687, + 22, + 627, + 687, + 27, + 600, + 688, + 22, + 623, + 688, + 3, + 628, + 688, + 26, + 600, + 689, + 27, + 629, + 689, + 25, + 600, + 690, + 28, + 630, + 690, + 24, + 600, + 691, + 29, + 633, + 691, + 21, + 600, + 692, + 31, + 633, + 692, + 21, + 600, + 693, + 30, + 631, + 693, + 23, + 600, + 694, + 54, + 600, + 695, + 53, + 600, + 696, + 22, + 626, + 696, + 27, + 600, + 697, + 23, + 626, + 697, + 28, + 600, + 698, + 23, + 626, + 698, + 4, + 633, + 698, + 21, + 605, + 699, + 9, + 633, + 699, + 21, + 606, + 700, + 8, + 633, + 700, + 21, + 606, + 701, + 8, + 633, + 701, + 21, + 606, + 702, + 8, + 633, + 702, + 21, + 606, + 703, + 8, + 633, + 703, + 21, + 606, + 704, + 8, + 633, + 704, + 18, + 652, + 704, + 2, + 606, + 705, + 8, + 633, + 705, + 21, + 606, + 706, + 8, + 633, + 706, + 21, + 606, + 707, + 8, + 633, + 707, + 21, + 606, + 708, + 8, + 627, + 708, + 27, + 621, + 709, + 27, + 621, + 710, + 27, + 651, + 710, + 1, + 621, + 711, + 8, + 631, + 711, + 17, + 651, + 711, + 3, + 621, + 712, + 9, + 631, + 712, + 17, + 650, + 712, + 4, + 621, + 713, + 9, + 631, + 713, + 17, + 650, + 713, + 4, + 621, + 714, + 10, + 633, + 714, + 15, + 650, + 714, + 4, + 621, + 715, + 12, + 635, + 715, + 13, + 650, + 715, + 4, + 621, + 716, + 13, + 635, + 716, + 13, + 650, + 716, + 4, + 621, + 717, + 27, + 650, + 717, + 4, + 615, + 718, + 4, + 621, + 718, + 27, + 650, + 718, + 4, + 615, + 719, + 33, + 650, + 719, + 4, + 615, + 720, + 33, + 650, + 720, + 4, + 615, + 721, + 33, + 650, + 721, + 2, + 653, + 721, + 1, + 615, + 722, + 33, + 615, + 723, + 33, + 652, + 723, + 1, + 615, + 724, + 33, + 650, + 724, + 4, + 615, + 725, + 33, + 649, + 725, + 5, + 615, + 726, + 15, + 632, + 726, + 16, + 650, + 726, + 4, + 615, + 727, + 15, + 632, + 727, + 16, + 650, + 727, + 4, + 615, + 728, + 11, + 628, + 728, + 21, + 650, + 728, + 4, + 619, + 729, + 8, + 631, + 729, + 2, + 634, + 729, + 9, + 644, + 729, + 5, + 650, + 729, + 4, + 619, + 730, + 9, + 634, + 730, + 20, + 619, + 731, + 8, + 633, + 731, + 21, + 619, + 732, + 9, + 629, + 732, + 1, + 633, + 732, + 21, + 619, + 733, + 11, + 633, + 733, + 19, + 619, + 734, + 11, + 633, + 734, + 2, + 636, + 734, + 16, + 619, + 735, + 12, + 633, + 735, + 21, + 619, + 736, + 13, + 633, + 736, + 21, + 613, + 737, + 1, + 615, + 737, + 2, + 619, + 737, + 13, + 633, + 737, + 14, + 649, + 737, + 5, + 613, + 738, + 19, + 633, + 738, + 14, + 649, + 738, + 5, + 613, + 739, + 19, + 634, + 739, + 20, + 612, + 740, + 21, + 634, + 740, + 20, + 612, + 741, + 42, + 612, + 742, + 42, + 612, + 743, + 42, + 612, + 744, + 42, + 612, + 745, + 36, + 651, + 745, + 3, + 612, + 746, + 36, + 651, + 746, + 3, + 612, + 747, + 36, + 650, + 747, + 4, + 618, + 748, + 30, + 653, + 748, + 1, + 619, + 749, + 29, + 619, + 750, + 28, + 618, + 751, + 29, + 618, + 752, + 29, + 619, + 753, + 28, + 619, + 754, + 28, + 612, + 755, + 5, + 618, + 755, + 29, + 612, + 756, + 4, + 618, + 756, + 29, + 613, + 757, + 4, + 618, + 757, + 21, + 642, + 757, + 1, + 644, + 757, + 2, + 613, + 758, + 4, + 618, + 758, + 21, + 642, + 758, + 1 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "area": 35200 + }, + "type": "wall", + "pixels": [], + "dimensions": { + "x": { + "min": 599, + "max": 803, + "mid": 701, + "avg": 702 + }, + "y": { + "min": 636, + "max": 761, + "mid": 699, + "avg": 703 + }, + "pixelCount": 1408 + }, + "compressedPixels": [ + 609, + 636, + 64, + 607, + 637, + 3, + 672, + 637, + 2, + 606, + 638, + 2, + 673, + 638, + 2, + 606, + 639, + 1, + 674, + 639, + 1, + 606, + 640, + 2, + 674, + 640, + 1, + 605, + 641, + 3, + 674, + 641, + 1, + 605, + 642, + 1, + 674, + 642, + 1, + 605, + 643, + 1, + 674, + 643, + 1, + 605, + 644, + 1, + 674, + 644, + 1, + 605, + 645, + 1, + 608, + 645, + 2, + 674, + 645, + 1, + 605, + 646, + 1, + 608, + 646, + 2, + 674, + 646, + 1, + 674, + 647, + 1, + 674, + 648, + 1, + 674, + 649, + 1, + 607, + 650, + 3, + 674, + 650, + 1, + 607, + 651, + 1, + 674, + 651, + 1, + 607, + 652, + 1, + 674, + 652, + 1, + 607, + 653, + 1, + 674, + 653, + 1, + 685, + 653, + 19, + 607, + 654, + 1, + 674, + 654, + 1, + 685, + 654, + 1, + 703, + 654, + 1, + 607, + 655, + 1, + 674, + 655, + 1, + 685, + 655, + 1, + 703, + 655, + 1, + 607, + 656, + 1, + 674, + 656, + 1, + 685, + 656, + 1, + 703, + 656, + 1, + 607, + 657, + 1, + 674, + 657, + 1, + 685, + 657, + 1, + 703, + 657, + 1, + 607, + 658, + 1, + 674, + 658, + 1, + 685, + 658, + 1, + 703, + 658, + 1, + 607, + 659, + 3, + 674, + 659, + 1, + 685, + 659, + 1, + 703, + 659, + 1, + 609, + 660, + 1, + 674, + 660, + 1, + 685, + 660, + 1, + 703, + 660, + 10, + 674, + 661, + 1, + 685, + 661, + 1, + 712, + 661, + 23, + 739, + 661, + 2, + 745, + 661, + 1, + 750, + 661, + 52, + 674, + 662, + 1, + 685, + 662, + 1, + 745, + 662, + 2, + 750, + 662, + 1, + 761, + 662, + 1, + 780, + 662, + 2, + 790, + 662, + 1, + 794, + 662, + 1, + 801, + 662, + 1, + 608, + 663, + 2, + 674, + 663, + 1, + 685, + 663, + 1, + 746, + 663, + 1, + 750, + 663, + 1, + 761, + 663, + 1, + 801, + 663, + 1, + 606, + 664, + 1, + 608, + 664, + 2, + 674, + 664, + 1, + 685, + 664, + 1, + 750, + 664, + 1, + 801, + 664, + 1, + 606, + 665, + 1, + 674, + 665, + 1, + 685, + 665, + 1, + 746, + 665, + 2, + 750, + 665, + 2, + 801, + 665, + 1, + 604, + 666, + 2, + 653, + 666, + 1, + 674, + 666, + 1, + 685, + 666, + 1, + 746, + 666, + 14, + 801, + 666, + 2, + 604, + 667, + 1, + 653, + 667, + 2, + 658, + 667, + 1, + 674, + 667, + 1, + 685, + 667, + 1, + 764, + 667, + 1, + 802, + 667, + 1, + 604, + 668, + 2, + 653, + 668, + 6, + 674, + 668, + 1, + 685, + 668, + 1, + 768, + 668, + 1, + 790, + 668, + 1, + 795, + 668, + 2, + 801, + 668, + 2, + 604, + 669, + 1, + 653, + 669, + 1, + 658, + 669, + 1, + 673, + 669, + 2, + 685, + 669, + 1, + 768, + 669, + 2, + 781, + 669, + 1, + 794, + 669, + 1, + 796, + 669, + 1, + 800, + 669, + 2, + 603, + 670, + 2, + 653, + 670, + 1, + 658, + 670, + 1, + 673, + 670, + 1, + 685, + 670, + 1, + 794, + 670, + 1, + 801, + 670, + 3, + 603, + 671, + 1, + 653, + 671, + 1, + 658, + 671, + 16, + 685, + 671, + 1, + 794, + 671, + 1, + 803, + 671, + 1, + 603, + 672, + 1, + 653, + 672, + 1, + 685, + 672, + 1, + 795, + 672, + 1, + 803, + 672, + 1, + 603, + 673, + 1, + 653, + 673, + 29, + 686, + 673, + 2, + 795, + 673, + 1, + 803, + 673, + 1, + 603, + 674, + 1, + 653, + 674, + 2, + 667, + 674, + 2, + 681, + 674, + 4, + 687, + 674, + 1, + 803, + 674, + 1, + 603, + 675, + 1, + 654, + 675, + 1, + 667, + 675, + 2, + 681, + 675, + 2, + 684, + 675, + 1, + 686, + 675, + 2, + 803, + 675, + 1, + 603, + 676, + 1, + 684, + 676, + 3, + 803, + 676, + 1, + 603, + 677, + 1, + 685, + 677, + 1, + 803, + 677, + 1, + 603, + 678, + 2, + 627, + 678, + 2, + 803, + 678, + 1, + 603, + 679, + 2, + 803, + 679, + 1, + 599, + 680, + 5, + 654, + 680, + 1, + 667, + 680, + 2, + 746, + 680, + 2, + 803, + 680, + 1, + 599, + 681, + 1, + 681, + 681, + 1, + 746, + 681, + 1, + 750, + 681, + 1, + 803, + 681, + 1, + 599, + 682, + 1, + 746, + 682, + 1, + 750, + 682, + 1, + 803, + 682, + 1, + 599, + 683, + 1, + 746, + 683, + 1, + 750, + 683, + 1, + 803, + 683, + 1, + 599, + 684, + 1, + 706, + 684, + 2, + 709, + 684, + 14, + 746, + 684, + 1, + 750, + 684, + 54, + 599, + 685, + 1, + 706, + 685, + 2, + 746, + 685, + 1, + 599, + 686, + 1, + 698, + 686, + 2, + 722, + 686, + 1, + 746, + 686, + 1, + 599, + 687, + 1, + 697, + 687, + 4, + 706, + 687, + 1, + 722, + 687, + 1, + 746, + 687, + 1, + 599, + 688, + 1, + 697, + 688, + 1, + 700, + 688, + 2, + 706, + 688, + 1, + 722, + 688, + 1, + 746, + 688, + 1, + 599, + 689, + 1, + 696, + 689, + 3, + 701, + 689, + 4, + 706, + 689, + 1, + 722, + 689, + 1, + 746, + 689, + 1, + 599, + 690, + 1, + 698, + 690, + 2, + 704, + 690, + 3, + 722, + 690, + 5, + 743, + 690, + 4, + 599, + 691, + 1, + 699, + 691, + 2, + 726, + 691, + 1, + 743, + 691, + 2, + 599, + 692, + 1, + 700, + 692, + 2, + 726, + 692, + 1, + 744, + 692, + 1, + 599, + 693, + 1, + 701, + 693, + 6, + 726, + 693, + 1, + 744, + 693, + 3, + 599, + 694, + 1, + 706, + 694, + 2, + 726, + 694, + 1, + 744, + 694, + 1, + 746, + 694, + 1, + 599, + 695, + 1, + 707, + 695, + 1, + 726, + 695, + 1, + 746, + 695, + 1, + 599, + 696, + 1, + 707, + 696, + 1, + 726, + 696, + 1, + 746, + 696, + 1, + 599, + 697, + 1, + 707, + 697, + 1, + 726, + 697, + 1, + 746, + 697, + 1, + 599, + 698, + 1, + 694, + 698, + 1, + 707, + 698, + 1, + 726, + 698, + 1, + 746, + 698, + 1, + 599, + 699, + 1, + 630, + 699, + 1, + 705, + 699, + 3, + 726, + 699, + 1, + 746, + 699, + 1, + 599, + 700, + 1, + 624, + 700, + 8, + 689, + 700, + 1, + 707, + 700, + 1, + 726, + 700, + 1, + 746, + 700, + 1, + 599, + 701, + 1, + 602, + 701, + 3, + 619, + 701, + 6, + 631, + 701, + 1, + 707, + 701, + 1, + 726, + 701, + 1, + 746, + 701, + 1, + 599, + 702, + 4, + 604, + 702, + 1, + 614, + 702, + 6, + 631, + 702, + 1, + 707, + 702, + 1, + 726, + 702, + 1, + 746, + 702, + 2, + 604, + 703, + 2, + 614, + 703, + 1, + 631, + 703, + 1, + 707, + 703, + 1, + 726, + 703, + 1, + 747, + 703, + 1, + 604, + 704, + 2, + 614, + 704, + 1, + 631, + 704, + 1, + 707, + 704, + 1, + 726, + 704, + 1, + 747, + 704, + 1, + 604, + 705, + 1, + 614, + 705, + 1, + 631, + 705, + 2, + 707, + 705, + 1, + 726, + 705, + 1, + 746, + 705, + 2, + 604, + 706, + 1, + 614, + 706, + 1, + 628, + 706, + 5, + 707, + 706, + 1, + 725, + 706, + 2, + 746, + 706, + 1, + 604, + 707, + 1, + 614, + 707, + 1, + 626, + 707, + 3, + 707, + 707, + 1, + 725, + 707, + 1, + 746, + 707, + 1, + 604, + 708, + 2, + 614, + 708, + 1, + 620, + 708, + 7, + 707, + 708, + 1, + 725, + 708, + 1, + 746, + 708, + 1, + 797, + 708, + 3, + 605, + 709, + 10, + 619, + 709, + 2, + 707, + 709, + 1, + 725, + 709, + 1, + 746, + 709, + 1, + 795, + 709, + 3, + 799, + 709, + 1, + 619, + 710, + 1, + 648, + 710, + 3, + 652, + 710, + 5, + 707, + 710, + 1, + 723, + 710, + 3, + 746, + 710, + 1, + 795, + 710, + 1, + 799, + 710, + 2, + 619, + 711, + 2, + 648, + 711, + 3, + 655, + 711, + 2, + 707, + 711, + 1, + 723, + 711, + 1, + 725, + 711, + 1, + 746, + 711, + 46, + 795, + 711, + 1, + 800, + 711, + 3, + 619, + 712, + 1, + 649, + 712, + 1, + 707, + 712, + 1, + 723, + 712, + 1, + 791, + 712, + 1, + 802, + 712, + 2, + 619, + 713, + 1, + 707, + 713, + 1, + 723, + 713, + 1, + 791, + 713, + 1, + 803, + 713, + 1, + 619, + 714, + 2, + 707, + 714, + 1, + 723, + 714, + 1, + 791, + 714, + 1, + 803, + 714, + 1, + 620, + 715, + 1, + 707, + 715, + 1, + 723, + 715, + 1, + 791, + 715, + 2, + 795, + 715, + 1, + 803, + 715, + 1, + 620, + 716, + 1, + 707, + 716, + 1, + 723, + 716, + 1, + 792, + 716, + 4, + 803, + 716, + 1, + 614, + 717, + 7, + 707, + 717, + 1, + 723, + 717, + 1, + 803, + 717, + 1, + 614, + 718, + 1, + 707, + 718, + 1, + 723, + 718, + 1, + 803, + 718, + 1, + 614, + 719, + 1, + 707, + 719, + 1, + 723, + 719, + 1, + 803, + 719, + 1, + 614, + 720, + 1, + 707, + 720, + 1, + 723, + 720, + 1, + 803, + 720, + 1, + 614, + 721, + 1, + 707, + 721, + 1, + 723, + 721, + 1, + 802, + 721, + 2, + 613, + 722, + 1, + 648, + 722, + 1, + 652, + 722, + 2, + 707, + 722, + 1, + 721, + 722, + 3, + 800, + 722, + 3, + 613, + 723, + 1, + 648, + 723, + 1, + 707, + 723, + 1, + 721, + 723, + 1, + 783, + 723, + 1, + 786, + 723, + 6, + 795, + 723, + 5, + 613, + 724, + 1, + 707, + 724, + 1, + 721, + 724, + 1, + 783, + 724, + 4, + 789, + 724, + 1, + 795, + 724, + 1, + 613, + 725, + 1, + 648, + 725, + 1, + 707, + 725, + 1, + 721, + 725, + 1, + 783, + 725, + 1, + 795, + 725, + 1, + 611, + 726, + 1, + 613, + 726, + 1, + 648, + 726, + 1, + 707, + 726, + 1, + 721, + 726, + 1, + 783, + 726, + 1, + 795, + 726, + 1, + 611, + 727, + 1, + 707, + 727, + 1, + 721, + 727, + 1, + 778, + 727, + 1, + 782, + 727, + 2, + 791, + 727, + 1, + 795, + 727, + 1, + 611, + 728, + 1, + 649, + 728, + 1, + 707, + 728, + 1, + 721, + 728, + 1, + 777, + 728, + 6, + 795, + 728, + 1, + 611, + 729, + 1, + 649, + 729, + 1, + 707, + 729, + 1, + 721, + 729, + 1, + 777, + 729, + 1, + 795, + 729, + 1, + 611, + 730, + 1, + 707, + 730, + 1, + 721, + 730, + 1, + 777, + 730, + 2, + 795, + 730, + 1, + 611, + 731, + 7, + 707, + 731, + 1, + 715, + 731, + 7, + 778, + 731, + 1, + 795, + 731, + 1, + 617, + 732, + 1, + 707, + 732, + 1, + 715, + 732, + 1, + 752, + 732, + 3, + 778, + 732, + 1, + 795, + 732, + 1, + 617, + 733, + 2, + 707, + 733, + 1, + 711, + 733, + 3, + 715, + 733, + 1, + 743, + 733, + 10, + 754, + 733, + 1, + 778, + 733, + 1, + 795, + 733, + 1, + 617, + 734, + 1, + 707, + 734, + 1, + 711, + 734, + 1, + 713, + 734, + 3, + 742, + 734, + 2, + 749, + 734, + 1, + 752, + 734, + 3, + 778, + 734, + 1, + 795, + 734, + 1, + 612, + 735, + 1, + 707, + 735, + 1, + 711, + 735, + 1, + 742, + 735, + 1, + 749, + 735, + 1, + 778, + 735, + 1, + 788, + 735, + 1, + 795, + 735, + 1, + 611, + 736, + 2, + 617, + 736, + 1, + 707, + 736, + 1, + 711, + 736, + 1, + 742, + 736, + 1, + 749, + 736, + 1, + 778, + 736, + 1, + 788, + 736, + 1, + 795, + 736, + 1, + 611, + 737, + 1, + 707, + 737, + 1, + 711, + 737, + 1, + 742, + 737, + 1, + 749, + 737, + 1, + 778, + 737, + 1, + 788, + 737, + 2, + 795, + 737, + 1, + 611, + 738, + 1, + 647, + 738, + 2, + 707, + 738, + 1, + 711, + 738, + 1, + 741, + 738, + 2, + 749, + 738, + 1, + 772, + 738, + 7, + 789, + 738, + 7, + 611, + 739, + 1, + 707, + 739, + 1, + 711, + 739, + 1, + 741, + 739, + 2, + 749, + 739, + 1, + 772, + 739, + 1, + 611, + 740, + 1, + 707, + 740, + 1, + 711, + 740, + 1, + 749, + 740, + 1, + 772, + 740, + 1, + 611, + 741, + 1, + 707, + 741, + 1, + 711, + 741, + 1, + 749, + 741, + 1, + 772, + 741, + 1, + 611, + 742, + 1, + 707, + 742, + 1, + 711, + 742, + 1, + 749, + 742, + 1, + 772, + 742, + 1, + 611, + 743, + 1, + 707, + 743, + 1, + 711, + 743, + 1, + 742, + 743, + 1, + 748, + 743, + 2, + 772, + 743, + 1, + 611, + 744, + 1, + 707, + 744, + 1, + 711, + 744, + 1, + 741, + 744, + 8, + 772, + 744, + 1, + 611, + 745, + 1, + 655, + 745, + 2, + 707, + 745, + 1, + 711, + 745, + 1, + 740, + 745, + 1, + 772, + 745, + 1, + 611, + 746, + 1, + 649, + 746, + 2, + 655, + 746, + 2, + 707, + 746, + 1, + 711, + 746, + 1, + 740, + 746, + 1, + 772, + 746, + 1, + 611, + 747, + 1, + 707, + 747, + 1, + 711, + 747, + 1, + 740, + 747, + 1, + 772, + 747, + 1, + 611, + 748, + 1, + 707, + 748, + 1, + 711, + 748, + 1, + 772, + 748, + 1, + 611, + 749, + 2, + 692, + 749, + 2, + 707, + 749, + 1, + 711, + 749, + 1, + 772, + 749, + 1, + 612, + 750, + 6, + 652, + 750, + 2, + 707, + 750, + 1, + 711, + 750, + 1, + 756, + 750, + 5, + 772, + 750, + 1, + 617, + 751, + 1, + 648, + 751, + 1, + 651, + 751, + 4, + 707, + 751, + 1, + 711, + 751, + 1, + 756, + 751, + 1, + 760, + 751, + 1, + 764, + 751, + 9, + 617, + 752, + 1, + 648, + 752, + 4, + 653, + 752, + 1, + 659, + 752, + 6, + 705, + 752, + 1, + 707, + 752, + 1, + 711, + 752, + 1, + 756, + 752, + 1, + 760, + 752, + 1, + 763, + 752, + 2, + 617, + 753, + 1, + 648, + 753, + 1, + 653, + 753, + 2, + 659, + 753, + 1, + 664, + 753, + 1, + 707, + 753, + 1, + 711, + 753, + 1, + 756, + 753, + 1, + 760, + 753, + 4, + 611, + 754, + 2, + 617, + 754, + 1, + 647, + 754, + 2, + 654, + 754, + 6, + 664, + 754, + 18, + 693, + 754, + 1, + 704, + 754, + 1, + 707, + 754, + 1, + 711, + 754, + 1, + 756, + 754, + 1, + 611, + 755, + 1, + 647, + 755, + 2, + 681, + 755, + 1, + 707, + 755, + 1, + 711, + 755, + 1, + 756, + 755, + 1, + 611, + 756, + 1, + 648, + 756, + 1, + 681, + 756, + 9, + 707, + 756, + 1, + 711, + 756, + 1, + 756, + 756, + 1, + 611, + 757, + 2, + 647, + 757, + 2, + 690, + 757, + 1, + 707, + 757, + 1, + 711, + 757, + 1, + 756, + 757, + 1, + 612, + 758, + 2, + 646, + 758, + 2, + 690, + 758, + 1, + 707, + 758, + 1, + 711, + 758, + 1, + 714, + 758, + 1, + 752, + 758, + 3, + 756, + 758, + 1, + 613, + 759, + 5, + 646, + 759, + 1, + 690, + 759, + 2, + 706, + 759, + 2, + 711, + 759, + 5, + 752, + 759, + 1, + 754, + 759, + 3, + 617, + 760, + 30, + 691, + 760, + 16, + 715, + 760, + 1, + 752, + 760, + 1, + 715, + 761, + 38 + ] + } + ], + "entities": [ + { + "__class": "PointMapEntity", + "metaData": { + "angle": 3 + }, + "points": [ + 3282, + 3298 + ], + "type": "robot_position" + }, + { + "__class": "PointMapEntity", + "metaData": { + "angle": 2 + }, + "points": [ + 3281, + 3323 + ], + "type": "charger_location" + } + ] +} \ No newline at end of file diff --git a/backend/test/lib/robots/dreame/res/map/l10su_1121_new_path.bin b/backend/test/lib/robots/dreame/res/map/l10su_1121_new_path.bin new file mode 100644 index 00000000..980fdb21 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/l10su_1121_new_path.bin @@ -0,0 +1 @@ +eF7tWsmOI7tyLcNeeGEDb_HWXtRaaeQ8XOAtSvOQmmddPAiSUrOUmkfDW_-C_8P-Dn-J1961DTOCmcpJVSXV0F190Qe4mRSTDJ4TDAbJ6vu3D__5N6l__8e__O9_PPzTQ_b_6g_8w389_NvDn_5H_--HH4Nvr8Lf48fjOjny60-v4QPUuAa_Cn_7F0Ha_9mB1R2er0sh-IZN3wP36Fdwn_mAMRRDfH6bGNLsntGCCIzvxz1qAsaomDtwx2BXEBg_gNvtB219bzHAIMjChdft26vLs2Iufb-jGESAhBuv2qcaqKJvjiBL4VcUY3v_UnTB38PBVxXjK94AovLriQFYa-vFmQjUQ783iLnMOMBP9VU8S4_iG9KySvfhfjEA928_11dxA8dbxdh-efj2gD_BuovbTXirGDqRN3B8QCFOw2tdgL4lxtb0JjFu3CUGI-gas6t4WYyrzi5eE_Pg_uH_aOESbHeKeR32gvn2MWK8a8JVdoBaUPTPL8bV5ePFvFhycKMYDzB7XYLqUukU_YxfwDVOAVyTcK3jm8TYRLxqnJKb7Su4ximAaxKudXyPGE-ri7KHjxDjrb78cqW9ax0_QcxdJ4BrnAJwiXHgbmDhA8XQTHaXFAhVh8AzcBHHwncQY6cFF9GbcI2UF34xz-NNYmzK3laWGEvUrbK-UU87NJyTiL_iU8Rc5uZKK-ePOm4xL6ijtQ4NbAhkri32ryHGX-GHizj8snCpCxSu49PEeCbiTjH-SpQFjzeKAbhJeuGI8TWDNeNtQxtC5Q8Tg7bcLL3AOwiFt9kzYl49f74iJlDAq0ug8m1i6BHZ9XY-3C_Gezu7X4xTfEkMhYvpNTwnxpu86Kdr-AYH-6ti6L0X6y7U7Bo3bpoZy6Sb6uu4yPdaCdZYQJ7uc4DlQvh0qXOoBWpeq3yXGDsj-HYVrPLUWAj62lrtnoNOUIwrtj5RDOoIMAeFN4qhgOhz_fK9v6cYF2wrz4rxsrbh0_LjxLiTgm3LXfbjmhgvLsyuNb2iwFV8vxgHHyzGVeXAVRksfqgYGmg0J3jsOniTGKvi-4qxVxCUPXYdBCgGcGUSruLK8vGJeXXbvBU2I495GOHC4DncKsY1NdfFvHduAgioCVB8tiLwIYCLZlt5YDA_nXciYN_LxxMtVoXv_SwuU2hr-onFuE6fNgKD-dm8EwH7jh8RnoMM4lYxgY7fXwyFxYPwCc6VTdJXH-AeqPgkMeB7u-izT3ERA2dML6HnZuYK9wD8g32EGLyA2WWffYoLYVfZxjNiboF_sA8RQ025yz54xHjW0BcVg_8WFdhnKC5h5pQveGbN3AL_YB8nBi8CfvMWbL6u8gX2nuGvvwH-0Zyl64GVUW-EZQr_enEVL86Mnb79H15HcLiraoLN7oNPqGfNePjgzEAzX-1NuMLyU8R4x3NL84uhuF77PHAer7D8DmKufnoX_lBiEEHjv8S8hvvEfLPC5l4EjV_Nzlea3YX7xPz548Rcm5urzW4D5qy7xbwJQeMfPDPg4o8QE9x4gpMXNH5lXt4lBod1xLhxaXALAu1-kJhnYEnyV78Vtne8w_uV_OmTxKCz3y4GI9h7e_AP_j3FvBN_KDEBXGH504r5sWvmY2H9_x9eBMVczRM34pPFWGvGyfQ-BMRcb3YjvouY5xkGxfhb3INPFoN4XsvPJ-Y5LRh7f-fDc_F4Ez5dDJKjZwn_0MDdL4bU-Nvdju8gBrQgTf_Qfh0W_O1ux6eLATWUtp_kzygGAu0qyZ9RzLMkf0IxHpI0EdhwPnnwc4h5lr4XIMar-lZ8ghqvRT_V14Fi_uENoGLuF_QQvPPb8F7n_ExvwHvEANzD3wTvpcv9Ay-YLvipvg5k5Cd6C-hi-0gxvnn2M70JfpY3whJzXc0z1a_B6eUneSv8LG_EJ4nBjn6Kt8PP8ka8NcxeBK5CP8F74Gd5I94q5oU1A_neOlq-FX6WN-KNYrwJ0CfGilw_wzvgZ3kj3irmpS363VruFfNgvS0xf38nXjs-vU_LVxPjp3cfPFRfA4QCfdsB7mf7CqxQCkTX54h5-TxgiXER8LN9BVRMsMrGh4pBV7kVwU8XHvAk54i5PjXPS7RmJlB1seen9yI8Kwx-uKnSpeAW8-AUackKs8vgV8VcrwVYkeWt-3gxTgA_E2juKXLEeGjZeEmM_XDVvVmMD5YEWwaFQ_o5OONDew-1l3Gt7ceJcRl6dk4C8GUgP7s78ePEYBNfLz-7O_F2Mb4t1kcrqMYVdTSP4dPby8_uTnyQGLpS3LYcFRa-OXVUxg8RY6_rF-EyQ20F4aujP72dnt9WbsLLYqxhvxfuSmdX8IoY19fvgHdq-VJiIAr8_O7CFxIDSt63aL6SGD-3u_GVxLxbzR9XTBCur5-Od2vxXmh-LP5YYgB-fnfhC4l5ePfk_BLzafglxsEvMZ-GX2Ic_BLzSXjvnknFXAo_FO-VQjSACCz4bX93vFuL81fOP4QY-6L6BcS8H46qnxzfXH92--nFuP8W8kvMl8IfSoxLzS8xXwy_xHxZXHZP_4fvhn953I7n_c22M1-255vH3zhZlniel1SJV7TQ43w7Nh5_e5T6HZXXOmq3p_W4x9DjpvP42--_cyExxIX4EPfXv4Yee6SzRF5L8kX5Z5GXWJYNcf8sWQVBDfG8EhIEISSwYkiStJAocqTfYDMno5KR1sQmG3rcrsl4dU4V5BDDcbKmSywp0CevC0qIEWSdJx9FWefIL4nVeTHEKKoucaQSnpwAT16X-BAj6yJpxLM6IcAIxAAZX9X5kMTRBxciBqAn9mFxHNJTwArWfvLY5PKkjDj7SevRANTwrqcQqLn0Qk3YSdRFiVjhdYZHPQzRQ6gxAv1F2ko8fVGqEtiiRY61-xKXcKIuEAuCpvPkJSo6RwyJqi4SQ7wGnSSbqUD7U6XUu8Q3Ygj6iiFR0gUJ_EScJgi6oIUECVhRp7E6G5IEIERJEnKsVctZtYQGsUQGQKmOUl7nHAMilND_jAYe1cgQKkweQyTx8OJDvEpf5BsJCGDBsyEy84wMw-LYHI5IniIYEEO8ojOgkrgMXE7s0Hm8VKJWCB3SgQN3En7U4Zb7aVQxvIRBxmDMgX4SdEhLI2Rd9rgQkFRCHLwEpAxRRtiQaSCuJI1RJCoHtiRiqQgRFgVaYJEsPMFdwBGetJ511bu_8laZ9mWcz_QpeJpKtEy9wdFWMrYS8TvVQ93jlCHCLi8qA1WI4Hge_I6Tfpl5ShTG4tAKj1YoE0o3KI8aJ5MMMUrmRoJwYiQRnwI-YQS73i7jegh-gBUNs4cZgoQuqRPJL1JJFgKsB_JNxqe9yvAbWSsavkgAMbxopw6c6bqgykBSZsmygLghrUic4vKCmCPBLsIyVVE4j9qgAXEvaU1sEhIiRhxZfopCRBO75Csnw0cGvoL3aHdZDbF1kn9J7HG8pEC9EuIhVqSQLJCFTRwlkDCS2ZCGMQrJlfSTQhwr6qSfAC7nZTICyXYQq6CUBqcGEwRLWtRJBYjgITuShYdfGPqJkQgDQYIJUakGVobJBEkQzCqELk_St6BzEokesmOAm1AUD54GUbwKkhmQCE8NvKqTSpXkFxbmHawRvgqYYeiiYEQOFzrHogQWEqM9Kl1J4E6SzkhUkWkmSgWyT7CEp6aAo0KQDRnYDGDRWQHAQwAodpKEtc9ZL8KBvIgvBQgAnrbEWYHo4GDxqzQCROhAlg7RSSzb-wn5QnYiO8BU9AfmI0yALMQExDbuSJ5txE63yMKu4VxfaRkWhP2k9bzreWnjrqGWsYzmRbpfwqzRkLfynBCClcXwVCmQxGTNw25AtzGVLgQF9gSQKcNiIQtIoG0FVIT7JSx0ycrxZGiFzJflDZrkSCok4U1cDRuJiCtFhdlmrX0DQh-K8LS2Y_dGwtl-RLXI0NIHgYg7OUw6bkg0zUo0j_IQPSrZ9Ml847YgYiYnWhgavLg4NdxJOEhonLU3QVBDJifCSE8UCQmLoT98G4mgkxEIew7CgMQ2dSx4W4D1hk4n3oBIZDDcIKQhgIAUxBas3UuChzVAFiVdCgKsSI7uIywuKhU9gkwFoA5MNewPPSEMgJUA0-BPtP6yrcpfYydpSsjxJi5JYtrZRmC5gy_4EOy3dAOh6d7el6jDaBkp0RddyuhwPAGgIJxAnHE6oWDEb8W939l23QzBbXwIdhGMbIG--MsLZoW1X3g00iA6GTjnwMRqkNVgpjiYMEiK2JD2gvi_mII6ni4jsMthc4gnMrd1kYdgkEmgwQcNjgMcHCUkiQS2poKfwBEaEaBClqdjQHvSzhoMZCgXH_MYBWS_Bk32QYceNOyzCB74WEqJBU4C5YSxZqVRoChhhifxJIuQmEny5Agv6Caq4BvqFeeoY3VT4OhFliVEoU2AHs5Qi0UAQxWEQsIBQvRAxuD2hVse7B64AskFALTwFy20CYNtILOqsJuLGgzut-TsCCxYEjUghSdQtET9BlkbdJI1T0mxdDzqX9gNJEoKOltpgZgAH8BGTX0igbPwiEhtM5ZiFCziDsd7nUKPnyKkHXt8mDlGhuMeB8okGUwTz2NcUNb0gAuswYPWxkWSMIYraw1PrEArGB50y3TDUSFNYHxxkLWs0KVOU-lR1gpbaIcv-sN6QsTjzowviAOJvmTMadAExMCMQngTk9iFw40BEjv5ylsvHrZmIAl3N7hlQRO6nOwVp9JtAjctGfO6tXHgSQTuANbc0BM0ZnRMEJgvqHboRfvScxrdsegOG9xt6T4b3Ft95WCN3R4HxJJE9YGbqT8hRDjqXe6SDuB12bKwJ-5buGVRF1C_Qixw9oX2whEfyJ-Fjqy14YEJiFYJzqlw_iLTj7s7BK4C4UOWLNk4SCDg8cu1H6L7aJlurDw-abLFXCxBlpXguCBBHkcCcDITIRnTDhhDUCbNiH1QJ-PLWZBwabP2WGAgu68-HDwh2jnrgAhPMMDD3Yk6HF88tQ0v9AjdhSC8NTxuYnDTE5qVb3EoBrIZubKCKxmVzIDCUguUMW6PLK5162oJV1rShZy2oSUKxFMJ3VLhaAFtrRQnQERdeMHV2dki6QCW_UuN-2lf6-BJtzDbApRFa8sEp9LEAi_aj3pYxDJ9Uhq0kUshhir4mnDHPRU9bd_XrY2VhAl4jYxIOVAtdHTb0Q5zdxmMW1nJjnx48fQFI-MvCGvrQkauTBosZ7gy8eTcQ24fmhBSYRgZ4gxjhlijBxvruCgQJ0gKuAgiXcRIp_kGrxL0fiSR8IL7EVlJJOtBUmXJ9JABOUz65NZA8pYKtx7iHLhs0DuWBsdPsqVB1iKE6QB4l1FxeI5ez8iNy_IlkGYhuERyY4NdiYwow1-cyJKRHkOPM36Nf7bqjNuL7mbb6c36j7_9_lesGOzW5ni7W_fbhw4pmcPH33jvB_jrmSAomOpIcMMf0ngZolzAn3Cp41mW_Wvod17DapY8yWTZrUTylIlAlbZRsRJ2AeJWtyWRtdvAtgbDwRMakWihwyueVmCYLCZSSe58ZAeCnxIPhuGeSXjBn_pA827bXayN_noDUshhBYxhQ1pWyX9gkJNxFPLAkl3NQ4G2p0UO2MIXEcnjT1qEvkjNNYaru2PN1edizRn-mjHo5qFFm2t2NeUNA4D7qVVaxCYOKZFFAkgDy65v6GG3t_0GHfLwxaHgGwmqL4RpKTAXbd7wTAeOCWWw4ngXqyxPAS_3F-uD3UHGgEBLtChClMEXxflJi2jV-YKW7S--KbxYw6IzjsvaZRwXZd84LgWuIb1irhEAbR6R1szRpWaVL_MBa4G6G0r2dNA1hvRpkSQGz7QL-KTGsOwOCfdAUPZOsDMiSkE7oIwWcUhr5p1EY_YPmFNwwYoQOZhT6E8YFNIJXcAhknmgGhMEOTqEMHFQkpAJaBuZtkG3kzYytkHDThuGUoV_LsDk5PYd5AuSoVA0Zh5MWZBTrAWBicjhpGCwgkKSmkMy-Bl9AFlOpGlnvegutu35wiDpk2Tux_V4g4mVvOePvz3248p2novv-HOzOtrWd4OmYTDaItHNGjw7OYe1YTM6HOuL2rp32ERn8flK7I5nUiq-1Q4VJbkW-sfxIVnMp1tJtVSdT0vR2UkeMqliOlZlGsy4FN0y8WmjNDkmz4NBZT84a_ETM96XY8V2O11g9Pq-YEZn59OqlBfjNS2W4obKqbtaT7lBPhzNjjsGwzcjhZioxKrr4lOmVxampt5ozyOZzETU0-VFo6SUEvVaOdUV63K4EV7V2plybFlbp9SBuR5HYjGxc2D7y-p-IolSfWzwWyMtRqqzCaPH-sVaItsbG1JstZgulD5_GjKjZS524mOTOBePb5R5Wq0sZ1KSXZ20TCqhJypGNr6KnxeSXFO3u8lYFsxxozDqqmZxoiWf8gJ7jq8KlchweyyUj71ZKpaW9uzYjEfmT4elcBhIcnaQGw_OAyOZyQ1b5-nkGF-elKYZO2UKpf26xyql1WD4tFpm5XKnNy43F9vpMsdmphmTj6SkUqd3MlKL3HSR6O12RyHc4fITpZR_Om9q80OZLxfSRrVc39XixWIikjqsq8qsvCo113K2qu75I1udq8tILpEtxZtiVRLT8ulQTOcSsWozfVxlxWxD6M8TnWlVWrSztU61KrBCoxMvN-vGcMmccpV9PZbez_TzSWMiczY-mmZmh6GUiDRb6ja-66-fMoJRX3LTPSNHxEN5kkunn2YJQ20UIrFUbGlGysu5UW4ZT0_msNTIh5OpU2ll1udPw2yzWhuOKvmwmR6N4xmlNDpUY6PhKJuJ9JhOJsvmD_NsFdtsR8ROfMTJfOocTsSbsZqyONdXRSNsDsZGed5oJcK9UiKTzxyelsJwsiC-qdcmjVhpWEmsIoXVZHhuD4_JWSSVb2TPJzY3rMwizcmaa3SmGaOWivTE0rSZ6cstLjycLCM9c3Ba9o7r06o9neSr09hyaEZTMUUabKR4Iqc9NdOLQzSfmBbMedesKku-tyFX8VRtWI9Fsq1xpbGSws3wMAqao_ljVZNMPReVFKajNPlMP7Ga5VfH02ax363EQ7-QWvFh8UmMj4yCbhQWo8qunm3lEp1zcWTU1uNVVF2XDHW9eqpMaoXGqWYkhNI-M-otI5XZVpJqi9Z4aG43qVWzxfK7XO1QGbVi5245XFP341lGL47lhLGKzTmt0zztkvzoaTJP83NTnw3D1fBEVfK9grLlopXZaCuzNZHX-saisjuEe_x2zObL4UNqOclv56XmarIe9iKZo9AvRzLnxWQ_y0pycaEl0uJSEVPioWgWWNYcKrmKcSjlC5Fwgc3OthMlrB4HrbiYPUUXyfY40SnV0v3zeKJGlyM1sjpwZWMT6yXDWbH9VKhl0sxmOuunxNFqNhFHsyfDiBYSYixd3BT2sc4guQ7XB8n82Zz0nrKHemxW5zq7bSqq7cOxZqoyikgxtdla1rlaNzLIHVKTUcZQO_XoajFaSE_lfi3e0xPlTW7YjkkdbjkScs3aKjsZztLcICUbkfS0stU4MTkyU6XjaBEz5LwWS0TmvVi2k-4VW0PR7I7zyV02m1H1UavAHsbR0SEbzjfjo2QjfV7JSyG8zkgkHHrZtHouJ9hYspJf5EdmbVqNGHKpkjCjx0l92pLyh8kknD0m0olkQR4myFh9o7qpRPOMrurn_DQ6MuvTNZeN5hKVbfyomtnE4Sz1Ovv8qVEYVOfsihdi81yqUGjElFSLLRfDm-NxWWLklNk91SqZ4nRebuab_DKdn-njQWKWlJtzY58yjZJQf-qWt_Ucx65K40p-mlyOu-ya3a0qqWp0cN6wk_qikdkkMrH9_NDsVDvZbKc6GJXTRlGSd5XTqLhXtrFM8dAo7zdFQUssS4sDjB1PTfXobDQKtw6HxmiTro0iIzOhM82Z_HSq78Mjsc1nU-dFpTI0mYnaSCn9SHmWSG47i-JpMWOa0eVQHDfz6mo814_jQpU_yJ1etRPdZxbLcTs8zomx3i4zOCdKWb2bCA8MrcJKxrCUaPfM_CiZfdqdxk1RHeqt9DZdEGrbfCOdnpRmbNOc1RQusVw8JTjmPOUXamI4nWv5wcZ4KpYr-UmB709TpG3RlAe7WqzKJRdsLNZeTYgLo-FwQc6eZXORZqTmITbpmzk-P0w1N0_ZSY9djJluLq2r3blWOKbz-4apRItipN9dH7bjHrPWcguBRExs34yk2UPzyUhIUmlYnDPlTcXkBnIhsTyWj7WydthHc-Z-zDOVpNIu6CaT3c-4rabl13OtXzkNBJ5T-638XNgdtCoTXRkDfdJVShrPCIaw2SVzyr67Y9VCwWgb-227N9jIqy4_0E-9CW-sWwNdyU5mK-a4b5tLeaONiodzSull5ovGLB3WloP4sbEgq6fZTSxyhVYrsVsWW1p0x51yrSVfqcw7863IJ-Lc_JjWjcaxUctOjFw2oiVn1cZuMc1spdHpqSmEWx1ut9v1-bGezz9lJidu9TQ8xLh6Y1hvLLe1k25I7Z2m7JKVdp8dRnsNplpkhWSRa3R1PtxidlI7t2Gj5mBTM3qVSq5XSRvxNVfjhczZZE_7liQu1nHNPGZGWz3BTzm9vc7Gh7v-ZKFUy4NBtb9NPm206mqlHaeqyonNuKyt09x50TO3g_2u1e1O1mMzc5pUTjOGzJ-6TS-l2TGxU4-bfEHfDM1lKbydman2tpgeNFq9sNqvF-otvTwZd2NmWta704y6EKZSeq6J3casJUitZTy334TVCFeel4Ul31qX6mtFXyS4ZaIxKcv7005X8z2hXjfbAzOjmTGR6W7bg9Zc7e5bPT0_OatMOd7l5f2ypRvtXZubkHkjJ6puV-gLu26jo-trvbtZtQQjU5P1FavFtdJ61Vht1zonrnVS6Eb500hMyqYRbg-K6b2paEkttxbCsb88_uv_A14flvY= \ No newline at end of file diff --git a/backend/test/lib/robots/dreame/res/map/l10su_1121_new_path.json b/backend/test/lib/robots/dreame/res/map/l10su_1121_new_path.json new file mode 100644 index 00000000..80fab0e8 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/l10su_1121_new_path.json @@ -0,0 +1,5655 @@ +{ + "__class": "ValetudoMap", + "metaData": { + "version": 2 + }, + "size": { + "x": 6554, + "y": 6554 + }, + "pixelSize": 5, + "layers": [ + { + "__class": "MapLayer", + "metaData": { + "segmentId": "1", + "active": true, + "source": "regular", + "area": 39675 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 686, + "max": 747, + "mid": 717, + "avg": 717 + }, + "y": { + "min": 654, + "max": 690, + "mid": 672, + "avg": 673 + }, + "pixelCount": 1587 + }, + "compressedPixels": [ + 686, + 654, + 17, + 686, + 655, + 17, + 686, + 656, + 17, + 686, + 657, + 17, + 686, + 658, + 17, + 686, + 659, + 17, + 686, + 660, + 17, + 686, + 661, + 22, + 686, + 662, + 45, + 733, + 662, + 11, + 686, + 663, + 45, + 733, + 663, + 13, + 686, + 664, + 60, + 686, + 665, + 60, + 686, + 666, + 60, + 686, + 667, + 45, + 733, + 667, + 11, + 746, + 667, + 2, + 686, + 668, + 45, + 733, + 668, + 11, + 746, + 668, + 2, + 686, + 669, + 62, + 686, + 670, + 62, + 686, + 671, + 62, + 687, + 672, + 61, + 688, + 673, + 60, + 689, + 674, + 59, + 688, + 675, + 60, + 688, + 676, + 60, + 690, + 677, + 58, + 692, + 678, + 56, + 695, + 679, + 53, + 696, + 680, + 50, + 695, + 681, + 51, + 696, + 682, + 50, + 696, + 683, + 10, + 709, + 683, + 37, + 696, + 684, + 10, + 723, + 684, + 23, + 697, + 685, + 9, + 723, + 685, + 23, + 701, + 686, + 5, + 723, + 686, + 23, + 701, + 687, + 5, + 723, + 687, + 23, + 702, + 688, + 4, + 723, + 688, + 23, + 723, + 689, + 3, + 727, + 689, + 17, + 745, + 689, + 1, + 727, + 690, + 16 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "2", + "active": false, + "source": "regular", + "area": 56225 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 605, + "max": 681, + "mid": 643, + "avg": 642 + }, + "y": { + "min": 629, + "max": 672, + "mid": 651, + "avg": 654 + }, + "pixelCount": 2249 + }, + "compressedPixels": [ + 673, + 629, + 9, + 673, + 630, + 9, + 672, + 631, + 10, + 672, + 632, + 10, + 671, + 633, + 11, + 671, + 634, + 11, + 671, + 635, + 11, + 674, + 636, + 8, + 674, + 637, + 8, + 608, + 638, + 65, + 675, + 638, + 7, + 608, + 639, + 65, + 674, + 639, + 8, + 609, + 640, + 64, + 678, + 640, + 4, + 611, + 641, + 62, + 678, + 641, + 4, + 611, + 642, + 62, + 611, + 643, + 62, + 611, + 644, + 62, + 611, + 645, + 62, + 611, + 646, + 62, + 611, + 647, + 62, + 611, + 648, + 62, + 611, + 649, + 62, + 612, + 650, + 61, + 608, + 651, + 65, + 608, + 652, + 65, + 609, + 653, + 64, + 609, + 654, + 64, + 608, + 655, + 65, + 609, + 656, + 2, + 612, + 656, + 61, + 612, + 657, + 61, + 610, + 658, + 63, + 611, + 659, + 62, + 611, + 660, + 62, + 610, + 661, + 63, + 610, + 662, + 63, + 610, + 663, + 63, + 610, + 664, + 63, + 610, + 665, + 43, + 654, + 665, + 19, + 606, + 666, + 21, + 629, + 666, + 24, + 655, + 666, + 3, + 660, + 666, + 13, + 607, + 667, + 20, + 629, + 667, + 24, + 660, + 667, + 13, + 607, + 668, + 20, + 628, + 668, + 25, + 660, + 668, + 12, + 606, + 669, + 47, + 659, + 669, + 13, + 606, + 670, + 47, + 605, + 671, + 48, + 605, + 672, + 48 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "3", + "active": false, + "source": "regular", + "area": 24500 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 748, + "max": 802, + "mid": 775, + "avg": 776 + }, + "y": { + "min": 662, + "max": 682, + "mid": 672, + "avg": 673 + }, + "pixelCount": 980 + }, + "compressedPixels": [ + 762, + 662, + 17, + 782, + 662, + 8, + 791, + 662, + 3, + 797, + 662, + 3, + 762, + 663, + 17, + 782, + 663, + 8, + 791, + 663, + 3, + 797, + 663, + 3, + 761, + 664, + 34, + 796, + 664, + 4, + 761, + 665, + 39, + 767, + 666, + 34, + 748, + 667, + 8, + 767, + 667, + 22, + 791, + 667, + 10, + 748, + 668, + 14, + 767, + 668, + 1, + 770, + 668, + 8, + 781, + 668, + 8, + 791, + 668, + 4, + 797, + 668, + 4, + 748, + 669, + 14, + 767, + 669, + 1, + 770, + 669, + 9, + 782, + 669, + 12, + 797, + 669, + 3, + 748, + 670, + 15, + 765, + 670, + 28, + 797, + 670, + 3, + 748, + 671, + 45, + 797, + 671, + 4, + 748, + 672, + 47, + 796, + 672, + 7, + 748, + 673, + 47, + 796, + 673, + 7, + 748, + 674, + 55, + 748, + 675, + 55, + 748, + 676, + 55, + 748, + 677, + 55, + 748, + 678, + 55, + 748, + 679, + 55, + 751, + 680, + 52, + 751, + 681, + 52, + 751, + 682, + 52 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "4", + "active": false, + "source": "regular", + "area": 78150 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 712, + "max": 802, + "mid": 757, + "avg": 747 + }, + "y": { + "min": 691, + "max": 760, + "mid": 726, + "avg": 729 + }, + "pixelCount": 3126 + }, + "compressedPixels": [ + 727, + 691, + 16, + 727, + 692, + 16, + 727, + 693, + 16, + 727, + 694, + 17, + 727, + 695, + 19, + 727, + 696, + 19, + 727, + 697, + 19, + 727, + 698, + 19, + 727, + 699, + 19, + 727, + 700, + 19, + 727, + 701, + 19, + 729, + 702, + 17, + 729, + 703, + 17, + 729, + 704, + 17, + 727, + 705, + 19, + 727, + 706, + 19, + 727, + 707, + 19, + 727, + 708, + 19, + 727, + 709, + 19, + 727, + 710, + 19, + 726, + 711, + 20, + 724, + 712, + 67, + 799, + 712, + 2, + 724, + 713, + 67, + 797, + 713, + 1, + 799, + 713, + 3, + 724, + 714, + 67, + 798, + 714, + 5, + 724, + 715, + 67, + 796, + 715, + 7, + 724, + 716, + 68, + 796, + 716, + 7, + 724, + 717, + 79, + 724, + 718, + 79, + 724, + 719, + 79, + 724, + 720, + 79, + 724, + 721, + 78, + 724, + 722, + 71, + 722, + 723, + 61, + 784, + 723, + 1, + 792, + 723, + 3, + 722, + 724, + 61, + 791, + 724, + 4, + 722, + 725, + 61, + 791, + 725, + 4, + 722, + 726, + 51, + 775, + 726, + 8, + 791, + 726, + 4, + 722, + 727, + 49, + 793, + 727, + 2, + 722, + 728, + 49, + 774, + 728, + 2, + 793, + 728, + 2, + 722, + 729, + 47, + 772, + 729, + 4, + 791, + 729, + 4, + 722, + 730, + 46, + 772, + 730, + 5, + 791, + 730, + 4, + 722, + 731, + 31, + 755, + 731, + 13, + 771, + 731, + 6, + 791, + 731, + 4, + 716, + 732, + 27, + 747, + 732, + 4, + 755, + 732, + 13, + 771, + 732, + 7, + 791, + 732, + 4, + 716, + 733, + 26, + 755, + 733, + 12, + 771, + 733, + 7, + 791, + 733, + 4, + 716, + 734, + 26, + 750, + 734, + 2, + 755, + 734, + 12, + 771, + 734, + 7, + 792, + 734, + 3, + 712, + 735, + 30, + 750, + 735, + 18, + 771, + 735, + 6, + 791, + 735, + 4, + 712, + 736, + 30, + 750, + 736, + 18, + 771, + 736, + 7, + 791, + 736, + 4, + 712, + 737, + 30, + 750, + 737, + 18, + 771, + 737, + 7, + 712, + 738, + 28, + 750, + 738, + 13, + 712, + 739, + 28, + 750, + 739, + 12, + 712, + 740, + 28, + 750, + 740, + 11, + 764, + 740, + 4, + 712, + 741, + 28, + 750, + 741, + 11, + 763, + 741, + 7, + 712, + 742, + 28, + 750, + 742, + 11, + 763, + 742, + 7, + 771, + 742, + 1, + 712, + 743, + 28, + 750, + 743, + 12, + 763, + 743, + 9, + 712, + 744, + 28, + 749, + 744, + 12, + 763, + 744, + 9, + 712, + 745, + 15, + 729, + 745, + 11, + 741, + 745, + 20, + 763, + 745, + 9, + 712, + 746, + 15, + 729, + 746, + 11, + 741, + 746, + 21, + 766, + 746, + 1, + 768, + 746, + 4, + 712, + 747, + 15, + 728, + 747, + 12, + 741, + 747, + 22, + 767, + 747, + 5, + 712, + 748, + 60, + 712, + 749, + 48, + 761, + 749, + 11, + 712, + 750, + 44, + 761, + 750, + 11, + 712, + 751, + 44, + 712, + 752, + 44, + 712, + 753, + 44, + 712, + 754, + 44, + 712, + 755, + 44, + 712, + 756, + 44, + 712, + 757, + 44, + 712, + 758, + 1, + 716, + 758, + 36, + 755, + 758, + 1, + 716, + 759, + 36, + 718, + 760, + 33 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "segmentId": "5", + "active": false, + "source": "regular", + "area": 174325 + }, + "type": "segment", + "pixels": [], + "dimensions": { + "x": { + "min": 600, + "max": 706, + "mid": 653, + "avg": 657 + }, + "y": { + "min": 673, + "max": 759, + "mid": 716, + "avg": 713 + }, + "pixelCount": 6973 + }, + "compressedPixels": [ + 605, + 673, + 48, + 605, + 674, + 48, + 656, + 674, + 11, + 669, + 674, + 12, + 605, + 675, + 49, + 656, + 675, + 11, + 669, + 675, + 12, + 605, + 676, + 78, + 687, + 676, + 1, + 606, + 677, + 21, + 629, + 677, + 53, + 683, + 677, + 2, + 686, + 677, + 4, + 606, + 678, + 21, + 629, + 678, + 53, + 683, + 678, + 9, + 605, + 679, + 49, + 656, + 679, + 11, + 669, + 679, + 13, + 683, + 679, + 12, + 605, + 680, + 49, + 656, + 680, + 11, + 669, + 680, + 11, + 683, + 680, + 13, + 601, + 681, + 3, + 605, + 681, + 49, + 656, + 681, + 25, + 683, + 681, + 12, + 601, + 682, + 81, + 683, + 682, + 13, + 600, + 683, + 96, + 600, + 684, + 96, + 600, + 685, + 97, + 600, + 686, + 98, + 600, + 687, + 97, + 600, + 688, + 96, + 600, + 689, + 96, + 600, + 690, + 98, + 600, + 691, + 99, + 600, + 692, + 94, + 696, + 692, + 4, + 600, + 693, + 94, + 696, + 693, + 5, + 600, + 694, + 105, + 600, + 695, + 106, + 600, + 696, + 107, + 600, + 697, + 90, + 692, + 697, + 2, + 696, + 697, + 11, + 600, + 698, + 27, + 628, + 698, + 3, + 633, + 698, + 56, + 692, + 698, + 2, + 696, + 698, + 11, + 600, + 699, + 26, + 633, + 699, + 72, + 600, + 700, + 3, + 606, + 700, + 8, + 633, + 700, + 39, + 673, + 700, + 16, + 691, + 700, + 16, + 601, + 701, + 2, + 606, + 701, + 8, + 633, + 701, + 38, + 672, + 701, + 17, + 691, + 701, + 16, + 606, + 702, + 8, + 633, + 702, + 74, + 606, + 703, + 8, + 633, + 703, + 21, + 656, + 703, + 51, + 606, + 704, + 8, + 633, + 704, + 18, + 652, + 704, + 2, + 656, + 704, + 51, + 606, + 705, + 8, + 633, + 705, + 74, + 606, + 706, + 8, + 633, + 706, + 74, + 606, + 707, + 8, + 633, + 707, + 69, + 704, + 707, + 3, + 606, + 708, + 8, + 633, + 708, + 21, + 655, + 708, + 47, + 704, + 708, + 3, + 621, + 709, + 7, + 633, + 709, + 15, + 655, + 709, + 52, + 621, + 710, + 6, + 633, + 710, + 15, + 658, + 710, + 49, + 621, + 711, + 6, + 633, + 711, + 15, + 651, + 711, + 4, + 657, + 711, + 50, + 621, + 712, + 6, + 633, + 712, + 15, + 650, + 712, + 6, + 657, + 712, + 50, + 621, + 713, + 7, + 637, + 713, + 11, + 649, + 713, + 7, + 657, + 713, + 50, + 621, + 714, + 7, + 633, + 714, + 15, + 649, + 714, + 7, + 657, + 714, + 50, + 621, + 715, + 6, + 633, + 715, + 15, + 649, + 715, + 7, + 657, + 715, + 14, + 673, + 715, + 34, + 621, + 716, + 6, + 629, + 716, + 1, + 633, + 716, + 15, + 650, + 716, + 6, + 657, + 716, + 14, + 673, + 716, + 15, + 690, + 716, + 17, + 621, + 717, + 9, + 633, + 717, + 15, + 649, + 717, + 7, + 657, + 717, + 31, + 690, + 717, + 17, + 615, + 718, + 16, + 633, + 718, + 15, + 649, + 718, + 7, + 657, + 718, + 31, + 689, + 718, + 18, + 615, + 719, + 16, + 633, + 719, + 15, + 649, + 719, + 7, + 657, + 719, + 32, + 703, + 719, + 4, + 615, + 720, + 16, + 632, + 720, + 16, + 649, + 720, + 7, + 657, + 720, + 33, + 696, + 720, + 3, + 702, + 720, + 5, + 615, + 721, + 33, + 657, + 721, + 32, + 690, + 721, + 9, + 700, + 721, + 7, + 615, + 722, + 33, + 657, + 722, + 31, + 690, + 722, + 9, + 700, + 722, + 7, + 615, + 723, + 33, + 649, + 723, + 7, + 657, + 723, + 16, + 678, + 723, + 10, + 689, + 723, + 10, + 700, + 723, + 7, + 615, + 724, + 33, + 649, + 724, + 7, + 657, + 724, + 10, + 678, + 724, + 10, + 689, + 724, + 10, + 700, + 724, + 7, + 615, + 725, + 33, + 649, + 725, + 7, + 658, + 725, + 19, + 678, + 725, + 10, + 689, + 725, + 10, + 700, + 725, + 7, + 615, + 726, + 19, + 637, + 726, + 11, + 650, + 726, + 7, + 658, + 726, + 9, + 668, + 726, + 9, + 679, + 726, + 9, + 689, + 726, + 10, + 700, + 726, + 7, + 612, + 727, + 23, + 638, + 727, + 11, + 650, + 727, + 7, + 658, + 727, + 9, + 668, + 727, + 9, + 679, + 727, + 9, + 689, + 727, + 10, + 700, + 727, + 7, + 612, + 728, + 17, + 631, + 728, + 3, + 639, + 728, + 10, + 650, + 728, + 7, + 658, + 728, + 9, + 668, + 728, + 9, + 679, + 728, + 9, + 689, + 728, + 10, + 700, + 728, + 7, + 613, + 729, + 3, + 619, + 729, + 9, + 639, + 729, + 10, + 650, + 729, + 7, + 658, + 729, + 9, + 668, + 729, + 10, + 679, + 729, + 9, + 689, + 729, + 10, + 700, + 729, + 7, + 615, + 730, + 1, + 619, + 730, + 9, + 640, + 730, + 8, + 650, + 730, + 7, + 658, + 730, + 20, + 679, + 730, + 9, + 689, + 730, + 10, + 700, + 730, + 7, + 619, + 731, + 9, + 640, + 731, + 8, + 649, + 731, + 8, + 658, + 731, + 9, + 668, + 731, + 10, + 679, + 731, + 9, + 689, + 731, + 10, + 700, + 731, + 7, + 619, + 732, + 9, + 640, + 732, + 8, + 649, + 732, + 8, + 658, + 732, + 9, + 668, + 732, + 10, + 679, + 732, + 9, + 689, + 732, + 10, + 700, + 732, + 7, + 619, + 733, + 9, + 640, + 733, + 8, + 650, + 733, + 3, + 655, + 733, + 2, + 658, + 733, + 30, + 689, + 733, + 10, + 700, + 733, + 7, + 619, + 734, + 9, + 640, + 734, + 8, + 650, + 734, + 3, + 655, + 734, + 2, + 658, + 734, + 30, + 689, + 734, + 10, + 700, + 734, + 7, + 619, + 735, + 9, + 640, + 735, + 8, + 649, + 735, + 8, + 658, + 735, + 30, + 689, + 735, + 10, + 700, + 735, + 7, + 619, + 736, + 9, + 633, + 736, + 2, + 636, + 736, + 1, + 639, + 736, + 9, + 649, + 736, + 8, + 658, + 736, + 30, + 689, + 736, + 10, + 700, + 736, + 7, + 613, + 737, + 1, + 619, + 737, + 11, + 632, + 737, + 6, + 639, + 737, + 8, + 649, + 737, + 8, + 658, + 737, + 30, + 689, + 737, + 10, + 700, + 737, + 7, + 613, + 738, + 33, + 649, + 738, + 8, + 658, + 738, + 30, + 689, + 738, + 10, + 700, + 738, + 7, + 613, + 739, + 33, + 649, + 739, + 8, + 658, + 739, + 4, + 669, + 739, + 19, + 689, + 739, + 10, + 700, + 739, + 7, + 612, + 740, + 36, + 649, + 740, + 8, + 669, + 740, + 19, + 689, + 740, + 10, + 700, + 740, + 7, + 612, + 741, + 22, + 635, + 741, + 13, + 649, + 741, + 8, + 659, + 741, + 9, + 669, + 741, + 19, + 689, + 741, + 10, + 700, + 741, + 7, + 612, + 742, + 36, + 649, + 742, + 9, + 659, + 742, + 9, + 669, + 742, + 19, + 689, + 742, + 10, + 700, + 742, + 7, + 612, + 743, + 36, + 649, + 743, + 9, + 659, + 743, + 9, + 669, + 743, + 19, + 689, + 743, + 10, + 700, + 743, + 7, + 612, + 744, + 36, + 649, + 744, + 9, + 659, + 744, + 9, + 669, + 744, + 19, + 689, + 744, + 10, + 700, + 744, + 7, + 612, + 745, + 36, + 651, + 745, + 4, + 657, + 745, + 1, + 659, + 745, + 9, + 669, + 745, + 19, + 689, + 745, + 10, + 700, + 745, + 7, + 612, + 746, + 36, + 651, + 746, + 4, + 657, + 746, + 1, + 659, + 746, + 9, + 669, + 746, + 19, + 689, + 746, + 10, + 700, + 746, + 7, + 612, + 747, + 2, + 618, + 747, + 40, + 659, + 747, + 9, + 669, + 747, + 19, + 689, + 747, + 10, + 700, + 747, + 7, + 618, + 748, + 33, + 653, + 748, + 1, + 655, + 748, + 3, + 659, + 748, + 9, + 669, + 748, + 19, + 689, + 748, + 3, + 694, + 748, + 5, + 701, + 748, + 6, + 618, + 749, + 34, + 654, + 749, + 4, + 659, + 749, + 33, + 694, + 749, + 6, + 703, + 749, + 4, + 619, + 750, + 29, + 649, + 750, + 2, + 654, + 750, + 4, + 659, + 750, + 48, + 619, + 751, + 28, + 655, + 751, + 3, + 665, + 751, + 23, + 689, + 751, + 16, + 619, + 752, + 28, + 654, + 752, + 4, + 665, + 752, + 39, + 706, + 752, + 1, + 619, + 753, + 28, + 681, + 753, + 26, + 619, + 754, + 28, + 682, + 754, + 4, + 695, + 754, + 8, + 615, + 755, + 3, + 619, + 755, + 28, + 691, + 755, + 16, + 614, + 756, + 33, + 690, + 756, + 17, + 614, + 757, + 32, + 691, + 757, + 16, + 614, + 758, + 30, + 691, + 758, + 16, + 693, + 759, + 11 + ] + }, + { + "__class": "MapLayer", + "metaData": { + "area": 35775 + }, + "type": "wall", + "pixels": [], + "dimensions": { + "x": { + "min": 599, + "max": 803, + "mid": 701, + "avg": 702 + }, + "y": { + "min": 636, + "max": 761, + "mid": 699, + "avg": 703 + }, + "pixelCount": 1431 + }, + "compressedPixels": [ + 609, + 636, + 64, + 607, + 637, + 3, + 672, + 637, + 2, + 606, + 638, + 2, + 673, + 638, + 2, + 606, + 639, + 1, + 674, + 639, + 1, + 606, + 640, + 2, + 674, + 640, + 1, + 605, + 641, + 3, + 674, + 641, + 1, + 605, + 642, + 1, + 674, + 642, + 1, + 605, + 643, + 1, + 674, + 643, + 1, + 605, + 644, + 1, + 674, + 644, + 1, + 605, + 645, + 1, + 608, + 645, + 2, + 674, + 645, + 1, + 605, + 646, + 1, + 608, + 646, + 2, + 674, + 646, + 1, + 674, + 647, + 1, + 674, + 648, + 1, + 674, + 649, + 1, + 607, + 650, + 3, + 674, + 650, + 1, + 607, + 651, + 1, + 674, + 651, + 1, + 607, + 652, + 1, + 674, + 652, + 1, + 607, + 653, + 1, + 674, + 653, + 1, + 685, + 653, + 19, + 607, + 654, + 1, + 674, + 654, + 1, + 685, + 654, + 1, + 703, + 654, + 1, + 607, + 655, + 1, + 674, + 655, + 1, + 685, + 655, + 1, + 703, + 655, + 1, + 607, + 656, + 1, + 674, + 656, + 1, + 685, + 656, + 1, + 703, + 656, + 1, + 607, + 657, + 1, + 674, + 657, + 1, + 685, + 657, + 1, + 703, + 657, + 1, + 607, + 658, + 1, + 674, + 658, + 1, + 685, + 658, + 1, + 703, + 658, + 1, + 607, + 659, + 3, + 674, + 659, + 1, + 685, + 659, + 1, + 703, + 659, + 1, + 609, + 660, + 1, + 674, + 660, + 1, + 685, + 660, + 1, + 703, + 660, + 10, + 674, + 661, + 1, + 685, + 661, + 1, + 712, + 661, + 23, + 739, + 661, + 2, + 750, + 661, + 45, + 796, + 661, + 6, + 674, + 662, + 1, + 685, + 662, + 1, + 745, + 662, + 2, + 750, + 662, + 1, + 761, + 662, + 1, + 780, + 662, + 2, + 790, + 662, + 1, + 794, + 662, + 3, + 801, + 662, + 1, + 608, + 663, + 2, + 674, + 663, + 1, + 685, + 663, + 1, + 746, + 663, + 1, + 750, + 663, + 1, + 761, + 663, + 1, + 795, + 663, + 1, + 801, + 663, + 1, + 608, + 664, + 2, + 674, + 664, + 1, + 685, + 664, + 1, + 750, + 664, + 1, + 795, + 664, + 1, + 801, + 664, + 1, + 606, + 665, + 3, + 674, + 665, + 1, + 685, + 665, + 1, + 746, + 665, + 2, + 750, + 665, + 2, + 801, + 665, + 1, + 604, + 666, + 2, + 653, + 666, + 1, + 674, + 666, + 1, + 685, + 666, + 1, + 746, + 666, + 14, + 801, + 666, + 2, + 604, + 667, + 1, + 653, + 667, + 2, + 658, + 667, + 1, + 674, + 667, + 1, + 685, + 667, + 1, + 764, + 667, + 1, + 802, + 667, + 1, + 604, + 668, + 2, + 627, + 668, + 1, + 653, + 668, + 6, + 674, + 668, + 1, + 685, + 668, + 1, + 768, + 668, + 1, + 780, + 668, + 2, + 790, + 668, + 1, + 794, + 668, + 3, + 801, + 668, + 2, + 604, + 669, + 1, + 653, + 669, + 1, + 658, + 669, + 1, + 673, + 669, + 2, + 685, + 669, + 1, + 768, + 669, + 2, + 780, + 669, + 2, + 790, + 669, + 1, + 794, + 669, + 1, + 796, + 669, + 1, + 800, + 669, + 2, + 603, + 670, + 2, + 653, + 670, + 1, + 658, + 670, + 1, + 673, + 670, + 1, + 685, + 670, + 1, + 794, + 670, + 1, + 801, + 670, + 3, + 603, + 671, + 1, + 653, + 671, + 1, + 658, + 671, + 16, + 685, + 671, + 1, + 794, + 671, + 1, + 803, + 671, + 1, + 603, + 672, + 1, + 653, + 672, + 1, + 685, + 672, + 1, + 794, + 672, + 2, + 803, + 672, + 1, + 603, + 673, + 1, + 653, + 673, + 29, + 686, + 673, + 2, + 794, + 673, + 2, + 803, + 673, + 1, + 603, + 674, + 1, + 653, + 674, + 2, + 667, + 674, + 2, + 681, + 674, + 4, + 687, + 674, + 1, + 803, + 674, + 1, + 603, + 675, + 1, + 654, + 675, + 1, + 667, + 675, + 2, + 681, + 675, + 2, + 684, + 675, + 1, + 686, + 675, + 2, + 803, + 675, + 1, + 603, + 676, + 1, + 684, + 676, + 3, + 803, + 676, + 1, + 603, + 677, + 1, + 685, + 677, + 1, + 803, + 677, + 1, + 603, + 678, + 2, + 627, + 678, + 2, + 803, + 678, + 1, + 603, + 679, + 2, + 803, + 679, + 1, + 599, + 680, + 5, + 654, + 680, + 1, + 667, + 680, + 2, + 746, + 680, + 5, + 803, + 680, + 1, + 599, + 681, + 1, + 681, + 681, + 1, + 746, + 681, + 1, + 750, + 681, + 1, + 803, + 681, + 1, + 599, + 682, + 1, + 746, + 682, + 1, + 750, + 682, + 1, + 803, + 682, + 1, + 599, + 683, + 1, + 746, + 683, + 1, + 750, + 683, + 54, + 599, + 684, + 1, + 706, + 684, + 2, + 709, + 684, + 14, + 746, + 684, + 1, + 599, + 685, + 1, + 706, + 685, + 2, + 722, + 685, + 1, + 746, + 685, + 1, + 599, + 686, + 1, + 698, + 686, + 2, + 722, + 686, + 1, + 746, + 686, + 1, + 599, + 687, + 1, + 697, + 687, + 4, + 706, + 687, + 1, + 722, + 687, + 1, + 746, + 687, + 1, + 599, + 688, + 1, + 697, + 688, + 1, + 700, + 688, + 2, + 706, + 688, + 1, + 722, + 688, + 1, + 746, + 688, + 1, + 599, + 689, + 1, + 696, + 689, + 3, + 701, + 689, + 4, + 706, + 689, + 1, + 722, + 689, + 1, + 746, + 689, + 1, + 599, + 690, + 1, + 698, + 690, + 2, + 704, + 690, + 3, + 722, + 690, + 5, + 743, + 690, + 4, + 599, + 691, + 1, + 699, + 691, + 2, + 726, + 691, + 1, + 743, + 691, + 1, + 599, + 692, + 1, + 700, + 692, + 2, + 726, + 692, + 1, + 743, + 692, + 1, + 599, + 693, + 1, + 701, + 693, + 6, + 726, + 693, + 1, + 743, + 693, + 2, + 599, + 694, + 1, + 706, + 694, + 2, + 726, + 694, + 1, + 744, + 694, + 3, + 599, + 695, + 1, + 707, + 695, + 1, + 726, + 695, + 1, + 746, + 695, + 1, + 599, + 696, + 1, + 707, + 696, + 1, + 726, + 696, + 1, + 746, + 696, + 1, + 599, + 697, + 1, + 707, + 697, + 1, + 726, + 697, + 1, + 746, + 697, + 1, + 599, + 698, + 1, + 694, + 698, + 1, + 707, + 698, + 1, + 726, + 698, + 1, + 746, + 698, + 1, + 599, + 699, + 1, + 630, + 699, + 1, + 705, + 699, + 3, + 726, + 699, + 1, + 746, + 699, + 1, + 599, + 700, + 1, + 624, + 700, + 8, + 689, + 700, + 1, + 707, + 700, + 1, + 726, + 700, + 1, + 746, + 700, + 1, + 599, + 701, + 1, + 602, + 701, + 3, + 619, + 701, + 6, + 631, + 701, + 1, + 689, + 701, + 1, + 707, + 701, + 1, + 726, + 701, + 1, + 746, + 701, + 1, + 599, + 702, + 4, + 604, + 702, + 1, + 614, + 702, + 6, + 631, + 702, + 1, + 707, + 702, + 1, + 726, + 702, + 1, + 746, + 702, + 1, + 604, + 703, + 2, + 614, + 703, + 1, + 631, + 703, + 1, + 707, + 703, + 1, + 726, + 703, + 1, + 746, + 703, + 1, + 604, + 704, + 2, + 614, + 704, + 1, + 631, + 704, + 1, + 707, + 704, + 1, + 726, + 704, + 1, + 746, + 704, + 1, + 604, + 705, + 1, + 614, + 705, + 1, + 631, + 705, + 2, + 707, + 705, + 1, + 726, + 705, + 1, + 746, + 705, + 1, + 604, + 706, + 1, + 614, + 706, + 1, + 628, + 706, + 5, + 707, + 706, + 1, + 725, + 706, + 2, + 746, + 706, + 1, + 604, + 707, + 1, + 614, + 707, + 1, + 626, + 707, + 3, + 707, + 707, + 1, + 725, + 707, + 1, + 746, + 707, + 1, + 604, + 708, + 2, + 614, + 708, + 1, + 620, + 708, + 7, + 707, + 708, + 1, + 725, + 708, + 1, + 746, + 708, + 1, + 797, + 708, + 3, + 605, + 709, + 10, + 619, + 709, + 2, + 707, + 709, + 1, + 725, + 709, + 1, + 746, + 709, + 1, + 795, + 709, + 3, + 799, + 709, + 1, + 619, + 710, + 1, + 648, + 710, + 9, + 707, + 710, + 1, + 723, + 710, + 3, + 746, + 710, + 1, + 799, + 710, + 2, + 619, + 711, + 2, + 648, + 711, + 3, + 655, + 711, + 2, + 707, + 711, + 1, + 723, + 711, + 1, + 725, + 711, + 1, + 746, + 711, + 46, + 795, + 711, + 1, + 800, + 711, + 3, + 619, + 712, + 1, + 649, + 712, + 1, + 707, + 712, + 1, + 723, + 712, + 1, + 791, + 712, + 1, + 802, + 712, + 2, + 619, + 713, + 1, + 707, + 713, + 1, + 723, + 713, + 1, + 791, + 713, + 1, + 803, + 713, + 1, + 619, + 714, + 2, + 707, + 714, + 1, + 723, + 714, + 1, + 791, + 714, + 1, + 803, + 714, + 1, + 620, + 715, + 1, + 707, + 715, + 1, + 723, + 715, + 1, + 791, + 715, + 2, + 795, + 715, + 1, + 803, + 715, + 1, + 620, + 716, + 1, + 707, + 716, + 1, + 723, + 716, + 1, + 792, + 716, + 4, + 803, + 716, + 1, + 614, + 717, + 7, + 707, + 717, + 1, + 723, + 717, + 1, + 803, + 717, + 1, + 614, + 718, + 1, + 707, + 718, + 1, + 723, + 718, + 1, + 803, + 718, + 1, + 614, + 719, + 1, + 707, + 719, + 1, + 723, + 719, + 1, + 803, + 719, + 1, + 614, + 720, + 1, + 707, + 720, + 1, + 723, + 720, + 1, + 803, + 720, + 1, + 614, + 721, + 1, + 707, + 721, + 1, + 723, + 721, + 1, + 802, + 721, + 2, + 613, + 722, + 1, + 648, + 722, + 1, + 652, + 722, + 2, + 707, + 722, + 1, + 721, + 722, + 3, + 795, + 722, + 8, + 613, + 723, + 1, + 648, + 723, + 1, + 707, + 723, + 1, + 721, + 723, + 1, + 783, + 723, + 1, + 786, + 723, + 6, + 795, + 723, + 1, + 613, + 724, + 1, + 707, + 724, + 1, + 721, + 724, + 1, + 783, + 724, + 4, + 789, + 724, + 1, + 795, + 724, + 1, + 613, + 725, + 1, + 648, + 725, + 1, + 707, + 725, + 1, + 721, + 725, + 1, + 783, + 725, + 1, + 795, + 725, + 1, + 611, + 726, + 1, + 613, + 726, + 1, + 648, + 726, + 1, + 707, + 726, + 1, + 721, + 726, + 1, + 783, + 726, + 1, + 795, + 726, + 1, + 611, + 727, + 1, + 707, + 727, + 1, + 721, + 727, + 1, + 777, + 727, + 2, + 782, + 727, + 2, + 791, + 727, + 1, + 795, + 727, + 1, + 611, + 728, + 1, + 649, + 728, + 1, + 707, + 728, + 1, + 721, + 728, + 1, + 777, + 728, + 6, + 795, + 728, + 1, + 611, + 729, + 1, + 649, + 729, + 1, + 707, + 729, + 1, + 721, + 729, + 1, + 777, + 729, + 1, + 795, + 729, + 1, + 611, + 730, + 1, + 707, + 730, + 1, + 721, + 730, + 1, + 777, + 730, + 2, + 795, + 730, + 1, + 611, + 731, + 7, + 707, + 731, + 1, + 715, + 731, + 7, + 778, + 731, + 1, + 795, + 731, + 1, + 707, + 732, + 1, + 715, + 732, + 1, + 752, + 732, + 3, + 778, + 732, + 1, + 795, + 732, + 1, + 617, + 733, + 2, + 707, + 733, + 1, + 711, + 733, + 3, + 715, + 733, + 1, + 742, + 733, + 11, + 754, + 733, + 1, + 778, + 733, + 1, + 795, + 733, + 1, + 617, + 734, + 2, + 707, + 734, + 1, + 711, + 734, + 1, + 713, + 734, + 3, + 742, + 734, + 1, + 749, + 734, + 1, + 752, + 734, + 3, + 778, + 734, + 1, + 795, + 734, + 1, + 612, + 735, + 1, + 707, + 735, + 1, + 711, + 735, + 1, + 742, + 735, + 1, + 749, + 735, + 1, + 778, + 735, + 1, + 788, + 735, + 1, + 795, + 735, + 1, + 611, + 736, + 2, + 617, + 736, + 1, + 648, + 736, + 1, + 707, + 736, + 1, + 711, + 736, + 1, + 742, + 736, + 1, + 749, + 736, + 1, + 778, + 736, + 1, + 788, + 736, + 1, + 795, + 736, + 1, + 611, + 737, + 1, + 707, + 737, + 1, + 711, + 737, + 1, + 742, + 737, + 1, + 749, + 737, + 1, + 778, + 737, + 1, + 788, + 737, + 2, + 795, + 737, + 1, + 611, + 738, + 1, + 647, + 738, + 2, + 707, + 738, + 1, + 711, + 738, + 1, + 740, + 738, + 3, + 749, + 738, + 1, + 772, + 738, + 7, + 789, + 738, + 7, + 611, + 739, + 1, + 647, + 739, + 2, + 707, + 739, + 1, + 711, + 739, + 1, + 740, + 739, + 2, + 749, + 739, + 1, + 772, + 739, + 1, + 611, + 740, + 1, + 707, + 740, + 1, + 711, + 740, + 1, + 741, + 740, + 1, + 749, + 740, + 1, + 772, + 740, + 1, + 611, + 741, + 1, + 707, + 741, + 1, + 711, + 741, + 1, + 740, + 741, + 2, + 749, + 741, + 1, + 772, + 741, + 1, + 611, + 742, + 1, + 707, + 742, + 1, + 711, + 742, + 1, + 740, + 742, + 1, + 749, + 742, + 1, + 772, + 742, + 1, + 611, + 743, + 1, + 707, + 743, + 1, + 711, + 743, + 1, + 740, + 743, + 2, + 748, + 743, + 2, + 772, + 743, + 1, + 611, + 744, + 1, + 707, + 744, + 1, + 711, + 744, + 1, + 741, + 744, + 8, + 772, + 744, + 1, + 611, + 745, + 1, + 655, + 745, + 2, + 707, + 745, + 1, + 711, + 745, + 1, + 727, + 745, + 2, + 740, + 745, + 1, + 772, + 745, + 1, + 611, + 746, + 1, + 649, + 746, + 2, + 655, + 746, + 2, + 707, + 746, + 1, + 711, + 746, + 1, + 727, + 746, + 2, + 740, + 746, + 1, + 772, + 746, + 1, + 611, + 747, + 1, + 707, + 747, + 1, + 711, + 747, + 1, + 740, + 747, + 1, + 772, + 747, + 1, + 611, + 748, + 1, + 707, + 748, + 1, + 711, + 748, + 1, + 772, + 748, + 1, + 611, + 749, + 2, + 692, + 749, + 2, + 707, + 749, + 1, + 711, + 749, + 1, + 772, + 749, + 1, + 612, + 750, + 6, + 652, + 750, + 2, + 707, + 750, + 1, + 711, + 750, + 1, + 756, + 750, + 5, + 772, + 750, + 1, + 617, + 751, + 1, + 648, + 751, + 1, + 651, + 751, + 4, + 707, + 751, + 1, + 711, + 751, + 1, + 756, + 751, + 1, + 760, + 751, + 13, + 617, + 752, + 1, + 648, + 752, + 4, + 653, + 752, + 1, + 659, + 752, + 6, + 705, + 752, + 1, + 707, + 752, + 1, + 711, + 752, + 1, + 756, + 752, + 1, + 617, + 753, + 1, + 648, + 753, + 1, + 653, + 753, + 2, + 659, + 753, + 1, + 664, + 753, + 1, + 707, + 753, + 1, + 711, + 753, + 1, + 756, + 753, + 1, + 611, + 754, + 2, + 617, + 754, + 1, + 647, + 754, + 2, + 654, + 754, + 6, + 664, + 754, + 18, + 693, + 754, + 1, + 704, + 754, + 1, + 707, + 754, + 1, + 711, + 754, + 1, + 756, + 754, + 1, + 611, + 755, + 1, + 647, + 755, + 2, + 681, + 755, + 1, + 707, + 755, + 1, + 711, + 755, + 1, + 756, + 755, + 1, + 611, + 756, + 1, + 648, + 756, + 1, + 681, + 756, + 9, + 707, + 756, + 1, + 711, + 756, + 1, + 756, + 756, + 1, + 611, + 757, + 2, + 647, + 757, + 2, + 690, + 757, + 1, + 707, + 757, + 1, + 711, + 757, + 1, + 756, + 757, + 1, + 612, + 758, + 2, + 646, + 758, + 2, + 690, + 758, + 1, + 707, + 758, + 1, + 711, + 758, + 1, + 713, + 758, + 3, + 752, + 758, + 3, + 756, + 758, + 1, + 613, + 759, + 5, + 646, + 759, + 1, + 690, + 759, + 2, + 706, + 759, + 2, + 711, + 759, + 3, + 715, + 759, + 1, + 752, + 759, + 1, + 754, + 759, + 3, + 617, + 760, + 30, + 691, + 760, + 16, + 715, + 760, + 1, + 752, + 760, + 1, + 715, + 761, + 38 + ] + } + ], + "entities": [ + { + "__class": "PointMapEntity", + "metaData": { + "angle": 272 + }, + "points": [ + 3625, + 3348 + ], + "type": "robot_position" + }, + { + "__class": "PointMapEntity", + "metaData": { + "angle": 3 + }, + "points": [ + 3280, + 3321 + ], + "type": "charger_location" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3460, + 3394, + 3465, + 3394, + 3470, + 3395, + 3474, + 3399, + 3477, + 3404, + 3478, + 3409, + 3481, + 3416, + 3486, + 3417, + 3491, + 3415, + 3496, + 3415, + 3501, + 3416, + 3506, + 3418, + 3510, + 3421, + 3513, + 3417, + 3513, + 3412, + 3514, + 3407, + 3514, + 3402, + 3519, + 3402, + 3524, + 3402, + 3529, + 3403, + 3534, + 3403, + 3539, + 3403, + 3544, + 3403, + 3549, + 3404, + 3554, + 3404, + 3559, + 3404, + 3564, + 3404, + 3570, + 3404, + 3575, + 3404, + 3580, + 3405, + 3585, + 3405, + 3590, + 3405, + 3595, + 3405, + 3601, + 3405, + 3606, + 3405, + 3611, + 3405, + 3616, + 3405, + 3621, + 3405, + 3626, + 3405, + 3631, + 3407, + 3630, + 3412, + 3630, + 3417, + 3630, + 3422, + 3630, + 3427, + 3630, + 3432, + 3635, + 3433, + 3640, + 3433, + 3645, + 3434, + 3649, + 3436, + 3652, + 3434, + 3655, + 3438, + 3657, + 3443, + 3659, + 3448, + 3663, + 3451, + 3668, + 3450, + 3673, + 3450, + 3679, + 3450, + 3684, + 3450, + 3689, + 3450, + 3694, + 3451, + 3698, + 3447, + 3700, + 3442, + 3703, + 3438, + 3707, + 3435, + 3711, + 3432, + 3711, + 3426, + 3711, + 3421, + 3711, + 3416, + 3711, + 3411, + 3711, + 3406, + 3711, + 3401, + 3711, + 3396, + 3710, + 3391, + 3714, + 3387, + 3719, + 3387, + 3724, + 3387, + 3729, + 3386, + 3734, + 3386, + 3735, + 3381, + 3735, + 3376, + 3736, + 3371, + 3736, + 3366, + 3727, + 3368, + 3722, + 3366, + 3717, + 3364, + 3713, + 3361, + 3709, + 3358, + 3705, + 3355, + 3703, + 3350, + 3703, + 3345, + 3703, + 3340, + 3704, + 3335, + 3705, + 3330, + 3701, + 3327, + 3696, + 3327, + 3691, + 3328, + 3686, + 3328, + 3680, + 3328, + 3675, + 3328, + 3677, + 3333, + 3678, + 3338, + 3679, + 3343, + 3679, + 3348, + 3678, + 3353, + 3675, + 3358, + 3672, + 3362, + 3667, + 3364, + 3662, + 3365, + 3657, + 3365, + 3652, + 3365, + 3647, + 3363, + 3643, + 3360, + 3640, + 3356, + 3637, + 3352, + 3636, + 3347, + 3636, + 3342, + 3637, + 3337, + 3639, + 3332, + 3634, + 3330, + 3629, + 3330, + 3624, + 3330, + 3619, + 3330, + 3614, + 3330, + 3609, + 3330, + 3604, + 3330, + 3599, + 3329, + 3594, + 3329, + 3589, + 3329, + 3583, + 3329, + 3578, + 3329, + 3573, + 3329, + 3568, + 3329, + 3563, + 3329, + 3558, + 3329, + 3553, + 3329, + 3547, + 3328, + 3542, + 3327, + 3537, + 3326, + 3532, + 3325, + 3527, + 3325, + 3522, + 3325, + 3517, + 3324, + 3512, + 3324, + 3507, + 3324, + 3502, + 3324, + 3496, + 3324, + 3495, + 3319, + 3495, + 3314, + 3496, + 3309, + 3496, + 3304, + 3496, + 3299, + 3496, + 3294, + 3496, + 3289, + 3491, + 3288, + 3486, + 3288, + 3480, + 3288, + 3475, + 3288, + 3470, + 3287, + 3465, + 3287, + 3460, + 3287, + 3455, + 3287, + 3450, + 3287, + 3445, + 3290, + 3445, + 3295, + 3445, + 3301, + 3445, + 3306, + 3445, + 3311, + 3445, + 3316, + 3445, + 3322, + 3445, + 3327, + 3445, + 3332, + 3445, + 3337, + 3445, + 3342, + 3445, + 3347, + 3445, + 3352, + 3448, + 3357, + 3451, + 3361, + 3453, + 3365, + 3455, + 3370, + 3455, + 3375, + 3455, + 3380, + 3453, + 3385, + 3455, + 3390, + 3459, + 3392, + 3464, + 3393, + 3469, + 3394 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3663, + 3438, + 3695, + 3438, + 3699, + 3437, + 3701, + 3432, + 3698, + 3428, + 3696, + 3427, + 3644, + 3427, + 3639, + 3426, + 3637, + 3421, + 3640, + 3417, + 3642, + 3416, + 3700, + 3416, + 3705, + 3415, + 3706, + 3410, + 3703, + 3406, + 3701, + 3405, + 3645, + 3405 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3502, + 3403, + 3484, + 3400, + 3479, + 3394, + 3703, + 3391, + 3719, + 3382, + 3469, + 3382, + 3464, + 3371, + 3719, + 3371, + 3692, + 3358, + 3687, + 3358, + 3683, + 3356, + 3682, + 3351, + 3686, + 3348, + 3686, + 3348, + 3691, + 3348, + 3696, + 3346, + 3697, + 3341, + 3693, + 3337, + 3692, + 3337 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3631, + 3359, + 3460, + 3358, + 3456, + 3357, + 3454, + 3352, + 3457, + 3348, + 3458, + 3348, + 3625, + 3348, + 3630, + 3347, + 3632, + 3342, + 3629, + 3338, + 3628, + 3337, + 3458, + 3337, + 3461, + 3329, + 3481, + 3329, + 3486, + 3327, + 3489, + 3323, + 3488, + 3318, + 3484, + 3315, + 3483, + 3315, + 3462, + 3314, + 3458, + 3313, + 3455, + 3308, + 3457, + 3304, + 3461, + 3301, + 3477, + 3301 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3457, + 3375, + 3457, + 3376, + 3455, + 3380, + 3452, + 3385, + 3454, + 3389, + 3458, + 3392, + 3463, + 3393, + 3468, + 3394, + 3472, + 3397, + 3476, + 3401, + 3478, + 3406, + 3479, + 3411, + 3481, + 3415, + 3486, + 3417, + 3491, + 3415, + 3497, + 3411, + 3502, + 3413, + 3506, + 3417, + 3509, + 3421, + 3512, + 3416, + 3512, + 3411, + 3512, + 3406, + 3515, + 3402, + 3520, + 3402, + 3525, + 3403, + 3530, + 3403, + 3535, + 3403, + 3540, + 3403, + 3545, + 3403, + 3550, + 3403, + 3556, + 3404, + 3561, + 3404, + 3566, + 3404, + 3571, + 3404, + 3576, + 3404, + 3581, + 3404, + 3586, + 3404, + 3592, + 3405, + 3597, + 3405, + 3602, + 3405, + 3607, + 3405, + 3612, + 3405, + 3617, + 3405, + 3622, + 3405, + 3627, + 3405, + 3631, + 3408, + 3631, + 3413, + 3630, + 3418, + 3630, + 3423, + 3630, + 3428, + 3631, + 3433, + 3636, + 3433, + 3641, + 3433, + 3647, + 3434, + 3651, + 3436, + 3654, + 3440, + 3661, + 3446, + 3662, + 3451, + 3667, + 3451, + 3672, + 3451, + 3678, + 3451, + 3683, + 3451, + 3688, + 3451, + 3695, + 3451, + 3698, + 3446, + 3700, + 3442, + 3704, + 3438, + 3708, + 3434, + 3711, + 3430, + 3710, + 3425, + 3710, + 3420, + 3710, + 3415, + 3710, + 3410, + 3710, + 3405, + 3710, + 3400, + 3710, + 3395, + 3710, + 3389, + 3713, + 3385, + 3718, + 3386, + 3723, + 3385, + 3729, + 3385, + 3734, + 3385, + 3736, + 3380, + 3736, + 3375, + 3736, + 3370, + 3735, + 3365, + 3730, + 3365, + 3725, + 3365, + 3716, + 3366, + 3712, + 3363, + 3708, + 3360, + 3705, + 3356, + 3703, + 3351, + 3703, + 3346, + 3703, + 3340, + 3704, + 3335, + 3706, + 3331, + 3702, + 3327, + 3697, + 3327, + 3692, + 3328, + 3687, + 3328, + 3681, + 3328, + 3676, + 3328, + 3677, + 3334, + 3678, + 3339, + 3678, + 3344, + 3678, + 3349, + 3677, + 3354, + 3675, + 3358, + 3671, + 3362, + 3666, + 3364, + 3661, + 3365, + 3656, + 3365, + 3651, + 3364, + 3646, + 3362, + 3642, + 3359, + 3639, + 3355, + 3637, + 3351, + 3636, + 3345, + 3636, + 3340, + 3638, + 3335, + 3639, + 3331, + 3634, + 3330, + 3629, + 3330, + 3624, + 3330, + 3619, + 3330, + 3614, + 3330, + 3609, + 3330, + 3604, + 3329, + 3598, + 3329, + 3593, + 3329, + 3588, + 3329, + 3583, + 3329, + 3578, + 3329, + 3573, + 3329, + 3568, + 3329, + 3563, + 3329, + 3558, + 3329, + 3553, + 3329, + 3547, + 3328, + 3542, + 3327, + 3537, + 3326, + 3532, + 3325, + 3527, + 3325, + 3522, + 3325, + 3517, + 3324, + 3512, + 3324, + 3506, + 3324, + 3501, + 3324, + 3496, + 3324, + 3494, + 3320, + 3495, + 3315, + 3495, + 3310, + 3495, + 3305, + 3496, + 3299, + 3496, + 3294, + 3496, + 3289, + 3491, + 3288, + 3486, + 3288, + 3481, + 3288, + 3475, + 3288, + 3470, + 3288, + 3465, + 3288, + 3460, + 3288, + 3455, + 3288, + 3450, + 3288, + 3446, + 3291, + 3446, + 3296, + 3445, + 3301, + 3445, + 3306, + 3445, + 3311, + 3445, + 3316, + 3446, + 3321, + 3450, + 3325, + 3453, + 3329, + 3456, + 3333, + 3458, + 3338, + 3458, + 3343, + 3459, + 3348, + 3458, + 3353, + 3458, + 3358, + 3458, + 3364, + 3458, + 3369, + 3457, + 3374, + 3455, + 3378 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3698, + 3341, + 3699, + 3434, + 3686, + 3439, + 3686, + 3341, + 3681, + 3360, + 3673, + 3375, + 3673, + 3438, + 3672, + 3443, + 3668, + 3446, + 3663, + 3445, + 3661, + 3441, + 3661, + 3376, + 3660, + 3371, + 3655, + 3368, + 3650, + 3369, + 3648, + 3373, + 3648, + 3423, + 3647, + 3428, + 3642, + 3431, + 3637, + 3429, + 3636, + 3425, + 3634, + 3361, + 3623, + 3346, + 3623, + 3394, + 3622, + 3398, + 3617, + 3401, + 3612, + 3399, + 3611, + 3395, + 3611, + 3341, + 3610, + 3336, + 3605, + 3333, + 3600, + 3334, + 3598, + 3338, + 3598, + 3394, + 3597, + 3399, + 3592, + 3401, + 3587, + 3400, + 3586, + 3396, + 3585, + 3341, + 3584, + 3336, + 3580, + 3333, + 3575, + 3335, + 3573, + 3339, + 3573, + 3388, + 3572, + 3393, + 3568, + 3396, + 3563, + 3394, + 3561, + 3390, + 3560, + 3341, + 3559, + 3336, + 3555, + 3333, + 3550, + 3334, + 3548, + 3338, + 3548, + 3388, + 3547, + 3393, + 3542, + 3396, + 3537, + 3394, + 3536, + 3391, + 3535, + 3341, + 3524, + 3335, + 3523, + 3389, + 3522, + 3394, + 3518, + 3396, + 3513, + 3395, + 3511, + 3391, + 3510, + 3336, + 3509, + 3331, + 3505, + 3329, + 3500, + 3330, + 3498, + 3334, + 3498, + 3398, + 3486, + 3404, + 3486, + 3301, + 3485, + 3296, + 3481, + 3293, + 3476, + 3294, + 3473, + 3299, + 3473, + 3384, + 3472, + 3389, + 3468, + 3391, + 3463, + 3390, + 3461, + 3386, + 3461, + 3303, + 3448, + 3318, + 3446, + 3323, + 3445, + 3328, + 3445, + 3333, + 3444, + 3338, + 3444, + 3343, + 3444, + 3348, + 3445, + 3353, + 3448, + 3357, + 3450, + 3361, + 3453, + 3366, + 3455, + 3370, + 3456, + 3375, + 3459, + 3377, + 3457, + 3382, + 3454, + 3386, + 3458, + 3390, + 3462, + 3392, + 3467, + 3394, + 3471, + 3397, + 3475, + 3401, + 3477, + 3405, + 3479, + 3410, + 3481, + 3415, + 3486, + 3416, + 3491, + 3415, + 3496, + 3416, + 3501, + 3417, + 3506, + 3419, + 3510, + 3421, + 3513, + 3417, + 3514, + 3412, + 3514, + 3407, + 3514, + 3402, + 3519, + 3401, + 3524, + 3402, + 3530, + 3402, + 3535, + 3402, + 3540, + 3403, + 3545, + 3403, + 3550, + 3403, + 3555, + 3404, + 3560, + 3404, + 3565, + 3404, + 3570, + 3404, + 3575, + 3404, + 3580, + 3404, + 3586, + 3405, + 3591, + 3405, + 3596, + 3405, + 3601, + 3405, + 3606, + 3405, + 3611, + 3405, + 3616, + 3405, + 3622, + 3405, + 3627, + 3405, + 3631, + 3407, + 3631, + 3412, + 3630, + 3417, + 3630, + 3423, + 3630, + 3428, + 3630, + 3433, + 3635, + 3433, + 3640, + 3433, + 3645, + 3433, + 3650, + 3432, + 3652, + 3437, + 3652, + 3442, + 3652, + 3447, + 3656, + 3451, + 3661, + 3451, + 3666, + 3451, + 3671, + 3451, + 3676, + 3451, + 3682, + 3451, + 3687, + 3451, + 3692, + 3450, + 3697, + 3449, + 3699, + 3444, + 3701, + 3440, + 3705, + 3436, + 3704, + 3433, + 3709, + 3431, + 3712, + 3427, + 3711, + 3421, + 3711, + 3416, + 3711, + 3411, + 3710, + 3406, + 3710, + 3401, + 3710, + 3396, + 3710, + 3391, + 3712, + 3386, + 3717, + 3386, + 3722, + 3386, + 3728, + 3386, + 3733, + 3385, + 3735, + 3381, + 3736, + 3376, + 3735, + 3371, + 3735, + 3365, + 3730, + 3365, + 3725, + 3365, + 3720, + 3365, + 3715, + 3363, + 3711, + 3361, + 3707, + 3357, + 3704, + 3353, + 3703, + 3348, + 3703, + 3343, + 3704, + 3338, + 3706, + 3333, + 3708, + 3328, + 3703, + 3327, + 3698, + 3328, + 3693, + 3328, + 3688, + 3328, + 3683, + 3328, + 3678, + 3328, + 3680, + 3337, + 3682, + 3342, + 3681, + 3347, + 3679, + 3352, + 3677, + 3356, + 3673, + 3360, + 3665, + 3367, + 3660, + 3367, + 3655, + 3366, + 3650, + 3364, + 3645, + 3362, + 3641, + 3359, + 3635, + 3352, + 3634, + 3347, + 3635, + 3342, + 3637, + 3337, + 3639, + 3332, + 3634, + 3329, + 3629, + 3329, + 3624, + 3330, + 3619, + 3330, + 3614, + 3330, + 3608, + 3330, + 3603, + 3330, + 3598, + 3329, + 3593, + 3329, + 3588, + 3329, + 3583, + 3329, + 3578, + 3329, + 3573, + 3329, + 3568, + 3329, + 3562, + 3329, + 3557, + 3329, + 3552, + 3329, + 3547, + 3328, + 3542, + 3327, + 3537, + 3326, + 3531, + 3325, + 3526, + 3325, + 3521, + 3324, + 3516, + 3324, + 3511, + 3324, + 3506, + 3324, + 3501, + 3324, + 3496, + 3324, + 3494, + 3319, + 3495, + 3314, + 3495, + 3309, + 3495, + 3304, + 3496, + 3298, + 3496, + 3293, + 3495, + 3288, + 3490, + 3288, + 3484, + 3288, + 3479, + 3288, + 3474, + 3288, + 3469, + 3288, + 3464, + 3288, + 3459, + 3288, + 3453, + 3287, + 3448, + 3288, + 3446, + 3292, + 3446, + 3297, + 3446, + 3302, + 3445, + 3307, + 3445, + 3312, + 3445, + 3317, + 3445, + 3323 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3667, + 3438, + 3691, + 3436, + 3700, + 3428, + 3644, + 3427, + 3639, + 3426, + 3637, + 3421, + 3640, + 3417, + 3642, + 3416, + 3699, + 3416, + 3704, + 3415, + 3706, + 3410, + 3703, + 3406, + 3701, + 3405, + 3646, + 3405 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3502, + 3403, + 3492, + 3403 + ], + "type": "path" + }, + { + "__class": "PathMapEntity", + "metaData": {}, + "points": [ + 3592, + 3397, + 3701, + 3397, + 3706, + 3396, + 3708, + 3392, + 3704, + 3388, + 3470, + 3388, + 3465, + 3387, + 3464, + 3382, + 3466, + 3378, + 3468, + 3378, + 3725, + 3378, + 3711, + 3367, + 3464, + 3365, + 3458, + 3359, + 3630, + 3358, + 3625, + 3348 + ], + "type": "path" + } + ] +} \ No newline at end of file diff --git a/backend/test/lib/robots/dreame/res/map/z10_1056_paths.json b/backend/test/lib/robots/dreame/res/map/z10_1056_paths.json index c2f77e26..7251a538 100644 --- a/backend/test/lib/robots/dreame/res/map/z10_1056_paths.json +++ b/backend/test/lib/robots/dreame/res/map/z10_1056_paths.json @@ -3740,7 +3740,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "regular", "name": "Bad", @@ -3898,7 +3898,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "regular", "name": "Schlafzimmer", @@ -4674,7 +4674,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "regular", "name": "Küche", @@ -4916,7 +4916,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 4, + "segmentId": "4", "active": false, "source": "regular", "name": "Flur", @@ -5314,7 +5314,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 5, + "segmentId": "5", "active": false, "source": "regular", "name": "Wohnzimmer", @@ -5883,7 +5883,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 6, + "segmentId": "6", "active": false, "source": "regular", "name": "Essbereich", @@ -6206,7 +6206,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 7, + "segmentId": "7", "active": false, "source": "regular", "name": "Schreibtisch", diff --git a/backend/test/lib/robots/dreame/res/map/z10_1056_virtual_restrictions.json b/backend/test/lib/robots/dreame/res/map/z10_1056_virtual_restrictions.json index 63bbf1ca..b94d0047 100644 --- a/backend/test/lib/robots/dreame/res/map/z10_1056_virtual_restrictions.json +++ b/backend/test/lib/robots/dreame/res/map/z10_1056_virtual_restrictions.json @@ -1774,7 +1774,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "source": "rism", "area": 27700 @@ -1886,7 +1886,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "source": "rism", "area": 105425 @@ -2295,7 +2295,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "source": "rism", "area": 60675 @@ -2434,7 +2434,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 4, + "segmentId": "4", "active": false, "source": "rism", "area": 47900 @@ -2597,7 +2597,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 5, + "segmentId": "5", "active": false, "source": "rism", "area": 108350 @@ -2898,7 +2898,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 6, + "segmentId": "6", "active": false, "source": "rism", "area": 99675 diff --git a/backend/test/lib/robots/dreame/res/map/z10_1156_super_minimal.bin b/backend/test/lib/robots/dreame/res/map/z10_1156_super_minimal.bin new file mode 100644 index 00000000..2358aaa4 --- /dev/null +++ b/backend/test/lib/robots/dreame/res/map/z10_1156_super_minimal.bin @@ -0,0 +1 @@ +eF5jZGBk8GQAg__1IGjEwASEQa-CXoHEqpWKMouVrAx0lEoyc1OLSxJzC-JzgQKG5uaGQMHcokQlKyUDJR2l5JzUxLzi1BIgt7oWyC_KTEwG6wPqLwAyagHlpx3J \ No newline at end of file diff --git a/backend/test/lib/robots/roborock/RoborockMapParser_spec.js b/backend/test/lib/robots/roborock/RoborockMapParser_spec.js index 6a0412bd..09d97a86 100644 --- a/backend/test/lib/robots/roborock/RoborockMapParser_spec.js +++ b/backend/test/lib/robots/roborock/RoborockMapParser_spec.js @@ -1,4 +1,5 @@ const fs = require("fs").promises; +const path = require("path"); const should = require("should"); const RoborockMapParser = require("../../../../lib/robots/roborock/RoborockMapParser"); @@ -15,8 +16,8 @@ describe("RoborockMapParser", function () { it("should parse s5 map without extra data from firmware 1886 correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW1886_without_extra_data.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW1886_without_extra_data.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S5_FW1886_without_extra_data.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S5_FW1886_without_extra_data.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); @@ -40,8 +41,8 @@ describe("RoborockMapParser", function () { }); it("should parse s5 map with forbidden_zones,virtual_walls,currently_cleaned_zones from firmware 1886 correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW1886_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW1886_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S5_FW1886_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S5_FW1886_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); @@ -65,8 +66,8 @@ describe("RoborockMapParser", function () { }); it("should parse s5 map with goto_target from firmware 1886 correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW1886_with_goto_target.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW1886_with_goto_target.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S5_FW1886_with_goto_target.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S5_FW1886_with_goto_target.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); @@ -90,8 +91,8 @@ describe("RoborockMapParser", function () { }); it("should parse s5 map with forbidden_zones,virtual_walls,currently_cleaned_zones from firmware 2008 correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW2008_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW2008_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S5_FW2008_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S5_FW2008_with_forbidden_zones_and_virtual_walls_and_currently_cleaned_zones.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); @@ -115,8 +116,8 @@ describe("RoborockMapParser", function () { }); it("should parse s5 map with segments from firmware 2008 correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW2008_with_segments.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW2008_with_segments.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S5_FW2008_with_segments.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S5_FW2008_with_segments.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); @@ -140,8 +141,8 @@ describe("RoborockMapParser", function () { }); it("should parse s5 map with segments from firmware 2020 correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW2020_with_segments.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S5_FW2020_with_segments.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S5_FW2020_with_segments.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S5_FW2020_with_segments.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); @@ -165,8 +166,8 @@ describe("RoborockMapParser", function () { }); it("should parse s6 map with segments from firmware 2652 with active segments and no-mop-zones correctly", async function() { - let data = await fs.readFile("./test/lib/robots/roborock/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.bin"); - let expected = JSON.parse(await fs.readFile("./test/lib/robots/roborock/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.json", { encoding: "utf-8" })); + let data = await fs.readFile(path.join(__dirname, "/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.bin")); + let expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.json"), { encoding: "utf-8" })); let actual = RoborockMapParser.PARSE(data); diff --git a/backend/test/lib/robots/roborock/res/map/S5_FW2008_with_segments.json b/backend/test/lib/robots/roborock/res/map/S5_FW2008_with_segments.json index 893663ab..626c61d9 100644 --- a/backend/test/lib/robots/roborock/res/map/S5_FW2008_with_segments.json +++ b/backend/test/lib/robots/roborock/res/map/S5_FW2008_with_segments.json @@ -807,7 +807,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "area": 33775 }, @@ -945,7 +945,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "area": 38475 }, diff --git a/backend/test/lib/robots/roborock/res/map/S5_FW2020_with_segments.json b/backend/test/lib/robots/roborock/res/map/S5_FW2020_with_segments.json index 63441c78..91a0fe4a 100644 --- a/backend/test/lib/robots/roborock/res/map/S5_FW2020_with_segments.json +++ b/backend/test/lib/robots/roborock/res/map/S5_FW2020_with_segments.json @@ -7026,7 +7026,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 1, + "segmentId": "1", "active": false, "area": 452675 }, @@ -9141,7 +9141,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 2, + "segmentId": "2", "active": false, "area": 188375 }, @@ -10095,7 +10095,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 3, + "segmentId": "3", "active": false, "area": 83025 }, @@ -10887,7 +10887,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 4, + "segmentId": "4", "active": false, "area": 32775 }, @@ -11070,7 +11070,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 5, + "segmentId": "5", "active": false, "area": 36875 }, @@ -11256,7 +11256,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 6, + "segmentId": "6", "active": false, "area": 188650 }, @@ -12201,7 +12201,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 7, + "segmentId": "7", "active": false, "area": 38175 }, @@ -12528,7 +12528,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 8, + "segmentId": "8", "active": false, "area": 95950 }, diff --git a/backend/test/lib/robots/roborock/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.json b/backend/test/lib/robots/roborock/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.json index 69cd0504..8777aec2 100644 --- a/backend/test/lib/robots/roborock/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.json +++ b/backend/test/lib/robots/roborock/res/map/S6_FW2652_with_active_segment_and_no_mop_zone.json @@ -2973,7 +2973,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 16, + "segmentId": "16", "active": false, "area": 10800 }, @@ -3123,7 +3123,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 17, + "segmentId": "17", "active": true, "area": 134650 }, @@ -3603,7 +3603,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 18, + "segmentId": "18", "active": false, "area": 64100 }, @@ -3765,7 +3765,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 19, + "segmentId": "19", "active": false, "area": 154325 }, @@ -4302,7 +4302,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 20, + "segmentId": "20", "active": false, "area": 21975 }, @@ -4539,7 +4539,7 @@ { "__class": "MapLayer", "metaData": { - "segmentId": 21, + "segmentId": "21", "active": false, "area": 73975 }, diff --git a/backend/test/lib/updater/lib/UpdaterUtils_spec.js b/backend/test/lib/updater/lib/UpdaterUtils_spec.js new file mode 100644 index 00000000..6e3ace23 --- /dev/null +++ b/backend/test/lib/updater/lib/UpdaterUtils_spec.js @@ -0,0 +1,96 @@ +const should = require("should"); + +const UpdaterUtils = require("../../../../lib/updater/lib/UpdaterUtils"); +const ValetudoRelease = require("../../../../lib/updater/lib/update_provider/ValetudoRelease"); + +should.config.checkProtoEql = false; + +describe("UpdaterUtils", function () { + + it("Should not offer an update when up to date", function() { + const releases = [ + new ValetudoRelease({ + version: "3", + releaseTimestamp: new Date(), + changelog: "" + }), + new ValetudoRelease({ + version: "2", + releaseTimestamp: new Date(), + changelog: "" + }), + new ValetudoRelease({ + version: "1", + releaseTimestamp: new Date(), + changelog: "" + }) + ]; + const result = UpdaterUtils.determineReleaseToDownload( + releases, + "3" + ); + + result.should.deepEqual({ + release: releases[0], + updateRequired: false + }); + }); + + it("Should offer update to latest when running an unknown version", function() { + const releases = [ + new ValetudoRelease({ + version: "3", + releaseTimestamp: new Date(), + changelog: "" + }), + new ValetudoRelease({ + version: "2", + releaseTimestamp: new Date(), + changelog: "" + }), + new ValetudoRelease({ + version: "1", + releaseTimestamp: new Date(), + changelog: "" + }) + ]; + const result = UpdaterUtils.determineReleaseToDownload( + releases, + "0" + ); + + result.should.deepEqual({ + release: releases[0], + updateRequired: true + }); + }); + + it("Should offer update to next chronological release", function() { + const releases = [ + new ValetudoRelease({ + version: "3", + releaseTimestamp: new Date(), + changelog: "" + }), + new ValetudoRelease({ + version: "2", + releaseTimestamp: new Date(), + changelog: "" + }), + new ValetudoRelease({ + version: "1", + releaseTimestamp: new Date(), + changelog: "" + }) + ]; + const result = UpdaterUtils.determineReleaseToDownload( + releases, + "1" + ); + + result.should.deepEqual({ + release: releases[1], + updateRequired: true + }); + }); +}); diff --git a/backend/test/lib/updater/lib/update_provider/GithubValetudoUpdateProvider_spec.js b/backend/test/lib/updater/lib/update_provider/GithubValetudoUpdateProvider_spec.js new file mode 100644 index 00000000..fdbbefbb --- /dev/null +++ b/backend/test/lib/updater/lib/update_provider/GithubValetudoUpdateProvider_spec.js @@ -0,0 +1,27 @@ +const should = require("should"); + +const GithubValetudoUpdateProvider = require("../../../../../lib/updater/lib/update_provider/GithubValetudoUpdateProvider"); +const path = require("path"); +const {promises: fs} = require("fs"); + +should.config.checkProtoEql = false; + +describe("GithubValetudoUpdateProvider", function () { + it("Should parse regular overview response correctly", async function() { + const updateProvider = new GithubValetudoUpdateProvider(); + const data = JSON.parse(await fs.readFile(path.join(__dirname, "/res/GithubValetudoUpdateProvider/regular_overview_response.json"), { encoding: "utf-8" })); + const expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/GithubValetudoUpdateProvider/correctly_parsed_regular_overview_response.json"), { encoding: "utf-8" })); + const actual = updateProvider.parseReleaseOverviewApiResponse(data); + + JSON.parse(JSON.stringify(actual)).should.deepEqual(expected); + }); + + it("Should parse incorrectly sorted overview response correctly", async function() { + const updateProvider = new GithubValetudoUpdateProvider(); + const data = JSON.parse(await fs.readFile(path.join(__dirname, "/res/GithubValetudoUpdateProvider/incorrectly_sorted_overview_response.json"), { encoding: "utf-8" })); + const expected = JSON.parse(await fs.readFile(path.join(__dirname, "/res/GithubValetudoUpdateProvider/correctly_parsed_regular_overview_response.json"), { encoding: "utf-8" })); + const actual = updateProvider.parseReleaseOverviewApiResponse(data); + + JSON.parse(JSON.stringify(actual)).should.deepEqual(expected); + }); +}); diff --git a/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/correctly_parsed_regular_overview_response.json b/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/correctly_parsed_regular_overview_response.json new file mode 100644 index 00000000..de17b23f --- /dev/null +++ b/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/correctly_parsed_regular_overview_response.json @@ -0,0 +1,210 @@ +[ + { + "version": "2022.08.0", + "releaseTimestamp": "2022-08-02T19:20:05.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.08.0

\r\n
\r\n\r\nNew firmwares for dreame robots and some bugfixes\r\n\r\n## New dreame firmwares\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454333-356ba835-4f69-4041-a720-7c2d97eb3209.png)\r\n\r\nIt took quite a lot of time and work, but now we're proud to announce that we've managed to get newer dreame firmwares\r\nto work rooted and with Valetudo. A big thank you to everyone who helped during the beta test!\r\n\r\n**Important**: That does **not** mean that these newer firmwares have become rootable.\r\nYou will need to have an already rooted robot to install these latest rooted firmwares.\r\n\r\nTo update, head over to the dustbuilder at [https://builder.dontvacuum.me/](https://builder.dontvacuum.me/) to build and install a new image.\r\nMake sure to update Valetudo **before** updating the firmware.\r\n\r\n## Other dreame news\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454516-57ef159d-d97e-458a-815d-97a60db689ba.png)\r\n\r\nStarting today, every firmware image built with the dustbuilder will contain a fix for the vanishing Valetudo issue,\r\nwhich occasionally left people with a rooted robot but no Valetudo.\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454599-cab62e88-6179-43da-b907-6ac7236c7d17.png)\r\n\r\nIf a user starts a new mapping pass, the fresh map should now appear instantly.\r\nFurthermore, issues with frozen maps either during cleanups or when editing segments were fixed as well.\r\n\r\n## Robot Coverage View\r\n\r\n[](https://user-images.githubusercontent.com/974410/182455081-879226c5-aa14-4160-bc2f-f9c0f2a2d3d3.png)\r\n\r\n\r\nThe UI has been extended with a view displaying a much thicker path.\r\nThis can be used to better see which areas of the map have been cleaned.\r\n\r\nWhether this view will stick around long-term is yet to be decided. It was pretty easy to implement though.\r\nFeel free to leave your feedback in the comments.\r\n\r\n\r\n## The usual\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454845-cc693f37-a126-4978-b2f0-5c9f77a970d8.png)\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Misc\r\n\r\nThis changelog features artworks generated by DALL-E 2 because I thought it would be neat to have something to look at.\r\nUnfortunately, it doesn't like generating artworks featuring lidar-based vacuum robots (yet?)\r\n\r\nI hope they've nonetheless enhanced your changelog reading experience.\r\nFeel free to leave feedback on that as well.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n- **vendor.dreame**: Newer D9 Firmwares also have a sensor consumable [`17c0d27`](http://github.com/Hypfer/Valetudo/commit/17c0d27fb69b92b5a8028d6bab489e5b97fb4537)\r\n- **ui**: Trim whitespaces when renaming segments [`39d72f4`](http://github.com/Hypfer/Valetudo/commit/39d72f4e787108c75a1cb501995151fb19b4d8b1)\r\n- **ui**: Add robot coverage map [`a9661a0`](http://github.com/Hypfer/Valetudo/commit/a9661a02bcbe642c3e7de46be4015f9532e4ce49)\r\n- **vendor.dreame**: Add mop-only quirk for newer firmwares [`a33afe3`](http://github.com/Hypfer/Valetudo/commit/a33afe351c1b868919bc7b036e2e02a05b8e581c)\r\n- **vendor.dreame**: Add Mop Dock UV-C Toggle Quirk [`7ce4abe`](http://github.com/Hypfer/Valetudo/commit/7ce4abe7353567fd3db6a7a9cc1c767d68a9db93)\r\n\r\n### Fixes\r\n\r\n- **vendor.dreame**: Add support for more features of newer firmwares [`b74c281`](http://github.com/Hypfer/Valetudo/commit/b74c281e1727ca2a007d96915c6fceb3f386bd28)\r\n- **ui**: Add margin to apple touch icon (#1526) [`dc72ef0`](http://github.com/Hypfer/Valetudo/commit/dc72ef05319799020a504a3b20e0b7e6092984ee)\r\n- **vendor.dreame**: Ignore empty maps [`99aad7b`](http://github.com/Hypfer/Valetudo/commit/99aad7be8b20c9459e849dd6b9ce8df5171b9690)\r\n- **networkadvertisement**: Don't crash the process on ssdp multicast membership errors [`bfb96c0`](http://github.com/Hypfer/Valetudo/commit/bfb96c09aa2bc0ff9e151fb6cdab4ac5bbd58a36)\r\n- **miio**: Allow two simultaneous FDS uploads [`6e26374`](http://github.com/Hypfer/Valetudo/commit/6e26374c32e9fe33c93f4f91c189f917c5f884a5)\r\n- **vendor.dreame**: Switch to async map preprocessing to not block the event loop [`3b5743b`](http://github.com/Hypfer/Valetudo/commit/3b5743b41264c3d8d36d8cc0a75da30e90bb7338)\r\n- **miio**: Further improve fds upload timeout handling [`8c1ba9e`](http://github.com/Hypfer/Valetudo/commit/8c1ba9ea2fcc980bf726a4678902afd2577a0191)\r\n- **miio**: Gracefully handle connectivity issues when receiving fds uploads [`8aab94f`](http://github.com/Hypfer/Valetudo/commit/8aab94fa2ab01479997968904e9312fbc8111a83)\r\n- **vendor.dreame**: Ignore timezone update message [`5ecf7fa`](http://github.com/Hypfer/Valetudo/commit/5ecf7fa0842c498a2ad8abfd792a71b420ce34bf)\r\n- **ui**: Allow sending home basic control command while paused [`0dfb4ba`](http://github.com/Hypfer/Valetudo/commit/0dfb4ba59bd1334f994beea211ac17fdf5323f1f)\r\n- **vendor.dreame**: Fix maps for newer firmwares [`5f67103`](http://github.com/Hypfer/Valetudo/commit/5f6710348fd304046a201c2423490555e44d3b20)\r\n- **webserver**: Fix openapi schema for MapSegmentEditCapability [`f106735`](http://github.com/Hypfer/Valetudo/commit/f106735cbae0eed2ebfebaa6843c7da976c5127e)\r\n\r\n### Refactoring\r\n\r\n- **webserver**: Response cleanup [`839310a`](http://github.com/Hypfer/Valetudo/commit/839310ab0941941d68ea4ba0c1fbfc17b8924443)\r\n- **webserver**: Actually make use of the openapi schema validation [`6e2d2e1`](http://github.com/Hypfer/Valetudo/commit/6e2d2e1904040aa891dda5d35909654553e04eb7)\r\n- Introduce RobotFirmwareError and refactor CapabilityRouter for unified error logs [`1d2ad47`](http://github.com/Hypfer/Valetudo/commit/1d2ad47e9d49eac71f0621d2aa0444acf871acec)\r\n\r\n### Chores\r\n\r\n- **release**: 2022.08.0 [`214b5c0`](http://github.com/Hypfer/Valetudo/commit/214b5c0c11c0cf70fa56ff915fda05e064a18355)\r\n- Minor cleanup [`9356ba8`](http://github.com/Hypfer/Valetudo/commit/9356ba8e19825a1602cd842db9487389aa553ccf)\r\n- **vendor.dreame**: Fix tests [`15eee37`](http://github.com/Hypfer/Valetudo/commit/15eee3749e41fc77ddf62fbaf8fc348f8d872672)\r\n- **mqtt**: Minor cleanup [`4ae1d03`](http://github.com/Hypfer/Valetudo/commit/4ae1d0365d2b54f9d27c49caf5e38b915ff47e4c)\r\n- Minor misc cleanups [`7bf3c87`](http://github.com/Hypfer/Valetudo/commit/7bf3c87db34a8f27624fe735737a4ccd17fbf8bc)\r\n- Add eslintrc flavors [`b3843f8`](http://github.com/Hypfer/Valetudo/commit/b3843f8bd3c95346735d674f7df4543ff5f78b81)\r\n- Add close_threads github workflow [`e10313d`](http://github.com/Hypfer/Valetudo/commit/e10313dc75a0f7867d64c195fbd9ef69ca3b199b)\r\n- **ui**: Add missing rel=\"noopener\" tag to menu bar [`a7e6920`](http://github.com/Hypfer/Valetudo/commit/a7e6920c7924b5db43b9eb086a434fddaa276d75)\r\n- **build**: Bump to NodeJS v18.5.0 [`66712f9`](http://github.com/Hypfer/Valetudo/commit/66712f91dd3f16c24b0b22b334a37ecfeb983df9)\r\n- Update wording in VoicepackHelp.ts [`05a6b89`](http://github.com/Hypfer/Valetudo/commit/05a6b89848b5c1e9a04f4a822da58e03cd89b5f8)\r\n- Update issue template [`cebca05`](http://github.com/Hypfer/Valetudo/commit/cebca057ceb05d202f3f76211a2e63290f39b002)", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495" + } + }, + { + "version": "2022.06.0", + "releaseTimestamp": "2022-06-13T18:16:34.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.06.0

\r\n
\r\n\r\nAnother maintenance release featuring upgraded dependencies, refactoring and some bugfixes\r\n\r\n## Bonjour/mDNS fixes\r\n\r\nUsers can now discover multiple robots of the same model in their home network:\r\n\r\n[](https://user-images.githubusercontent.com/974410/173417472-ca0d279e-05f2-4980-9f1b-d46af2897882.png)\r\n\r\nApparently, the Bonjour service name needs to be unique or else _some_ bonjour implementations will deduplicate it.\r\nBecause of this, the companion app only displayed one robot even though there were multiple ones on the network.\r\n\r\n\r\n## Nightly build enhancements\r\n\r\nThe nightly update provider will now display a changelog of all changes since the last release.\r\n\r\n[](https://user-images.githubusercontent.com/974410/173417506-3f156a64-4130-48cc-ab21-6bdabf747707.png)\r\n\r\nYou can switch to the nightly update provider by changing the `updater.updateProvider.type` in your `valetudo_config.json` to `github_nightly`.\r\nPlease keep in mind that nightly builds might be unstable. They should only be used by people that know what they're doing and are willing to handle occasional breakage.\r\n\r\n## UI Improvements\r\n\r\nMultiple issues that caused the live map to stop refreshing have been fixed.\r\n\r\nChecking back on the Valetudo UI after having it in a background tab for a while during a cleanup will now display the latest map data.\r\nAlso, running Valetudo behind a flaky reverse proxy should not interfere with the SSE connection anymore.\r\n\r\n## Boring chores\r\n\r\nThis release features plenty of dependency upgrades, the migration to create-react-app 5 and more.\r\nIt also contains a lot of refactorings that should further improve the code quality.\r\n\r\nWhile all that doesn't offer any directly noticeable benefits to the user, it is worth noting nonetheless, as keeping the project well-maintained is vital to its longevity.\r\n\r\nThe exciting stuff will hopefully happen later this year :-)\r\n\r\n\r\nApart from code changes, I've been busy figuring out how to build statically linked recent versions of common tools that might be added to our robot firmware images. It's all done using dockerfiles to make it easy to understand, document and reproduce.\r\nInterestingly, information on the internet do to just that is rather sparse so this might also be useful to someone with a different embedded use-case.\r\n\r\nYou can find that stuff here: [https://github.com/Hypfer/valetudo-misc](https://github.com/Hypfer/valetudo-misc)\r\nIf you're missing a tool there please let me know\r\n\r\n## Other news\r\n\r\nAs mentioned in the previous release notes, we're currently still pretty busy figuring out how to root new robots and/or firmware versions.\r\nSince that worked well in the past, I shall continue mentioning it here.\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\nThe autogenerated changelog generation has been updated to be even better and less of a hassle to use.\r\nEnjoy\r\n\r\n### Breaking Changes\r\n\r\n- **timers**: Updating timers should be a PUT instead of a POST [`9c57f0c`](http://github.com/Hypfer/Valetudo/commit/9c57f0c6db069eae796b6fb68766ca2f5d16c907)\r\n\r\n### Features\r\n\r\n- **updater**: Add changelog to nightly update provider [`3a874db`](http://github.com/Hypfer/Valetudo/commit/3a874db088f445d03e71f08f9125ac5ce9cbc4d6)\r\n- **mqtt**: Deduplicate mqtt map data as well [`269aa30`](http://github.com/Hypfer/Valetudo/commit/269aa3004f3925e26afe66139109b201133afcfe)\r\n\r\n### Fixes\r\n\r\n- **networkadvertisement**: Bonjour service names need to be unique [`956487e`](http://github.com/Hypfer/Valetudo/commit/956487ee1f06e571371eb237aa87a86e50969356)\r\n- **ui**: Remove obsolete css statement [`6793c67`](http://github.com/Hypfer/Valetudo/commit/6793c67eb12bb4bf90a83adfb22c0dca01b741ef)\r\n- **ui**: Fix map SSE EventSource not reconnecting on error [`d84efd5`](http://github.com/Hypfer/Valetudo/commit/d84efd586122aff81cab8524517cc2c5a0b7b37b)\r\n- **ui**: fix circular chunk dependency [`271e53c`](http://github.com/Hypfer/Valetudo/commit/271e53c6fa6aa659f94e14e4fd10934901857b82)\r\n- **ui**: Fix map not properly redrawing on visibility state change [`bd77d2e`](http://github.com/Hypfer/Valetudo/commit/bd77d2e22adc33813fb4ab5e3897e6b58d5340e2)\r\n- **utils**: hash key instead of value (#1503) [`bae09ab`](http://github.com/Hypfer/Valetudo/commit/bae09ab9f1d09ca98cd54272aab96afac05e52cb)\r\n- **miio**: Fix ERR_HTTP_HEADERS_SENT exception (#1501) [`a47f3b9`](http://github.com/Hypfer/Valetudo/commit/a47f3b9c97c4abd3f8a5c9a61750312ffce05800)\r\n- **vendor.dreame**: The STYTJO6ZHM does not feature a watertank [`9b75974`](http://github.com/Hypfer/Valetudo/commit/9b7597420084cd579ce9990667d1118c8d5a27ed)\r\n- **vendor.roborock**: copy statusflag from previous state on state update (#1497) [`84de0ef`](http://github.com/Hypfer/Valetudo/commit/84de0ef9d869f5150c504fa13bcd49956c71bf4c)\r\n\r\n### Refactoring\r\n\r\n- **updater**: Move type constant to update providers [`5ca525e`](http://github.com/Hypfer/Valetudo/commit/5ca525ec8f6899f577cc21a616e0fbcf26b2c76e)\r\n- **vendor.roborock**: Improve logic legibility in ZoneCleaningCapability [`560a50e`](http://github.com/Hypfer/Valetudo/commit/560a50edfca23c6a80378f0bed9cc3c1a533d8bc)\r\n- **ui**: Port map color finder to typescript [`6c1b126`](http://github.com/Hypfer/Valetudo/commit/6c1b126138f4e8b751913eb4d4c411a22d7f492c)\r\n- **ui**: Make use of webpack 5 and convert the map layer render webworker to typescript [`d17b66d`](http://github.com/Hypfer/Valetudo/commit/d17b66d6be3381a9c14cf3dfe118f560bd5ed408)\r\n- **ui**: Port map touch handling to typescript [`9548012`](http://github.com/Hypfer/Valetudo/commit/95480129dbf4d72eb2e87a7a0ac1d9c18e429369)\r\n- **ui**: Do not monkey patch the 2d context of the map renderer [`212e4f5`](http://github.com/Hypfer/Valetudo/commit/212e4f541b14a9d5a55d4fe10d54a5c173fc2800)\r\n- **ui**: Remove unnecessary nullchecks in the map component [`96ba8cf`](http://github.com/Hypfer/Valetudo/commit/96ba8cf83f6a4d0c9235359b77414e0cbd70d658)\r\n- **vendor.dreame**: Improve mop dock settings handling [`412a65a`](http://github.com/Hypfer/Valetudo/commit/412a65ab4c5cf3c7ba061ea59d61c88c1d345e34)\r\n- **miio**: Unify previously duplicated map poll code [`356d144`](http://github.com/Hypfer/Valetudo/commit/356d144b9cd15840ccd32c2b2a0a21cb0fa011a8)\r\n\r\n### Chores\r\n\r\n- **release**: 2022.06.0 [`3504a4a`](http://github.com/Hypfer/Valetudo/commit/3504a4a6974afe4ff35d52ab1d676104a77ca86b)\r\n- Fix nightly changelog generation [`2c73de3`](http://github.com/Hypfer/Valetudo/commit/2c73de3cb7d4a564c4b3306e37a5bfa3f3755ff2)\r\n- Minor misc code cleanups [`3c3c561`](http://github.com/Hypfer/Valetudo/commit/3c3c5617dfac3b8a48f43e695c005d95593857ac)\r\n- More dependency changes [`0becd44`](http://github.com/Hypfer/Valetudo/commit/0becd4490b397539de3a8a6593e547cbc4fcba15)\r\n- Delete obsolete Events.js [`5176cce`](http://github.com/Hypfer/Valetudo/commit/5176cce43a9dff88d7acfc39038b3b4e7c303a86)\r\n- Bump dependencies [`8ae420c`](http://github.com/Hypfer/Valetudo/commit/8ae420c1576331dd26acfdf2d3e7a83ff05ebf06)\r\n- bump GitHub codeql action to v2 [`643dcc5`](http://github.com/Hypfer/Valetudo/commit/643dcc581c556797bc6b989dde25671e9ad55378)\r\n- **vendor.dreame**: Add documentation on the mop dock settings data format [`881f717`](http://github.com/Hypfer/Valetudo/commit/881f717ac37505c7f113b6c82f6754837e8a9d43)\r\n- typo fix [`41055d1`](http://github.com/Hypfer/Valetudo/commit/41055d1c9a4615fe9664487e66ec7e9a81773428)", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065" + } + }, + { + "version": "2022.05.1", + "releaseTimestamp": "2022-05-08T09:27:12.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.05.1

\r\n
\r\n\r\nA small incremental release featuring a few UI/UX improvements\r\n\r\n## MQTT/REST Segment/Zone/GoTo improvements\r\n\r\nThis release adds an easy way of getting the payload to automate zoned cleanups, segment cleanups and go-to commands via MQTT or REST.\r\nSimply set up your zones/select your presets as you'd usually do but instead of just clicking the cleanup button, long-press it, and you will receive a dialog containing the copy-pastable payload for MQTT/REST. `ctrl + a` also works :)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/167289945-4b84df5c-8ebd-4dc4-a121-efc997454aab.png)\r\n\r\n\r\n## Client Map Structure Visibility\r\n\r\nThis release adds a shadow to zones drawn onto the map to improve visibility especially when using the light theme.\r\n\r\nBefore:\r\n![image](https://user-images.githubusercontent.com/974410/167289951-151daef5-bbcf-4fbd-b81c-5674ef12c74f.png)\r\n\r\nAfter:\r\n![image](https://user-images.githubusercontent.com/974410/167289957-d6422c64-7feb-4ab1-905f-cb76ffd38d16.png)\r\n\r\n\r\nFurthermore, NoGoAreas and VirtualWalls now are slightly less transparent to improve visibility on orange segments.\r\n\r\n## Map Crispness\r\n\r\nAt some point for some reason, the map renderer canvas lost the `image-rendering: crisp-edges` css property, which caused occasional blurry maps.\r\n\r\nThis has been fixed. We can now all again enjoy crisp edges :)\r\n\r\nUncrisp edges:\r\n![image](https://user-images.githubusercontent.com/974410/167289962-65a5ffc4-0b86-490a-959e-1f27f3570470.png)\r\n\r\nCrisp edges:\r\n![image](https://user-images.githubusercontent.com/974410/167289969-0d3d78cd-b71e-4dd9-8092-2608b43acee4.png)\r\n\r\n\r\n## Node V18\r\n\r\nThe base binaries have been upgraded to the latest NodeJS v18.1.0.\r\nThey're also now built with `-Os`, which decreased our binary size by a few percent.\r\n\r\n## Other news\r\n\r\nAs mentioned in the previous release notes, we're currently still pretty busy figuring out how to root new robots and/or firmware versions.\r\nSince that worked well the last time, I shall continue mentioning it here.\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Get payload of segment/zone cleanup via long-press ([52731bf](https://github.com/Hypfer/Valetudo/commit/52731bf3b218b58f8469342bcdfdb08f9725ccb1))\r\n* **vendor.roborock:** Add support for the M1S ([f234925](https://github.com/Hypfer/Valetudo/commit/f234925aef5415784c9358f39435aa7e01d9ef79))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Limit the maximum fdsUpload filesize ([c1de1c5](https://github.com/Hypfer/Valetudo/commit/c1de1c59084cfe9dfcd9f5659c4be92b153bbfc2))\r\n* **miio:** process _async.stat, _otc.ncstat and _otc.ncinfo messages ([#1488](https://github.com/Hypfer/Valetudo/issues/1488)) ([7cf1fe9](https://github.com/Hypfer/Valetudo/commit/7cf1fe98b7546fa97ad06ce75e04952e436fcbb2))\r\n* **ui:** Add shadow to some client structures for better visibility ([d4e7f83](https://github.com/Hypfer/Valetudo/commit/d4e7f83521b4324bbf9263822d33f7603765d088))\r\n* **ui:** Fix map crispness ([e55a5dc](https://github.com/Hypfer/Valetudo/commit/e55a5dc646e12b3cda2510ff3e792d2d88aa0ee3))\r\n* **ui:** Improve visibility of red virtual restrictions on orange segments ([797143a](https://github.com/Hypfer/Valetudo/commit/797143a1b330c2bcbc44deb4dead656eb381cc56))\r\n* Work around Node v18 breaking os.networkInterfaces ([226dae1](https://github.com/Hypfer/Valetudo/commit/226dae13b9ebd49797d6b0e2f0dacd9ac394cd53))\r\n* **vendor.roborock:** copy metadata from previous state on state update ([#1489](https://github.com/Hypfer/Valetudo/issues/1489)) ([6ecc76b](https://github.com/Hypfer/Valetudo/commit/6ecc76b843e5a582936702f4a5c0fea04a9a4d07))\r\n* **vendor.roborock:** Ignore event.fan_power_reduced ([c56e7a2](https://github.com/Hypfer/Valetudo/commit/c56e7a26df92e628906f78e7b2ee28b243dcd70b))\r\n* **vendor.roborock:** Multiple fixes for Mijia 1S ([#1485](https://github.com/Hypfer/Valetudo/issues/1485)) ([c66798d](https://github.com/Hypfer/Valetudo/commit/c66798db6e19a8a2dac494bf10f444795015872f))\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630" + } + }, + { + "version": "2022.05.0", + "releaseTimestamp": "2022-05-01T16:02:49.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.05.0

\r\n
\r\n\r\nSpring-cleaning 2022: Usability improvements, bugfixes and the removal of zone/goto presets + the old UI\r\n\r\n## Zone/GoTo Preset removal\r\n\r\nValetudo 2022.05.0 removes the Zone Preset/GoTo Location feature that has been deprecated since more than six months now.\r\n\r\nAs a replacement for this feature, the MQTT interface now accepts coordinates instead of preset IDs.\r\nThus, users can just change the place where they store their coordinates from the Valetudo config file to e.g., the Home Assistant config files.\r\n\r\nPlease head over to the MQTT docs to find out how to use it.\r\nIt's the same payload that is used by the REST API. No surprises there.\r\n\r\n
\r\nIf you're unhappy and/or like to know more about why this change was done, feel free to click on this spoiler\r\n\r\n
\r\nFeature removal is delicate topic, since there always will be at least one person that is very upset and unhappy with whatever change was done to a project. See also: XKCD 1172.\r\n\r\nStill, it has to be done once in a while to keep a clean codebase and focus on what is most important.\r\nWithout these kinds of cleanups, projects eventually grow to a point when they start suffocating under their own weight.\r\n\r\nIf you've ever worked with larger legacy enterprise codebases, you should understand the issue.\r\nThey tend to be torn apart by\r\n\r\n- legacy features/behaviour having to stay like they are for existing customers/long-running support contracts\r\n\r\nand\r\n\r\n- management, sales and the market in general demanding newer features that no one could ever have predicted previously\r\n\r\nSee also this anecdote on Oracle 12.2 found on Hackernews.\r\n\r\n\r\nAs avid listeners of my ramblings have likely been aware, I've been very unhappy with that preset feature for more much more than just half a year now.\r\nIt was always a very fragile feature to begin with, given that Valetudo itself would store these coordinates without knowing anything about the underlying map.\r\nThe robot might've decided to rotate the map, leading to them pointing to a completely different location without Valetudo being able to catch that.\r\n\r\nAt the time when it was added, it was the best we had, given that map segments simply weren't invented just yet.\r\nWe didn't even have persistent maps, which is very strange to look back to.\r\n\r\nThat however was almost four years ago. Since then, the market changed a lot as you can tell.\r\nBasically every robot now supports not only persistent maps but also the map segmentation, which is handled by the firmware and not Valetudo.\r\nThose are objectively superior to some rectangles that are drawn onto the map, which is why it was finally time to remove this hack.\r\n\r\n\r\nI know that this may be bad news for V1 owners who do not have segments support and also don't want to use something like Home Assistant.\r\nHowever, I'd like to point out that there is nothing forcing anyone to upgrade to a newer Valetudo version.\r\nThere is no automatic update check that periodically annoys the user.\r\nThere is no cloud that will change its API.\r\nIt just works and will continue to do so.\r\n\r\nTherefore, for those who want to continue using zone presets and goto locations, it is recommended to stick with Valetudo 2022.03.1.\r\nIt also shouldn't be too hard to backport changes to that version. I however simply can't provide that kind of support.\r\nI hope that you will all understand that.\r\n
\r\n
\r\n\r\n## Removal of the old UI\r\n\r\nWith the presets gone, we can finally remove the old frontend entirely, which reduced the binary size by around 1MiB.\r\nWhile this doesn't sound like much given that it's \"only\" 3%, it's important to note that currently, 24MiB of the armv7 build consist of the bundled nodejs runtime. This means that with this update, the size of Valetudo itself shrunk by **15%**!\r\n\r\n## UI improvements\r\n\r\nThe menu opening thingy of the mobile UI now always stays at the bottom of the screen to improve user experience when using long phones.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154092-65a71eec-1af7-4268-83c2-50c827065824.png)\r\n\r\n\r\nThe live map now renders virtual restrictions with more opacity and less bright colors as they were pretty obstructive previously.\r\nThe edit map remains unchanged.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154102-0d9f9700-59a2-42af-a488-6cb953b97add.png)\r\n\r\n\r\nThe log viewer now uses the jetbrains mono font.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154108-8bb2a3ec-4dbe-4ae2-9af9-00eb2a5921f4.png)\r\n\r\n\r\n## Attachments\r\n\r\nYour robot will now only report and display attachments whose state it is able to track. No more always attached dustbins confusing users.\r\n\r\n\r\n## Companion apps\r\n\r\nOver the last weeks, a few new companion applications were built:\r\n\r\n1. valetudo-tray-companion\r\n\r\n A tray icon that allows easy access to Valetudo instances on your network. It's mostly handy when dealing with 4+ robots\r\n\r\n2. valetudo-helper-miioota\r\n\r\n A standalone all-in-one firmware update flasher tool for roborock v1 and s5. The docs have been updated to suggest using it\r\n\r\n3. valetudo-helper-httpbridge\r\n\r\n A standalone self-contained utility webserver currently most useful for rooting dreames. The docs have been updated to suggest using it\r\n\r\n4. valetudo-helper-miio\r\n\r\n A standalone self-contained utility to send raw miio commands. Useful for development of valetudo or other software interacting via miio\r\n\r\n5. valetudo-helper-voicepacks\r\n\r\n A WIP tool to help with Voicepacks\r\n\r\nThese should make installation and usage of Valetudo even easier than before.\r\n\r\n## Other news\r\n\r\nWe're currently pretty busy figuring out how to root new robots and/or firmware versions.\r\nThese endeavors are partly funded by your donations. Thank you!\r\n\r\nIf you want to see Valetudo on more robots, you might want to consider donating:\r\n\r\nhttps://github.com/sponsors/Hypfer\r\n\r\nhttps://builder.dontvacuum.me/donations.txt\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Provide attachment state attributes autodiscovery for home assistant ([b7b6344](https://github.com/Hypfer/Valetudo/commit/b7b6344281183fa022d83f4635894af3beae7a97))\r\n* **ui:** Improve mobile controls for long screens ([f7f3f0d](https://github.com/Hypfer/Valetudo/commit/f7f3f0db6e155aff25344d293e9822b589e43d9a))\r\n* **ui:** Reduce live map obstructions caused by virtual restrictions ([ddec0b3](https://github.com/Hypfer/Valetudo/commit/ddec0b34b215cc9b81d5b2e86926c8b73e446ca5))\r\n* **ui:** Use JetBrains Mono ([5a7045c](https://github.com/Hypfer/Valetudo/commit/5a7045c1a03c97bf892738d40999824fb2ae6a81))\r\n* **vendor.dreame:** 1C PendingMapChangeHandling ([1b2f3bf](https://github.com/Hypfer/Valetudo/commit/1b2f3bf0055587faadaaa2bd841449e887de0a49))\r\n* **vendor.dreame:** Add support for the STYTJO6ZHM ([519c5b4](https://github.com/Hypfer/Valetudo/commit/519c5b4a437868e9d7de2e20448bbc6d1f1cfceb))\r\n* **vendor.viomi:** Fetch and display firmware version ([7f08743](https://github.com/Hypfer/Valetudo/commit/7f087438e08e66a5663ae6f52868249cb5348659))\r\n* **vendor.viomi:** Raise zone count limit to 10 ([8130e24](https://github.com/Hypfer/Valetudo/commit/8130e24dc31be40d76a4f417ca8ceb7f40751de5))\r\n* Provide list of attachments supported by the model of robot ([fe65df3](https://github.com/Hypfer/Valetudo/commit/fe65df3696d2a0af608db27c54f32b49bcb88635))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** MqttController default state should be disconnected ([137e630](https://github.com/Hypfer/Valetudo/commit/137e630147eadb06673d269920f29abed07c7dcf))\r\n* **networkadvertisement:** Disabling the Network advertisement multiple times in a row should not cause any issues ([789608f](https://github.com/Hypfer/Valetudo/commit/789608f8cc384692ad05c66223480a555843c729))\r\n* **ui:** Allow closing of ValetudoEvents even if there are a lot ([ec599b2](https://github.com/Hypfer/Valetudo/commit/ec599b2f7ed2b328f0ab801ac029902eec54e7fe))\r\n* **ui:** Fix auto empty dock control loading state ([7ec1e5d](https://github.com/Hypfer/Valetudo/commit/7ec1e5d62cd53c8829cb70bc46a0402b5a3306d6))\r\n* **ui:** Handle timers with invalid actions ([b467443](https://github.com/Hypfer/Valetudo/commit/b4674433c40a576cc4c51e97a7a6ea9aedfcf29a))\r\n* **ui:** use correct relative paths to allow hosting in a subdirectory ([6129ec5](https://github.com/Hypfer/Valetudo/commit/6129ec5f4282edf07de1a5173fcf3a88067fe151))\r\n* **vendor.dreame:** Fix 1C powersave state mapping ([fdb51e7](https://github.com/Hypfer/Valetudo/commit/fdb51e7945fd908dec498b8b0b90a272227daf47))\r\n* **vendor.roborock:** Don't update state for attachments that we don't have ([f27bbfd](https://github.com/Hypfer/Valetudo/commit/f27bbfd97f71fb5f4b0c6dea4c3be9cf8774d22d))\r\n* **vendor.roborock:** Fix manual control for roborock v1 ([abccee4](https://github.com/Hypfer/Valetudo/commit/abccee47dbdd8972431cad3873029c502a093928))\r\n* **vendor.roborock:** Fix obnoxious \"no error\" error event ([f3b4a54](https://github.com/Hypfer/Valetudo/commit/f3b4a548dffc3aa96c2ecdf37c063b73847b0d5e))\r\n* **vendor.roborock:** Remove confusing attachments that never get updated ([e4274d3](https://github.com/Hypfer/Valetudo/commit/e4274d3da8ba64d0bc31f9d7683a4f3fbf91c79a))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409" + } + }, + { + "version": "2022.03.1", + "releaseTimestamp": "2022-02-25T23:43:51.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.03.1

\r\n
\r\n\r\nOrdered segment cleanups via the UI, MQTT deduplication and a lot of internal refactoring\r\n\r\n## Ordered segment cleanup\r\n\r\nThe UI now tracks the order in which segments were selected, meaning that if your robots' firmware supports it, they will be cleaned in the order you've specified.\r\n\r\nIf supported, the order will be displayed as a roman numeral above the segment label triangle.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770812-180860d1-44f4-4531-a746-eff91e97e0cf.png)\r\n\r\n## MQTT\r\n\r\nThe MQTT connectivity feature now reports a state to the UI. Furthermore, it also collects some statistics.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770843-92204a3d-23e6-469f-b053-704ff2ec2347.png)\r\n\r\n\r\nBy watching those stats, you will notice that this release also causes less traffic, as most outgoing messages are deduplicated.\r\n\r\nInitially, I didn't want to do that as the solution proposed was to just store every payload in memory and then compare on each mqtt publish.\r\nThat would work, however it comes with a hefty ram overhead as you now have to constantly keep 300+ somewhat long string payloads in memory.\r\nWith each character taking up 2 byte, this approach isn't feasible with the ram budget we have (32 Mbyte or less).\r\n\r\nTo reduce the amount of ram required, we could use a hash function such as md5, however that would still be too much.\r\nAs they'd be saved as hex strings, that would mean 32 characters each with each character taking up 2 bytes, resulting in each pair of topic and payload using 128 byte or more.\r\n\r\nThus, instead we're now using 32-bit CRC32. With object keys being strings, I'd think that these pairs should use around 20 byte each.\r\nThe downside of CRC32 is that the risk of collisions is much higher. However, I highly doubt that that could actually happen in this application.\r\n\r\nTo save CPU time, which is also quite limited on our robots, the (in comparison) huge map data is not being deduplicated.\r\n\r\n## Misc\r\n\r\n- The system information page will now display the current robot firmware version if available\r\n- The UI will now prevent the user from configuring invalid MQTT topic names (containing spaces, # or +)\r\n- The UPnP/SSDP lib was dropped in favour of our own implementation, which should fix some unhandledRejections caused by the lib\r\n- The log viewer now doesn't scroll back down automatically if the user scrolled up\r\n- TotalStatistics should now also work for the Roborock S7\r\n- It is now possible to disable network advertisement (bonjour/mDNS and UPnP/SSDP) via the UI if you so desire\r\n- The nonsensical always-attached dustbin attachment has been removed\r\n- It is now possible to have 50% more virtual restrictions on roborock robots\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Allow setting the order of segments cleaned if support by the robot ([9eec3b6](https://github.com/Hypfer/Valetudo/commit/9eec3b6200dee08d4094fdac47e9200e9585961e))\r\n* NetworkAdvertisementManager UI control ([bd5fa9c](https://github.com/Hypfer/Valetudo/commit/bd5fa9c1d156cab2b499952acb7664ebee554623)), closes [#1168](https://github.com/Hypfer/Valetudo/issues/1168)\r\n* **core:** Remove outdated VirtualWallCapability and RestrictedZoneCapability ([5e24783](https://github.com/Hypfer/Valetudo/commit/5e247835e3772ed57d445c8be82849bcedba6db6))\r\n* **core:** Remove SensorCalibrationCapability ([5b081a7](https://github.com/Hypfer/Valetudo/commit/5b081a78a4dbccf54ad2fb547daaa622ce8c8c7f))\r\n* **mqtt:** Collect runtime metrics and provide them via REST ([dcc1db4](https://github.com/Hypfer/Valetudo/commit/dcc1db4f86265be47242d2f836ba3ffac521ed67))\r\n* **ui:** Display firmware version if available ([e78e9b4](https://github.com/Hypfer/Valetudo/commit/e78e9b4e1dc84b7ce2b60adb36ec35675664ded0))\r\n* **ui:** Display MQTTClient status ([c54ebc8](https://github.com/Hypfer/Valetudo/commit/c54ebc8c1eae6c14a35247e7e55ce2bb2e0d0ccd))\r\n* **vendor.roborock:** Support S7 total statistics ([d1926a9](https://github.com/Hypfer/Valetudo/commit/d1926a9b33dfdbdf53f8b3b53ef0ee695c53c867))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Fix free memory reporting on kernels >= 3.14 ([dceea16](https://github.com/Hypfer/Valetudo/commit/dceea16f5a3fbc7b69ea938dd3c112e12a874019))\r\n* **miio:** Don't throw plain objects on error responses ([e84fe8c](https://github.com/Hypfer/Valetudo/commit/e84fe8c066b3ad3b7576405ee7d8cd8f17fd3d85))\r\n* **miio:** Fix RetryWrapper never handshaking on stale stamp ([326cb4b](https://github.com/Hypfer/Valetudo/commit/326cb4bafda8b558e8eff2937aa034d3ae25306a))\r\n* **mqtt:** Deduplicate outgoing messages ([b835336](https://github.com/Hypfer/Valetudo/commit/b835336089aa02430cdeb7e877353869fd3e363d))\r\n* **networkadvertisement:** Replace ssdp lib with custom implementation ([f5e505a](https://github.com/Hypfer/Valetudo/commit/f5e505ae3c04313237a0648e5a35d04b6af59ef6))\r\n* **ui:** Disallow whitespaces, + and # for mqtt topic customization ([8148736](https://github.com/Hypfer/Valetudo/commit/81487363a0158c643ce55c7d555790d02d35d48a))\r\n* **ui:** Make the logviewer only auto-scroll if it is already scrolled down ([3c24eba](https://github.com/Hypfer/Valetudo/commit/3c24eba7794b01188f8e0446c4b6dc73c23af96c))\r\n* **vendor.dreame:** Mapping passes can only be done by lidar-based robots ([411fab5](https://github.com/Hypfer/Valetudo/commit/411fab5496c9c2eba9f488d7d97a742073ddf3de))\r\n* **vendor.dreame:** Re-enable custom order segment cleanups and hope for the best ([744a4bb](https://github.com/Hypfer/Valetudo/commit/744a4bb8558e2c938c3b163b3916a6408478b23b))\r\n* **vendor.roborock:** Fix roborock virtual restrictions counting vertices incorrectly ([cc5e37b](https://github.com/Hypfer/Valetudo/commit/cc5e37b6d4e81987005760f867f2487c40435073)), closes [#1423](https://github.com/Hypfer/Valetudo/issues/1423)\r\n* **vendor.roborock:** Properly parse and handle lab_status and map_status ([e158ac4](https://github.com/Hypfer/Valetudo/commit/e158ac4b7fc58ad9ee06bbf4bb296d054afb77d9)), closes [#1424](https://github.com/Hypfer/Valetudo/issues/1424)\r\n* Remove nonsensical always-attached dustbin attachment ([b9bd959](https://github.com/Hypfer/Valetudo/commit/b9bd9599c9931940cc7536eaccbbe2f11f25e066))\r\n* SegmentIds should be strings ([6325045](https://github.com/Hypfer/Valetudo/commit/63250452dfeeaae0e477dc66060be3136df5a7c2))\r\n* SegmentIds should be strings pt2 ([a8d314d](https://github.com/Hypfer/Valetudo/commit/a8d314d2e8878c58a16c2fd4f58f5e866b4fcf85))\r\n* **ui:** Fix customOrder flag for segmentActions ([07c5281](https://github.com/Hypfer/Valetudo/commit/07c5281ae7b52571f49e0e8d553339cf01b6f450))\r\n\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593" + } + }, + { + "version": "2022.02.0", + "releaseTimestamp": "2022-01-28T10:39:20.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.02.0

\r\n
\r\n\r\nLots of UI changes and more polishing\r\n\r\n## Quirks\r\n\r\nThis release adds the quirks concept, which shall be understood as a catch-all and/or staging area containing vendor-specific toggles that don't fit the generic abstraction that is Valetudo (yet).\r\nThis should make it fairly easy to quickly implement (some of the) exciting new vendor features without jeopardizing the architecture of Valetudo in the long run.\r\n\r\nHere's an example taken from the Dreame Z10:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532264-ff6b848f-0c5a-4083-af92-d3bc29be77a0.png)\r\n\r\n\r\n## Settings\r\n\r\nRobot, Map and Connectivity settings have been reorganized/redone.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532305-e97a3534-3f8a-44bc-8d4d-dec5537d7c70.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532320-456cda6f-b5f7-4104-95f5-4b258d0b576b.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532335-d0a79b27-b1ae-4114-b5f2-e5f2311ed8e0.png)\r\n\r\n\r\nWi-Fi and NTP state display has been redone as well:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532430-07629c75-e112-4d8c-acb6-5138d0d6de3d.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532445-ba2b34b4-6b25-4a22-9a7b-558054405b3f.png)\r\n\r\n\r\n## Quality of Life\r\n\r\nA _lot_ of help text sections and dialogs have been added all around the application to make usage of Valetudo even easier.\r\nThey should also answer a lot of common support questions, so make sure to read them before asking questions.\r\n\r\nFurthermore, all password fields have been updated to feature a plain-text-display toggle.\r\n\r\n\r\n## Total Statistics\r\n\r\nBecause displaying three numbers is boring, @ccoors had the great idea of adding gamification the total statistics feature.\r\nAfter some iteration on that idea, we've ended up with this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532462-7843b526-9c81-4b7f-bffe-1165d7dd02c9.png)\r\n\r\n\r\nThere's also an overview of all achievements:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532488-d0cfc8d4-c477-4ed6-8d48-edcfe6d6bec7.png)\r\n\r\n\r\nI'm very happy with how this turned out. Now we just need to think of more achievements.\r\nIf you have any ideas, feel free to leave them down in the comments.\r\n\r\n\r\n\r\n## Nightly builds\r\n\r\nThere are now automated nightly builds, which you can install using the updater.\r\n\r\nAs this is meant for people willing to accept and capable of handling breakage, there is no UI toggle to switch to nightly builds.\r\nTo enable them, ssh into your robot and change the update provider to `github_nightly`.\r\n\r\n## Misc\r\n\r\n- Viomi consumables have been fixed by @adrez99\r\n- @schinken fixed local access via IPv6\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** WifiScanCapability ([a4fe895](https://github.com/Hypfer/Valetudo/commit/a4fe895c9944ffe8fae6e621a87e2aa70e9aecde))\r\n* **ui:** Add general help ([ec298dc](https://github.com/Hypfer/Valetudo/commit/ec298dc2cf2d81ca40031dfae455abf490f9fcf8))\r\n* **ui:** Add help for dnd, voice packs and the updater ([84c8c04](https://github.com/Hypfer/Valetudo/commit/84c8c04657778795cb7e7acd76bbef001465ba3a))\r\n* **ui:** Add Map Management Help ([9d62c26](https://github.com/Hypfer/Valetudo/commit/9d62c26318ecda5d5a38e21333f56ac0ff1f70c6))\r\n* **ui:** Add quirks help ([77183ed](https://github.com/Hypfer/Valetudo/commit/77183ed3e63c94d30afbefc6d48cab8bf946b9f2))\r\n* **ui:** Add total statistics page ([#1330](https://github.com/Hypfer/Valetudo/issues/1330)) ([8fd0b2e](https://github.com/Hypfer/Valetudo/commit/8fd0b2eb3c59a5b949da8c9c6f0f4230886d48e6))\r\n* **ui:** Allow display of Wi-Fi passwords entered ([89624eb](https://github.com/Hypfer/Valetudo/commit/89624eb5b6c2b8091ab66821ebf1c3f82f119316))\r\n* **ui:** Allow newlines in confirmation dialog ([df2ee4f](https://github.com/Hypfer/Valetudo/commit/df2ee4f0ac0e209ac537a77705a860c5161f756b))\r\n* **ui:** Another achievement ([0ffbef4](https://github.com/Hypfer/Valetudo/commit/0ffbef4f3d64e1c50ae6663c277ef33d9c2e80ce))\r\n* **ui:** Extend map management help ([e1514bc](https://github.com/Hypfer/Valetudo/commit/e1514bcc59f8c0022aef588b58b10e2cc05c1ef9))\r\n* ValetudoWifiStatus may contain a bssid ([86fe2f2](https://github.com/Hypfer/Valetudo/commit/86fe2f207c2f050ca7351c21bd736de4f2d5d27b))\r\n* **ui:** Allow display of entered passwords for mqtt and basic auth ([4e75531](https://github.com/Hypfer/Valetudo/commit/4e7553100abb4dba247fbb036a6539499c619b89))\r\n* **ui:** Disable edit map tap interaction while not docked to reduce confusion ([b68e444](https://github.com/Hypfer/Valetudo/commit/b68e44428b3c2669cae147c8c4f21bbfc9bc016d))\r\n* **ui:** Improve achievement badges ([7eea13e](https://github.com/Hypfer/Valetudo/commit/7eea13e84950d01c044bc69ef385b33908ee20df))\r\n* **ui:** Improve NTP client state display ([0a265a7](https://github.com/Hypfer/Valetudo/commit/0a265a7dce5468e2948a077bd7e6f364212a285b))\r\n* **ui:** More achievements ([892017e](https://github.com/Hypfer/Valetudo/commit/892017ea38c16eee3ac6bc52d8ff5bde76e87ab1))\r\n* **ui:** Move map-related features to map management page ([ea45f01](https://github.com/Hypfer/Valetudo/commit/ea45f01b6a597f43d6000318500936702c89e397))\r\n* **ui:** Move Wi-Fi settings to connectivity ([dff909c](https://github.com/Hypfer/Valetudo/commit/dff909cae688b2106cc526475247cf0659251e46))\r\n* **ui:** Provide an overview of all achievements ([381e3cd](https://github.com/Hypfer/Valetudo/commit/381e3cd4dab807b85d8066ca4aa9f8628fe599d6))\r\n* **ui:** Rename about page to system information ([ad1dd16](https://github.com/Hypfer/Valetudo/commit/ad1dd1608dc0e2668914d7ab7a2eb68cb6978163))\r\n* **ui:** Restructure connectivity settings ([bfe33e4](https://github.com/Hypfer/Valetudo/commit/bfe33e4d4d929741a1a3191559ae84343dbe9a61))\r\n* **ui:** Restructure robot settings ([5c71be4](https://github.com/Hypfer/Valetudo/commit/5c71be44eb4a9f30674af550e230590b203ea82d))\r\n* **ui:** Restructure routers and add about page ([e3a1f13](https://github.com/Hypfer/Valetudo/commit/e3a1f1303bb8693aea0a8ea7ffb32d8fd658110a))\r\n* **updater:** Add nightly builds ([d1a0d91](https://github.com/Hypfer/Valetudo/commit/d1a0d919a6fd7df93031bdb7da469b1b61cdbc13))\r\n* **vendor.dreame:** Add auto empty interval quirk ([1b6205a](https://github.com/Hypfer/Valetudo/commit/1b6205a467304bcd4c9ce32aa28721fe0fd377f5))\r\n* **vendor.roborock:** Add quirks ([7fc584a](https://github.com/Hypfer/Valetudo/commit/7fc584af029efbe2a7b8e063fb9659afa43d0955))\r\n* **vendor.viomi:** Add quirks ([#1369](https://github.com/Hypfer/Valetudo/issues/1369)) ([b369e4d](https://github.com/Hypfer/Valetudo/commit/b369e4d7a253bd668f354f179a878fd8ce9c0717))\r\n* QuirksCapability ([79deeb1](https://github.com/Hypfer/Valetudo/commit/79deeb14eb855e294f0b9d3197151e8af5cc03ce))\r\n* **webserver:** Allow IPv6 requests from own network ([#1342](https://github.com/Hypfer/Valetudo/issues/1342)) ([165deff](https://github.com/Hypfer/Valetudo/commit/165deff8e033b45ec1e507d4678833dbca8b22d4))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix consumables not being polled by the autorefresh ([58d6267](https://github.com/Hypfer/Valetudo/commit/58d6267e3008c6637725ed7f531f07d182b01ddf)), closes [#1355](https://github.com/Hypfer/Valetudo/issues/1355)\r\n* **networkadvertisement:** Attempt to catch issues of the ssdp lib ([ee3154b](https://github.com/Hypfer/Valetudo/commit/ee3154bfdb6c5caadc22382e0e48e9a42a2df202))\r\n* **ui:** Allow refetching when there are zero quirks ([7f3ed2b](https://github.com/Hypfer/Valetudo/commit/7f3ed2b8b688ecf9f26436209625dda35e654b62))\r\n* **ui:** Allow user-selection of wifi IP addresses ([33c9470](https://github.com/Hypfer/Valetudo/commit/33c9470162ba4fe6ae2bbf5ba2de26ea08f1d47f))\r\n* **ui:** Allow user-selection of wifi IP addresses... again ([2bdcea4](https://github.com/Hypfer/Valetudo/commit/2bdcea4701b8828dfbcdde79aac12823ece07295))\r\n* **ui:** Disable updater buttons when busy ([f82ae1a](https://github.com/Hypfer/Valetudo/commit/f82ae1a0a114c3255c43d2700cab54a9f87067ff))\r\n* **ui:** Don't display updater warning if state is busy ([4d5c781](https://github.com/Hypfer/Valetudo/commit/4d5c7811b74c3a61f3eebaf1064bb18f6a1810a0))\r\n* **ui:** Don't provide the wifi configuration route if there is no wifi configuration capability ([82e954e](https://github.com/Hypfer/Valetudo/commit/82e954e2d072dcf7888aeef7eb732b78a73311f4))\r\n* **ui:** Fix about title ([67a9a05](https://github.com/Hypfer/Valetudo/commit/67a9a051c7d2071099a57a3a6dbf1e4fa101ca31))\r\n* **ui:** Fix display of text in conjunction with controls in Map Management ([1cc76c5](https://github.com/Hypfer/Valetudo/commit/1cc76c55f3c27be5f03e5a7cbfd6cc184ad40675))\r\n* **ui:** Fix logviewer timestamp display for chrome ([56f5ba0](https://github.com/Hypfer/Valetudo/commit/56f5ba08a9bc864eb20df9b17f109c0b1a89226e))\r\n* **ui:** Fix map management not using unique keys for all options ([2305b52](https://github.com/Hypfer/Valetudo/commit/2305b528be28351e3e02f6197ca88135dc95e64c))\r\n* **ui:** Fix menu drawer scrollbars ([4a6c9fa](https://github.com/Hypfer/Valetudo/commit/4a6c9faffcefba07277372a9172aa6f899d795ad))\r\n* **ui:** fix minor typo ([#1341](https://github.com/Hypfer/Valetudo/issues/1341)) ([77e07ec](https://github.com/Hypfer/Valetudo/commit/77e07ec04bb32407176ff184e706a4229cdffced))\r\n* **ui:** Properly implement newlines in ConfirmationDialog ([b8f8eb0](https://github.com/Hypfer/Valetudo/commit/b8f8eb0163b8b3c13b5a2e1bab27837b8ff90811))\r\n* **ui:** Sort total statistics data points ([a568c03](https://github.com/Hypfer/Valetudo/commit/a568c03afa0521779f40c4933935b5315a81bd24))\r\n* **ui:** use relativ paths to allow hosting in a subdirectory .. again ([3007dbb](https://github.com/Hypfer/Valetudo/commit/3007dbb1460596591199ece1d974c3b4e1db58e3))\r\n* **updater:** Add missing return statement ([f5e7451](https://github.com/Hypfer/Valetudo/commit/f5e7451a5877815a8871cdccdbf997f09b4b78ca))\r\n* **vendor.viomi:** Fix Viomi consumables ([#1367](https://github.com/Hypfer/Valetudo/issues/1367)) ([ccfe175](https://github.com/Hypfer/Valetudo/commit/ccfe175886ac41ff58f900de54657967a8f17337))\r\n* **webserver:** Fix missing doctype for error pages ([3d48611](https://github.com/Hypfer/Valetudo/commit/3d486114830eb69ba2f414aa67fdf4494cfefe3c))\r\n* **webserver:** Fix some endpoints never returning anything ([32c0f6a](https://github.com/Hypfer/Valetudo/commit/32c0f6ae922f71a8fd7ac5b035b9f5fffd1cdc8f))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812" + } + }, + { + "version": "2022.01.0", + "releaseTimestamp": "2021-12-31T12:50:40.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2022.01.0

\r\n
\r\n\r\nQuality of life improvements, bugfixes and more polishing. Also, Happy New Year :)\r\n\r\n## UI/UX Changes\r\n\r\n### Map Management\r\n\r\nThe map management feature has been restructured to be easier to understand especially for newcomers.\r\nFurthermore, there are now help texts available in the editor, which should answer common questions.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824285-2d9337b3-3a50-478a-ae2b-9f216fbcd544.png)\r\n![image](https://user-images.githubusercontent.com/974410/147824293-0c03affb-d343-4f6f-a5ba-4f939c56ec0b.png)\r\n![image](https://user-images.githubusercontent.com/974410/147824290-d1b5f4d2-e4aa-403a-b5a7-82461ec1a6ed.png)\r\n\r\n\r\n### Updater\r\n\r\nThe updater now auto-refreshes its state and provides more feedback.\r\nIt will also display the latest changelog if there's no update available.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824299-49d9aa54-b571-4544-84e9-143a30e5c545.png)\r\n\r\n\r\n### Misc\r\n\r\n- The UI now auto-refreshes if the backend version changed\r\n- Visual consistency has been improved\r\n- The title is now updated based on the page you're on which makes your browser history actually useful\r\n- Hovering over some unlabelled buttons/icons should now give you a tooltip clearing things up\r\n- You can now hover over the progress bars in the about page to get a tooltip for the value as well\r\n- Info boxes answering common questions have been added to the connectivity page\r\n- It should now be possible to use Valetudo in a sub folder of a reverse proxy again\r\n\r\n\r\n## MQTT Changes\r\n\r\n### Home Assistant 2021.12\r\n\r\nValetudo now **requires Home Assistant 2021.12 or newer** as that release introduced the `object_id` field for\r\nMQTT autodiscovery. This allows us to influence the `entity_id` so that the days of `camera.map_data_3` are gone.\r\n\r\nYou might have to delete the device in HA and let it be rediscovered for these changes to be applied.\r\n\r\nIt is worth it though:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824304-96a6d2c9-3ff8-4b6a-965a-dc3ff599ab9f.png)\r\n\r\n\r\n### Bugfixes\r\n\r\nMultiple issues regarding MQTT stability and reliability have been identified and fixed with this release, hopefully\r\nsolving connectivity issues in situations with bad Wi-Fi signal coverage.\r\n\r\n\r\n## External Access\r\n\r\nValetudo now attempts to block access from public-routable IPs to its REST-Interface by default.\r\nThis was necessary, because publicly-accessible Valetudo instances kept appearing \r\non Shodan.io.\r\n\r\nIt is certainly no foolproof solution, but it might at least help a little.\r\nYou can also disable the filter if you absolutely have to, however I'd strongly recommend not doing that.\r\n\r\n## Misc\r\n\r\nAs it turns out, nodes `os.getNetworkInterfaces()` does not return all network interfaces, which led to the unique\r\nsystem identifier randomly changing depending on whether or not the robot had an IP address.\r\nThis has been fixed by the use of the mighty `sysfs`.\r\n\r\nMoreover, Valetudo now polls the network state every 30s in an attempt to catch network changes and restart\r\nthe network advertisement so that the companion app doesn't display `192.168.5.1` right after provisioning.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Remove DebugCapability ([78c84de](https://github.com/Hypfer/Valetudo/commit/78c84ded4eef1ac3b9a3e0d66ef88ebd5d44c19f))\r\n* **ui:** Add hover labels to system ram and load information ([62ed252](https://github.com/Hypfer/Valetudo/commit/62ed252968b97b72662a4a6622f2c0c75bdf2b5b))\r\n* **ui:** Add info boxes answering common questions to the connectivity settings page ([9eae3e3](https://github.com/Hypfer/Valetudo/commit/9eae3e393dda0a7376be79b5b6cdc81c9fc0b27e))\r\n* **ui:** Add link to the docs ([88b810c](https://github.com/Hypfer/Valetudo/commit/88b810c1b454c637c72aa51ab5015f7162e9812a))\r\n* **ui:** Automatically refresh the page when the backend version changed ([905ada1](https://github.com/Hypfer/Valetudo/commit/905ada104441c2283038c4a963a2e197bf511af1))\r\n* **ui:** Change infobox icon ([a82e1df](https://github.com/Hypfer/Valetudo/commit/a82e1df022395e109ddb5ea207be652ce93565e0))\r\n* **ui:** Consolidate paths to a single svg ([82bc46b](https://github.com/Hypfer/Valetudo/commit/82bc46b9e157df21490ad5009beae6277520b564))\r\n* **ui:** Improve first-time usability by adding titles to buttons and more minor changes ([6126718](https://github.com/Hypfer/Valetudo/commit/612671809d2f8ce8018866b2ca8257b34b1d1bbf))\r\n* **ui:** Improve segment edit help ([17e1d5f](https://github.com/Hypfer/Valetudo/commit/17e1d5ffaa0d938317699b89a2244541dd9dad14))\r\n* **ui:** Improve visual consistency ([006b94b](https://github.com/Hypfer/Valetudo/commit/006b94b1c47cbe6376d0340d2c7c0ae82fc26341))\r\n* **ui:** More space for mobile ([6a6ba65](https://github.com/Hypfer/Valetudo/commit/6a6ba65ce7d7d9c4629d39ef9c61ee6e685679bc))\r\n* **ui:** Rework map management ([4f51935](https://github.com/Hypfer/Valetudo/commit/4f51935fe1ea55921c81080c33918355807e23fe))\r\n* **ui:** Use non-swipable drawer for better performance ([25298a0](https://github.com/Hypfer/Valetudo/commit/25298a05ead114dca93c8e4e3b4b39e623838f8d))\r\n* **updater:** Display changelog of latest release when in noUpdateRequired state ([ce0c675](https://github.com/Hypfer/Valetudo/commit/ce0c675eca5548b7bb1fc55a9e2fc40290ce1bb3))\r\n* **updater:** Introduce busy state to provide better user feedback ([4e9ed3d](https://github.com/Hypfer/Valetudo/commit/4e9ed3d0b38a225bb1a93a5d32dee4686b04382b))\r\n* **webserver:** Attempt to block external access to valetudo ([10b1662](https://github.com/Hypfer/Valetudo/commit/10b1662f94d719d03b59c29bd51ab440b7d616dc))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **updater:** fix(updater): Use busy state flag instead of busy state ([d122efcb](https://github.com/Hypfer/Valetudo/commit/d122efcb53f301b124f182ef471e3f9e23c5771b))\r\n* **core:** Use sysfs to reliably determine the unique system identifier in all network conditions ([8d74825](https://github.com/Hypfer/Valetudo/commit/8d74825f4dd8ec3a8414259c3da8671efc694f36))\r\n* **mqtt:** Don't try to publish anything if there is no mqtt connection ([9051ac0](https://github.com/Hypfer/Valetudo/commit/9051ac04156c061f84e50e5e741ab7e65fc8431c))\r\n* **mqtt:** Fix mqtt getting stuck forever requiring a restart ([42a5613](https://github.com/Hypfer/Valetudo/commit/42a5613d19cd46bba0e5243f656d062f8a4d4415))\r\n* **mqtt:** Force disconnect if it takes longer than 1500ms ([ced9ee1](https://github.com/Hypfer/Valetudo/commit/ced9ee1b3312489c0c937723ba8744c21264f540))\r\n* **mqtt:** More .disconnect() fixes ([322efcc](https://github.com/Hypfer/Valetudo/commit/322efcc7cad8e1ae67126ded81b2d327c50bea8d))\r\n* **networkadvertisement:** Attempt to watch for network state changes to fix advertisement after initial provisioning ([7a2c3d1](https://github.com/Hypfer/Valetudo/commit/7a2c3d1a8c32d88562bc2dacec9671e1e756947a))\r\n* **ui:** Redraw map on visibilityState change to fix map not being updated if the tab was invisible for too long ([1c86152](https://github.com/Hypfer/Valetudo/commit/1c861521430e5df4640d614d75dcaa6def09124c))\r\n* **ui:** use relativ paths to allow hosting in a subdirectory ([1e73947](https://github.com/Hypfer/Valetudo/commit/1e73947d2a16bb831bc14d85ebeedb242b7714ef))\r\n* **vendor.dreame:** Ignore more irrelevant property updates ([9e4e202](https://github.com/Hypfer/Valetudo/commit/9e4e2028c69c9a37f661a4c90904311d65c9e90e))\r\n* **webserver:** Handle aborted connections gracefully ([b3e8024](https://github.com/Hypfer/Valetudo/commit/b3e802479e5068df25c951b2e148655c8f7448fa))\r\n\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531" + } + }, + { + "version": "2021.12.1", + "releaseTimestamp": "2021-12-09T13:08:53.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.12.1

\r\n
\r\n\r\nMap data format changes, quality of life improvements and bugfixes.\r\n\r\n## Changes in 2021.12.1\r\n\r\nAs expected, something would go wrong with the map data format change.\r\nThis is a bugfix release, so 98% of the previous changelog still apply.\r\n\r\n\r\nIn 2021.12.0, if you have rooms that aren't rectangular, it might happen that the triangle to select it vanishes, leading to you being unable to trigger a segment cleanup using the UI.\r\nThis happened because in those cases, the UI calculates the median pixel coordinates to properly place the triangle.\r\nThis value isn't calculated by the backend, because it is an expensive operation, and we're both RAM and CPU-limited there.\r\n\r\nTo calculate the median, the UI needs the decompressed pixel coordinate format.\r\nThis works exactly once during the initial render, because of the MapLayerRenderer doing the pixel decompression on the map passed by reference to it.\r\n\r\nAs soon as the WebWorker is available however, this doesn't happen anymore, as the worker only receives a copy of the data.\r\nThis means that there are now 0 pixels as far as the SegmentLabel is concerned, leading it to be placed at coordinates `[NaN,NaN]`.\r\nSince testing is done locally without constant map updates, everything seemed fine during development.\r\n\r\n\r\nAnother thing discovered due to this bug was that the GithubValetudoUpdateProvider did not filter out pre-releases or drafts.\r\nNot a big issue though as it just requires you to update twice in a row.\r\n\r\nAnyways, on with the 2021.12.0 changelog:\r\n\r\n## Map data format changes\r\n\r\nThis release features the first version increment of the ValetudoMap data format.\r\nInitially, in version 1, pixel data such as walls or floor were stored as a huge array of coordinate pairs:\r\n`[x0, y0, x1, y1, ...]`. This was not a very efficient way of storing that data as most of it is redundant.\r\n\r\nThis resulted in map files that were over 1 MiB in size being pushed to your browser every 3 seconds.\r\n\r\nTo combat this, some thought was put into how the data is stored.\r\nIf you have a row of pixels, all of them will have the same y-coordinate, meaning that you only have to store that once.\r\nPeople already figured that out [in the 60s](https://en.wikipedia.org/wiki/Run-length_encoding).\r\n\r\nWith Map V2, pixels are stored as `[xStart0, y0, count0, xStart1, y1, count1, ...]` where `[xStart, y]` is the starting point and `count` represents additional pixels with the same y-coordinate to the right.\r\n\r\nThis resulted in V2 map files using between 5% and 15% of the size of the equivalent V1 map.\r\nThe huge testfile map for example was compressed from 847 kB to 75 kB.\r\n\r\n\r\nWhile this is a **breaking change**, the breakage actually isn't that big of a change as V2 can easily be converted back to V1.\r\nIn fact, running `JSON.parse()` on a V2 map and then converting it to a V1 one in memory is more than twice as fast as running `JSON.parse()` on a V1 map.\r\n\r\nSince this change drastically reduces the traffic caused by live maps, I expect to see general usability and reliability\r\nimprovements in situations where the Wi-Fi reception isn't that great.\r\n\r\n\r\n## LogViewer\r\n\r\nThe LogViewer has been greatly improved and now features a structured and color-coded view of your log.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744519-5ba963b9-6409-4e04-95d9-e73caf55021c.png)\r\n\r\nYou can use the text filter at the top to either filter for the loglevel or the message contents.\r\nJust start typing.\r\n\r\n## UI Help\r\n\r\nBoth consumables and timers now feature a help button, which shall explain how to use these features.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744625-d113d697-e4e1-4f77-a3a2-596ad88131a5.png)\r\n\r\n\r\n## Misc\r\n\r\n- Map reset on newer roborock models should now be fixed thanks to @supersmile2009\r\n- Zooming the map should now work much better if you zoom via a touchpad or trackpoint instead of a mousewheel\r\n- MQTT current statistics now have a unit_of_measurement in HA\r\n- Lowmem builds now have a reduced map poll rate to reduce memory pressure\r\n- Valetudo now manages its logfile size to prevent it from growing indefinitely\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Automatically clear the logfile when it gets too large ([c0698b4](https://github.com/Hypfer/Valetudo/commit/c0698b43dda5144d7d0c2c58d9336a1c0662cc65))\r\n* Reduce map polling interval for lowmem hosts ([fcf94ce](https://github.com/Hypfer/Valetudo/commit/fcf94ceeb60f9b46e25bfa04d2e4e88ac2a25926))\r\n* **ntpClient:** Improve log messages ([8880bbf](https://github.com/Hypfer/Valetudo/commit/8880bbfc7ed79969a61c6d6e51f7023c23d7561e))\r\n* **ui:** Add help button + modal to consumables view ([d1388f1](https://github.com/Hypfer/Valetudo/commit/d1388f124dae0046d2bee49345d0513441926f21))\r\n* **ui:** Add timers help ([c864170](https://github.com/Hypfer/Valetudo/commit/c864170d44c2b686394bb6d770cff937e8a9de43))\r\n* **ui:** Implement LogViewer component ([1b96ae0](https://github.com/Hypfer/Valetudo/commit/1b96ae06c8a74acbc9a6fa03cf941736520e30d0))\r\n* **ui:** Remove obsolete about > github release info ([253d9f9](https://github.com/Hypfer/Valetudo/commit/253d9f99b0965859705c52ffae9483c381d49ad7))\r\n* **ui:** Swap Manual control cw & ccw rotation button ([44eab06](https://github.com/Hypfer/Valetudo/commit/44eab06eadcd57c8c9b3784bc6f4c7a6dbea58e8))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Automatically refresh the updater state ([596dc06](https://github.com/Hypfer/Valetudo/commit/596dc067a6e77d908e3dc11b3e60aeab1e72bd07))\r\n* **ui:** Transparently decompress the v2 map data in the api client ([0bcb974](https://github.com/Hypfer/Valetudo/commit/0bcb974fd9c1ffa8c164b494899ef9c9e1735091)), closes [#1262](https://github.com/Hypfer/Valetudo/issues/1262)\r\n* **updater:** Ignore github release drafts and prereleases ([ad97a14](https://github.com/Hypfer/Valetudo/commit/ad97a146b0989f7caf21c3b834849aca75b9bdc3))\r\n* **ui:** Try avoiding bright flashes on initial loading ([f84a51d](https://github.com/Hypfer/Valetudo/commit/f84a51dc7c09ec4a7cb19e40e3889544375af58a))\r\n* Fix log sse endpoint ([fd6f0e2](https://github.com/Hypfer/Valetudo/commit/fd6f0e2d34ebc2f9de4aa5b23da2fa8ec2e4d630)), closes [#1256](https://github.com/Hypfer/Valetudo/issues/1256)\r\n* **mqtt:** Fix unit_of_measurement for current statistics and consumables ([7f052dc](https://github.com/Hypfer/Valetudo/commit/7f052dc3f64905afd69e35de217cd390377e6ce2))\r\n* **ntpClient:** Delay initial ntp sync to wait for valetudo to start up properly ([727af04](https://github.com/Hypfer/Valetudo/commit/727af04ab54d007c21a3c6ac270036611280e112))\r\n* **ui:** AppBar and menu should not be user-selectable ([69754b7](https://github.com/Hypfer/Valetudo/commit/69754b7204efe81ba147539a04630d644d0e07f4))\r\n* **ui:** Cleanup unused code ([c050940](https://github.com/Hypfer/Valetudo/commit/c05094011540c46737e7829532a319756255b2f3))\r\n* **ui:** Fix map zoom behavior for trackpoint and trackpad scroll zoom ([ca94600](https://github.com/Hypfer/Valetudo/commit/ca9460095eb6e4946f7653328667e8df60c678dc))\r\n* **ui:** Updater changelog should stay in its constraints ([5d815bf](https://github.com/Hypfer/Valetudo/commit/5d815bf98f334b9f40faecaf00f918bb6fecaacb))\r\n* **updater:** Ensure that there is enough space besides process.argv0 to store the new binary ([c298e98](https://github.com/Hypfer/Valetudo/commit/c298e9833cc6dcb2457a52b986daa8f2e81a8850))\r\n* **vendor.dreame:** Fix wrong segment iteration count ([9fd9c17](https://github.com/Hypfer/Valetudo/commit/9fd9c1723e0329b76b89e84cca108cc117a2a736))\r\n* **vendor.dreame:** There are actually no firmware limits for virtual restrictions ([8a8b536](https://github.com/Hypfer/Valetudo/commit/8a8b536b2eb126b9604b58e58cf196824da63be1))\r\n* **vendor.roborock:** Fix resetting incomplete map on Roborock. Detect and reset current map slot. ([#1252](https://github.com/Hypfer/Valetudo/issues/1252)) ([ba86057](https://github.com/Hypfer/Valetudo/commit/ba86057ba7946ee90c6ee7408ca446de56d23136))\r\n* Fix CurrentStatistics UI refresh ([93249ad](https://github.com/Hypfer/Valetudo/commit/93249ad142d4879ea967898f26905645af1c4f2b))\r\n* **ui:** Fix LogViewer overflow-wrap ([4799027](https://github.com/Hypfer/Valetudo/commit/4799027a42e6f5216cb748c75b88b1291a863335))\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037" + } + }, + { + "version": "2021.11.1", + "releaseTimestamp": "2021-11-21T11:43:51.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.11.1

\r\n
\r\n\r\nBugfixes, polishing, two minor breaking changes and new features.\r\nDon't forget: If you're running Valetudo 2021.11.0, you can now use the integrated updater :)\r\n\r\n## UI\r\n\r\n### Polishing\r\n\r\n- Controls in the UI were slightly rearranged/reworked.\r\n- The mobile controls drawer now works slightly different and more importantly more reliably with better performance (+ 50kb less bundle size).\r\n- There's a neat loading splashscreen, which you should only see for longer than a second if your Wi-Fi sucks\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760316-4af4fd83-79dd-4c42-857f-fa71ef2d2bc2.png) ![image](https://user-images.githubusercontent.com/974410/142760318-2b74c894-0572-4a55-8c71-6a655660f081.png)\r\n\r\n\r\n### Provisioning\r\n\r\nThe UI now checks if the robot is connected to a Wi-Fi network and if not opens a special provisioning page.\r\nIt's pretty neat and also fixes the issue of Dreames not being provisionable with the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760331-ee5a4031-c692-49be-9ad8-4144f35bb5e0.png)\r\n\r\n\r\n## Backend\r\n\r\n### CurrentStatisticsCapability\r\n\r\nStatistics related to the current (or most recent) operation of the robot are now back.\r\nYes, they are also being published to MQTT. Stop asking.\r\n\r\nData is published to MQTT as machine-readable (seconds for runtime, cm² for the area) as it is meant to build automations with it.\r\nUsing cm² instead of m² saves us from having to deal with floats.\r\n\r\n### TotalStatisticsCapability\r\n\r\nMore importantly, you can now get total statistics from your robot. \r\n\r\nDepending on your model those can be\r\n\r\n- Total operation count\r\n- Total runtime\r\n- Total area\r\n\r\nThis isn't available via the UI yet as it is yet TBD how to do that.\r\nMaybe have like badges, achievements or a rank system?\r\nMaybe have random trivia related to the numbers? (e.g. having cleaned 0.0001% of the Saarland)\r\n\r\nFeel free to leave your input in the comments. ~~Like, subscribe and click the bell icon~~\r\nIf you're good with graphics design, something like e.g. a Corporal IV vacuum robot badge would be a great contribution.\r\n\r\n## Zeroconf hostname changes\r\n\r\nBy actually reading the relevant RFCs, we've discovered that `valetudo_something.local` is not a valid bonjour hostname as the `_` is illegal.\r\nWhile it does seem to work in most setups, it might cause problems in some, which is why starting with this release, Valetudo will use an RFC-compliant hostname: `valetudo-something.local`.\r\n\r\nPlease **update your bookmarks** if you were using any.\r\n\r\n\r\n## MQTT\r\n\r\n### Home Assistant 2021.11 MQTT Changes\r\n\r\nValetudo 2021.11.1 makes use of new features introduced in Home Assistant 2021.11 (namely `configuration_url` and `entity_category`).\r\nThis means that **Home Assistant >= 2021.11 is now required** if you want to use it with Valetudo.\r\n\r\nYou might also have to delete your Valetudo device in HA and let it get rediscovered so that the changes are applied properly.\r\n\r\nIt now looks like this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760339-aa5b2314-692d-4167-9689-cec21f718924.png)\r\n\r\n\r\n### Possible MQTT OOM fixes\r\n\r\nWe have received unconfirmed, unsubstantiated and possibly falsified reports of Valetudo going OOM related to Wi-Fi connectivity issues and the MQTT interface.\r\n\r\nTo combat this, Valetudo now drops any outgoing MQTT message if there are more than 1 MiB of outgoing messages buffered. This may or may not ever happen.\r\nIf you see a warning in your log related to this, please report back. I have not been able to reproduce this.\r\n\r\n### Homie Consumables\r\n\r\nHome consumable durations are now reported as an int. This should fix issues with OpenHab.\r\n\r\n## Bugfixes\r\n\r\n### Dreame paths\r\n\r\nDreame paths now parse to multiple path map entities instead of a single one, which fixes the visual with lines going straight across the map connecting the previous path to the next one.\r\nConsumers of the Valetudo map data might have to be updated to properly display multiple path entities.\r\n\r\n### 1C-related fixes\r\n\r\nI've bought a Dreame 1C to do some QA, which led to a few fixes.\r\nI'm now quite happy with the current state of its implementation in Valetudo.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** CurrentStatisticsCapability ([8e4e183](https://github.com/Hypfer/Valetudo/commit/8e4e1839c217cc081f3172f227e935c2dc616bf1))\r\n* **core:** CurrentStatisticsCapability & TotalStatisticsCapability properties ([4fc9df2](https://github.com/Hypfer/Valetudo/commit/4fc9df271af4dbb9a9c1841d5f23a292d8cd0af3))\r\n* **core:** Introduce ConsumableMonitoringCapability properties and remove mqtt consumables hack ([a998ee1](https://github.com/Hypfer/Valetudo/commit/a998ee1eeeba2fd808c797bed719933d85922252))\r\n* **core:** TotalStatisticsCapability ([55b6696](https://github.com/Hypfer/Valetudo/commit/55b6696ecfb7f6d86b34da2e9e37b07287f8ef68))\r\n* **MockRobot:** Add MockCurrentStatisticsCapability + fix MockConsumableMonitoringCapability ([bda0b1a](https://github.com/Hypfer/Valetudo/commit/bda0b1adc54c8b651a3d23db8a4dc4638b460e48))\r\n* **mqtt:** Homie consumables should always be int ([c39ad93](https://github.com/Hypfer/Valetudo/commit/c39ad9380fc1d4cf752a3d95f0f57512e608c64f))\r\n* **mqtt:** Limit outgoing message buffer size to prevent OOM situations ([1a74f91](https://github.com/Hypfer/Valetudo/commit/1a74f9114de877f01b728e281b843e8459100b0f))\r\n* **mqtt:** Publish current statistics to mqtt ([102a078](https://github.com/Hypfer/Valetudo/commit/102a07890fe0a13efbda8b568b177fa4940478be))\r\n* **ui:** Add Valetudo loading splash ([a7ca33c](https://github.com/Hypfer/Valetudo/commit/a7ca33c845fa1e32d1a217115e48cd534c38b7bb))\r\n* **ui:** Collapse preset selection controls ([4f8aaec](https://github.com/Hypfer/Valetudo/commit/4f8aaec2f43b9e1a3bb21df88083b80509652fde))\r\n* **ui:** Display current statistics ([0fbc182](https://github.com/Hypfer/Valetudo/commit/0fbc182b0998cf1b3804b52ef24ee5d2d14c1b21))\r\n* **ui:** Slightly decrease required zoom level for segment label text ([08209a3](https://github.com/Hypfer/Valetudo/commit/08209a3164156db6e5e3ba340342bfbbf75bd7e3))\r\n* **vendor.dreame:** Total and current statistics for the 1C ([c1a51e9](https://github.com/Hypfer/Valetudo/commit/c1a51e916a9d123fcd6f9621eff02b645f79d702))\r\n* Provision Wizard thingy ([a6f6ded](https://github.com/Hypfer/Valetudo/commit/a6f6dedc851d6852e7b25ba1dc5222f3130ef210))\r\n* **ui:** Reorder state display ([828e54d](https://github.com/Hypfer/Valetudo/commit/828e54da624d2e00f500499e3497867fdb2ad6eb))\r\n* **ui:** Replace bottom sheet with simpler mobile controls ([17ff7ec](https://github.com/Hypfer/Valetudo/commit/17ff7ecb1105d9904f382a15b92dd5a6b988dd1f))\r\n* **vendor.dreame:** DreameCurrentStatisticsCapability ([656a19e](https://github.com/Hypfer/Valetudo/commit/656a19ee39f1411bb962e61077486d9336dd79b5))\r\n* **vendor.dreame:** DreameTotalStatisticsCapability ([4bb9342](https://github.com/Hypfer/Valetudo/commit/4bb934208ff52ad7fc1f42b82e5046362353ab6a))\r\n* **vendor.roborock:** RoborockCurrentStatisticsCapability ([93aa77b](https://github.com/Hypfer/Valetudo/commit/93aa77b09b7924baf5fce594d6455f4a5f51837e))\r\n* **vendor.roborock:** RoborockKeyLockCapability ([#1222](https://github.com/Hypfer/Valetudo/issues/1222)) ([02e155c](https://github.com/Hypfer/Valetudo/commit/02e155cec954cc75e41c5fcbf8ebe37acffb4c37))\r\n* **vendor.roborock:** RoborockTotalStatisticsCapability ([e0cbbff](https://github.com/Hypfer/Valetudo/commit/e0cbbff7470426119dd1eff6bde064a9387209b5))\r\n* **vendor.viomi:** ViomiCurrentStatisticsCapability ([9dd1091](https://github.com/Hypfer/Valetudo/commit/9dd1091cbc7a63ac7c0f61b40bc73abd026572bc))\r\n* **webserver:** Add 404 page ([8f5095c](https://github.com/Hypfer/Valetudo/commit/8f5095cac124c0ee0a6b8cdece07223c3374c51f))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Attempt to mitigate problems related to connectivity issues ([cf0f2d6](https://github.com/Hypfer/Valetudo/commit/cf0f2d691017ac69635d17f04062c260ebf62091))\r\n* **mqtt:** homie.durationsAsInteger should not be a breaking change ([bbd918a](https://github.com/Hypfer/Valetudo/commit/bbd918ac35530c0a7a8e8b684ebbe05967506bfc))\r\n* **ui:** Align preset selection labels with icons ([c6803f6](https://github.com/Hypfer/Valetudo/commit/c6803f6e2d5a60172d945bd62ab47badd679d234))\r\n* **ui:** Attachment buttons should be disabled ([922572a](https://github.com/Hypfer/Valetudo/commit/922572a779e0e1402ca53bb3e9b8a1c82605ea70))\r\n* **ui:** Fix CurrentStatistics trying to map something that isn't an array ([4d6f3d8](https://github.com/Hypfer/Valetudo/commit/4d6f3d869202288fb48bc50ee38d124c611fac78))\r\n* **ui:** Fix mobile control scrolling ([6264400](https://github.com/Hypfer/Valetudo/commit/6264400a473b36aff9f5409a5e157de536389e6d))\r\n* **ui:** Only check for provisioning once ([6bd0480](https://github.com/Hypfer/Valetudo/commit/6bd0480d8d40600aa5f438d060a21b2ba775925a))\r\n* **ui:** Only regular mouse clicks should interact with the map ([d452d88](https://github.com/Hypfer/Valetudo/commit/d452d88206afafbf4017138fa8b52edd38f1f70d))\r\n* **ui:** Preset selection labels should not be user selectable ([965a061](https://github.com/Hypfer/Valetudo/commit/965a0610c2dd73e028f944ed3a49a5e3c507d7e6))\r\n* **ui:** Swap presetSelection open/close icons ([380109b](https://github.com/Hypfer/Valetudo/commit/380109baa7bc6abfb06169eaeac036a7235af005))\r\n* **ui:** The whole controls body should not be user-selectable ([861f15f](https://github.com/Hypfer/Valetudo/commit/861f15f6da3633c266f0fbca8471193642b8ae57))\r\n* **vendor.dreame:** 1C shall ignore persistent map property updates ([5744346](https://github.com/Hypfer/Valetudo/commit/5744346272bf443ca734da77c5af938a559d314b))\r\n* **vendor.dreame:** Assume that we're in the docked state if we're charging on the 1C ([c73e062](https://github.com/Hypfer/Valetudo/commit/c73e06207c098deae3e596de135c5e2cbf50f4da))\r\n* **vendor.dreame:** Fine-tune 1C manual control ([72614e2](https://github.com/Hypfer/Valetudo/commit/72614e29977297078cf37425be361ad5310aad07))\r\n* **vendor.dreame:** Fine-tune manual control ([cc267c7](https://github.com/Hypfer/Valetudo/commit/cc267c75fe02178343cbddd43099ff59cfe8b16f))\r\n* **vendor.dreame:** Fix Dreame1CManualControlCapability ([9c85ca5](https://github.com/Hypfer/Valetudo/commit/9c85ca5f8c09dc5e1371f4b805767a6bec54175c))\r\n* **vendor.dreame:** Properly parse path data to multiple paths ([e083af2](https://github.com/Hypfer/Valetudo/commit/e083af2759f37706cda1e45a0b083b0782112f3b))\r\n* **vendor.dreame:** Remove capabilities for models that don't support them ([0d6d6ad](https://github.com/Hypfer/Valetudo/commit/0d6d6ad3ad44bdadb9ceea830652e8e742487776))\r\n* **vendor.dreame:** The 1C does not support multiple iterations for segment cleanups ([2d35bd9](https://github.com/Hypfer/Valetudo/commit/2d35bd9a0f00f52f9e0a67dae5f31d50e7a87cb3))\r\n* **vendor.viomi:** Fix ViomiPersistentMapControlCapability ([#1218](https://github.com/Hypfer/Valetudo/issues/1218)) ([80d7bb2](https://github.com/Hypfer/Valetudo/commit/80d7bb2bd91377d1c06a0c6afa4a262d0b7511e7))\r\n* Fix LinuxWifiConfigurationCapability not_connected state reporting ([25271f2](https://github.com/Hypfer/Valetudo/commit/25271f24c95976bae9b201ff1a6d2625c3e643a1))\r\n* **vendor.roborock:** RoborockSpeakerVolumeControlCapability.getVolume() should return a number ([32898d1](https://github.com/Hypfer/Valetudo/commit/32898d1cd27b3498f00e6dd4d67c2de09d0ec1ed))\r\n* **vendor.viomi:** Fix volume control ([0269182](https://github.com/Hypfer/Valetudo/commit/0269182f5e94d055d908b9c16e1524ef5a9f949d))\r\n* **webserver:** try/catch for SpeakerVolumeControlCapabilityRouter ([5cb7c5a](https://github.com/Hypfer/Valetudo/commit/5cb7c5ac3c09c9138ac11316aff3c7dcfa22fde1))\r\n* Nested assign configuration defaults + don't persist if there are no changes to persist ([b12c452](https://github.com/Hypfer/Valetudo/commit/b12c452b4d693326d0ebec81bf6b1145c8ca9de5))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376" + } + }, + { + "version": "2021.11.0", + "releaseTimestamp": "2021-10-24T11:41:55.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.11.0

\r\n
\r\n\r\nLikely the most important release of the year.\r\n\r\n## Recap 0.6.1 to 2021.11.0\r\nApparently, Valetudo 0.6.1 was released only a bit more than a year ago, but tbh it feels like an eternity.\r\nSo much has changed since then. The iteration speed of the project has been insane in the last months.\r\nAs we've now finished most if not all of the huge tasks, I expect things to slow down a little.\r\n\r\nHere's a quick recap of what happened since 0.6.1:\r\n\r\n- Complete core rewrite to easily support multiple vendors and different robots\r\n- A proper REST-API documented with Swagger UI\r\n- Complete MQTT rewrite to support Home Assistant as well as Homie\r\n- Easy map display in Home Assistant via MQTT and the custom lovelace valetudo map card\r\n- Complete UI rewrite based on a proper UI framework\r\n- Support for all relevant features of the robots\r\n- Support for autodiscovery of Valetudo-enabled robots via mDNS and SSDP\r\n- Support for Dreame-made robots\r\n- An [android companion app](https://valetudo.cloud/pages/companion_apps/valetudo_companion.html) that makes use of said autodiscovery feature\r\n- [Valeronoi](https://valetudo.cloud/pages/companion_apps/valeronoi.html): A companion app that generates Wi-Fi signal strength maps using Valetudo\r\n- An updater functionality\r\n- [Proper docs](https://valetudo.cloud/)\r\n- General polishing. A lot of it\r\n\r\n\r\n## Default new UI\r\n\r\nStarting with this release, the new react-based UI introduced by @jomik with large contributions by @ccoors is now the default.\r\n\r\nThe existing map renderer was ported to react with a few quality of life improvements:\r\n\r\n- You can now specify an iteration count when cleaning segments or zones\r\n- Layers are now sorted, meaning that walls will always be on top. This solves some visual issues of vSlam-based devices\r\n- Adding a new zone/virtual wall/etc. will now spawn it in the middle of your viewport \r\n- Map segment labels now attempt to actually be inside the segment they're for. This fixes issues with cornered hallways. No more stray triangles\r\n- Editing the map will now refresh your current view instead of navigating back\r\n- Rendering has been partly moved to a webworker for improved performance\r\n\r\nSpeaking of navigating back: Given that the new UI is based on a frontend framework including proper routing,\r\nwe now have a working back button. Amazing!\r\n\r\nThe only thing not yet available in the new UI is management of Zone and GoTo presets. This will be added later.\r\nFor now, please navigate to the old UI via the menu and use that.\r\n\r\n\r\n### Screenshots\r\n\r\n#### Phone/Mobile\r\n![image](https://user-images.githubusercontent.com/974410/138561830-e0a3edf7-1974-49cf-90a8-31e677b482d2.png) ![image](https://user-images.githubusercontent.com/974410/138561931-41b68344-f260-4343-9c79-ef85e56d9786.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138561874-f5e5fee9-81dd-43fb-9de0-75263169a0e6.png) ![image](https://user-images.githubusercontent.com/974410/138561884-9633600b-3362-454b-b95d-90f8e5951971.png)\r\n\r\n\r\n#### Tablet/Desktop\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138562037-05bc5140-d7af-488b-8734-72e66b820192.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138561911-77aa8d10-3918-4eb7-96ff-8a6d0440dfce.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138562111-3cbfe03c-7a19-4e57-9bfb-6b872239f432.png)\r\n\r\n\r\n## Updater\r\n\r\nStarting with this release, Valetudo will be capable of updating itself with the press of a button.\r\n\r\nThis has been a long-requested feature and considering how mature this whole project has become, I decided that\r\nit was finally time to actually implement that.\r\nAs it is implemented now, it uses the GitHub API by default, meaning that I am not able to track you.\r\n\r\nThere's also no automatic update check, because periodical pings to some cloud service are obviously problematic.
\r\nYou will decide when to press the \"Check for Updates\" button and also when to update.\r\n\r\n## More stickers\r\n\r\nI've decided to get a few more stickers printed because merch\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138592502-4c6d150e-ecde-46ea-9ce4-7da8fdb77431.png)\r\n\r\n## Misc\r\n\r\nI'm currently looking for a job that isn't a corporate hellhole with nice people doing interesting stuff.\r\nIf you're a likeminded hacker looking for a new colleague or know someone who does feel free to ping me\r\n\r\nThanks :)\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Add Valetudo logo to bottom sheet ([76eeaff](https://github.com/Hypfer/Valetudo/commit/76eeaffd4aa273e351d9306d4660df196380b275))\r\n* **ui:** Bring back the old map renderer ([7aa6822](https://github.com/Hypfer/Valetudo/commit/7aa6822e20ef026a73bcfebcf76c9bbd49ce2a94))\r\n* **ui:** Change map colors according to theme in use ([b17745e](https://github.com/Hypfer/Valetudo/commit/b17745e2ca70a9b24982f70cfc2272130cd1e9a4))\r\n* **ui:** Fan speed icon and battery level bar improvements ([d0a0671](https://github.com/Hypfer/Valetudo/commit/d0a06712315f0dc7b93fc35ee9f9270a9204df7e))\r\n* **ui:** Improve controls ([b678cda](https://github.com/Hypfer/Valetudo/commit/b678cdac0f2a15e1a3191f2125fbbaabbc7af833))\r\n* **ui:** Map Editing ([35feb65](https://github.com/Hypfer/Valetudo/commit/35feb654e76599d0c267ed118453f3c25e4b8fbd))\r\n* **ui:** Move locate to the map view ([32de2b8](https://github.com/Hypfer/Valetudo/commit/32de2b83daf1e03fa16b1115713a9290abc05029))\r\n* **ui:** Place new client structures in the middle of the viewport ([d9d2a64](https://github.com/Hypfer/Valetudo/commit/d9d2a6436bd6ea24dd431b24776c93587114cfba))\r\n* **ui:** Remove map transparency ([ace000b](https://github.com/Hypfer/Valetudo/commit/ace000b922a426076db49aaa25e1cbf4207b0ad8))\r\n* **ui:** Remove obsolete segment controls ([9912cf5](https://github.com/Hypfer/Valetudo/commit/9912cf58f60a6ca88517786bb9fc6afccf9a5cf0))\r\n* **updater:** Introduce ValetudoUpdaterNoUpdateRequiredState ([354028e](https://github.com/Hypfer/Valetudo/commit/354028e6f4f23e8c61a9f2e302edcaecf7807fe6))\r\n* Updater ([5db2c55](https://github.com/Hypfer/Valetudo/commit/5db2c554dc9905352c310f4be7d6130a26f7730c))\r\n* **ui:** Remove Accordion from interface settings ([c4c31bb](https://github.com/Hypfer/Valetudo/commit/c4c31bb5a68757a6ec687c3dde436f26374a2fdc))\r\n* **ui:** Set the new UI as the default ([c0f90fb](https://github.com/Hypfer/Valetudo/commit/c0f90fb90f44d7020db016cfe9129d80f8df7d56))\r\n* **ui:** Use a WebWorker for rendering the map layers when possible ([3eafded](https://github.com/Hypfer/Valetudo/commit/3eafded6c62a420795f6f910ca5b933f29a7e5f6))\r\n* **ui:** Use real swagger icon in sidebar ([#1160](https://github.com/Hypfer/Valetudo/issues/1160)) ([f4c0093](https://github.com/Hypfer/Valetudo/commit/f4c0093527be1ae3ce6fa298bd878b3cc5b1283c))\r\n* **ValetudoEvents:** Add Mop Attachment Reminder event ([ac268d7](https://github.com/Hypfer/Valetudo/commit/ac268d765f93c33aba14ad7ffd8602d00a02985e))\r\n* Add nonce to every instance of a Valetudo map ([f0489f1](https://github.com/Hypfer/Valetudo/commit/f0489f15260f8eb368bc6b759029a022781bebf9))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* Fix MopAttachmentReminderValetudoEvent not being a DismissibleValetudoEvent ([302f6ce](https://github.com/Hypfer/Valetudo/commit/302f6cefc3f155d45589ea1cf50ed39fc983b5d3))\r\n* **mqtt:** Fix consumable state attribute data being published multiple times ([894bba9](https://github.com/Hypfer/Valetudo/commit/894bba9c9b99a5b67f584dbaa9e1571ffa18812c))\r\n* **mqtt:** Fix zone cleanup ([#1130](https://github.com/Hypfer/Valetudo/issues/1130)) ([bb951b2](https://github.com/Hypfer/Valetudo/commit/bb951b2fcddb6435bfe6b838044cc2af7b0c235f))\r\n* **mqtt:** Hopefully avoid a deadlock ([c3313ea](https://github.com/Hypfer/Valetudo/commit/c3313eac738cf8d5dc1a05f3c60308e4b002dd3a))\r\n* **ui:** Allow more states for zone/segment cleanup and goto ([c738938](https://github.com/Hypfer/Valetudo/commit/c738938cc0d8140ce91011db8420df7a6768c893))\r\n* **ui:** Better placement of segment labels ([ba788a0](https://github.com/Hypfer/Valetudo/commit/ba788a0da1042106cac698e5de9f20d6e7bb89f5))\r\n* **ui:** Combinations of scrolling and touch events also should not cause any jank ([e36c40f](https://github.com/Hypfer/Valetudo/commit/e36c40f2a66a67baebd75da13ed8bb84cd26d371))\r\n* **ui:** Fix controls jumping around when there is a status flag ([c641fb1](https://github.com/Hypfer/Valetudo/commit/c641fb10e3bc2a7e56a9e6a388be1d479fb6c91b))\r\n* **ui:** Fix draw order for ControlsBottomSheet ([c46ef10](https://github.com/Hypfer/Valetudo/commit/c46ef10981298570bc14a7e9094698b70dd30e94))\r\n* **ui:** Fix SSE not reconnecting after having closed the connection once ([6feaaf8](https://github.com/Hypfer/Valetudo/commit/6feaaf807065f3e5d585c9f723e8b48f9aa32621))\r\n* **ui:** Further improve segment label placement using the median ([6545cc7](https://github.com/Hypfer/Valetudo/commit/6545cc7fb4077247b08675f8ea10895062996401))\r\n* **ui:** Ignore map updates if the tab is invisible ([370753d](https://github.com/Hypfer/Valetudo/commit/370753dcd5bb2dd1803d8dac67d3b96759dd94c3))\r\n* **ui:** MQTT port is an integer ([#1159](https://github.com/Hypfer/Valetudo/issues/1159)) ([5b91c96](https://github.com/Hypfer/Valetudo/commit/5b91c96eb8e2928be48b4ef63abbb7c043b34aa9))\r\n* **ui:** Postpone map data updates during pan/zoom to prevent jank ([92a9147](https://github.com/Hypfer/Valetudo/commit/92a9147191981b15d48e4817f7200875470a13fe))\r\n* **ui:** Postpone map data updates during scroll to prevent jank ([adcd117](https://github.com/Hypfer/Valetudo/commit/adcd1174a50b4bce4805da5a36bcf80646eb9979))\r\n* **ui:** Prevent issues with zooming on mobile ([a5057fd](https://github.com/Hypfer/Valetudo/commit/a5057fd7f4dd58b38628f5bbdd4ade951ca6b6fc))\r\n* **ui:** Use the correct canvas size for the map layer renderer ([b55ffa6](https://github.com/Hypfer/Valetudo/commit/b55ffa6cc56d7c7d6bb0c8459ccd1d35252c3b63))\r\n* **ui:** Zone dimensions should be based on the pixelSize ([b317c85](https://github.com/Hypfer/Valetudo/commit/b317c856dbdfe95ab45ea639223d23fca093c464))\r\n* **updater:** Fix fallback download location for roborock ([d515f04](https://github.com/Hypfer/Valetudo/commit/d515f04e5f6695b71567f6818ba2734553c75d03))\r\n* **vendor.dreame:** Fix virtual restriction coordinates being not sorted properly ([17cc303](https://github.com/Hypfer/Valetudo/commit/17cc303cf4726cf4bcbb9597c268273896b52c78))\r\n* **vendor.dreame:** Ignore error 68 ([dd44320](https://github.com/Hypfer/Valetudo/commit/dd44320a390c42f6e36a301931e5006e103a4684))\r\n* **webserver:** Allow unsetting names of segments ([f992e5a](https://github.com/Hypfer/Valetudo/commit/f992e5adce4c4fd997ff4a6c868f95d32a5e214b))\r\n* Use shorter model names ([d268013](https://github.com/Hypfer/Valetudo/commit/d268013b9c93b4dc610cb8374a3316d9e2a842a9))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111" + } + }, + { + "version": "2021.10.0", + "releaseTimestamp": "2021-10-01T21:25:10.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.10.0

\r\n
\r\n\r\nAnother release with a lot of UI changes by @ccoors. Also, there's an Android companion App now.\r\n\r\n## Android Companion App\r\n\r\nThanks to the help of @TheLastProject who had built the first prototype in less than 18h after initially mentioning the idea on the telegram group, there's now an Android Companion App for Valetudo.\r\n\r\nDon't worry, it is completely optional. All it does and aims to do is to find Valetudo instances on your network via Bonjour and help you with the provisioning (configuring Wi-Fi) process of new robots with Valetudo installed.\r\nThis can be helpful for example if you were to give your non-linux-skilled parents a rooted robot for Christmas or whatever.\r\n\r\nIt's available on F-Droid and Google Play and of course open source.\r\n\r\nFor more information, please check out [the docs](https://valetudo.cloud/pages/companion_apps/valetudo_companion.html).\r\n\r\n[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-02.png)[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-03.png)[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png)\r\n\r\n\r\n## UI Changes\r\n\r\n@ccoors provided very nice previews displaying their changes in each PR, which is why I will just copy-paste them here for your convenience.\r\nAlso, I'm lazy\r\n\r\n\"wifi\r\n\r\n\"voice\"manual\r\n\r\n\"more\r\n\r\n\r\n## Logo Cleanup\r\n\r\nAs you might've noticed, the logo slightly changed.\r\nThis avoids the bug in some people, which made them read it as *aletudo* when looking at it.\r\n\r\n## Valetudog\r\n\r\nThe thing from the telegram group finally got a name: Valetudog\r\nIt's now some kind of mascot I guess.\r\n\r\n\"valetudog\"\r\n\r\nI also bought a lot of stickers of it\r\n\r\n![image](https://user-images.githubusercontent.com/974410/135687512-e49f8bae-97ab-4d5c-bb8b-ba989eea1518.png)\r\n\r\nUnfortunately, I have no idea what to do with them.\r\nThey did turn out quite nice though.\r\n\r\n## Zoned Cleanup MQTT changes\r\n\r\nStarting with this release, it's no longer possible to clean multiple zone presets at once via MQTT.\r\nThat should've never been possible in the first place since it's conceptually wrong as you can only call a single preset at a time. Sorry about that.\r\n\r\nNote that this is a **breaking change** and will require updating of e.g. your Home Assistant automations.\r\nInstead of an array, you now have to send just the preset ID as a string.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Consumables bottom view sensors ([#1104](https://github.com/Hypfer/Valetudo/issues/1104)) ([2f83d8e](https://github.com/Hypfer/Valetudo/commit/2f83d8ea02aaefde8f132909071ca9bf7367de74))\r\n* **ui:** DoNotDisturb configuration & Masonry on large screens ([#1112](https://github.com/Hypfer/Valetudo/issues/1112)) ([935f903](https://github.com/Hypfer/Valetudo/commit/935f903981ad5f98e9224cae143396b353a195db))\r\n* **ui:** HTTP Basic Auth and NTP client config ([#1118](https://github.com/Hypfer/Valetudo/issues/1118)) ([2371878](https://github.com/Hypfer/Valetudo/commit/2371878cd48e19b57fce61b4200d76a1cc30257b))\r\n* **ui:** Manage voice packs ([#1108](https://github.com/Hypfer/Valetudo/issues/1108)) ([0d02c27](https://github.com/Hypfer/Valetudo/commit/0d02c278edaf1ea60810990455b33175b957acc7))\r\n* **ui:** Manual control ([#1114](https://github.com/Hypfer/Valetudo/issues/1114)) ([7e9ef04](https://github.com/Hypfer/Valetudo/commit/7e9ef04b2fa5d8fb4d5f7e8d3fa88366592873ea))\r\n* **ui:** Robot settings ([#1097](https://github.com/Hypfer/Valetudo/issues/1097)) ([4b43b37](https://github.com/Hypfer/Valetudo/commit/4b43b370663ca44f03d82ba828026169075d670c))\r\n* **ui:** Wifi configuration ([#1116](https://github.com/Hypfer/Valetudo/issues/1116)) ([3e71184](https://github.com/Hypfer/Valetudo/commit/3e7118414b6b190750e3f606c93e1b052d78b898))\r\n* **vendor.dreame:** Add Dreame D9 Pro ([cc50a8c](https://github.com/Hypfer/Valetudo/commit/cc50a8c6e4cab7a04c68ca61d21e59e15a3a59cb))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix MQTT Zone cleanup ([fdabcc5](https://github.com/Hypfer/Valetudo/commit/fdabcc52be3553f01648997ec714133e27a6e7cc))\r\n* **ui:** Allow start and home basic commands on error state ([5fd0354](https://github.com/Hypfer/Valetudo/commit/5fd0354eabd91aa50cc42120bdabdf6947aaf604))\r\n* **ui:** Blue line between buttons in PendingMapChangeEventControl ([196a29e](https://github.com/Hypfer/Valetudo/commit/196a29e1549ffd46fddcd78c7c8bee9b2d1e8c21))\r\n* **ui:** Fix mobile Icons in new frontend ([#1113](https://github.com/Hypfer/Valetudo/issues/1113)) ([313caa1](https://github.com/Hypfer/Valetudo/commit/313caa10ea0a246ea05dd4ba3fca83e374e75cdc))\r\n* **ui:** Import ToggleButton from core ([da0cce5](https://github.com/Hypfer/Valetudo/commit/da0cce588eee9c6065bb2ad4f2890b19cd8c5e59))\r\n* **ui:** RatioBar background color ([c00d174](https://github.com/Hypfer/Valetudo/commit/c00d1749c26bec217a60a529166c5f8bf6de3dba))\r\n* **ui:** Remove persistent data hint ([6777f3a](https://github.com/Hypfer/Valetudo/commit/6777f3aa7bbf4ef5afea5a3ba8fdecd2aa8f150e))\r\n* **ui:** repair light mode ([#1103](https://github.com/Hypfer/Valetudo/issues/1103)) ([842aea1](https://github.com/Hypfer/Valetudo/commit/842aea125b97a33adbf28c3b0c9d1cf84c069943))\r\n* **ui:** Root grid height ([957463a](https://github.com/Hypfer/Valetudo/commit/957463a9de34e4e7c3fafe5d94fdd6360b4a2f88))\r\n* **ui:** Root grid height ([1d9a244](https://github.com/Hypfer/Valetudo/commit/1d9a244412b235ed2da71d594cb77d00fd9eae45))\r\n* **ui:** Stop events badge flashing when it reloads ([#1115](https://github.com/Hypfer/Valetudo/issues/1115)) ([007926b](https://github.com/Hypfer/Valetudo/commit/007926b90881664e9b0c718e7c3ef21ad306e233))\r\n* **webserver:** Fix reflected xss vulnerability ([36a3bae](https://github.com/Hypfer/Valetudo/commit/36a3bae630dfc84c6a2e610ef35e93a002470857))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403" + } + }, + { + "version": "2021.09.1", + "releaseTimestamp": "2021-09-19T12:23:58.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.09.1

\r\n
\r\n\r\nThis release is packed with UI improvements thanks to @ccoors\r\n\r\n## Event UI\r\n\r\nThe new UI now subscribes to the ValetudoEvents endpoint and allows for interaction with them.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927122-054ed31b-7a47-447f-9193-6e92ca64757b.png)\r\n\r\nThis is helpful as they might contain errors that you've missed.\r\nAlso, your robot might require confirmation from you to store a new map so make sure to keep an eye on that.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927125-d069022e-8a18-4bd3-b879-734a4f9aba96.png)\r\n\r\n\r\n## Timer UI\r\n\r\nYou can now use the new UI to set up ValetudoTimers.\r\n\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927153-e109c4a5-2bff-45e7-af07-2ae7a4eb9ace.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927151-76b2daa1-9e26-4b6d-a2e1-ba20c97e9829.png)\r\n\r\nNote that timers are always stored and evaluated as UTC. The local time display is simply a convenience feature.\r\n\r\n## MQTT config UI\r\n\r\nMQTT configuration can now also be done via the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927206-8a4188a8-d178-46fb-9c2d-32907322f5f9.png)\r\n\r\nIt features a nice topic preview to make it easier for newcomers to interact with Valetudo via MQTT.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927215-e359d45a-c76e-47bb-a178-d1118cca25bc.png)\r\n\r\nAlso, the API will no longer return any MQTT credentials but instead replace them with `` for security reasons.\r\n\r\n## Logviewer UI\r\n\r\nA basic log viewer has been added to the new UI. While still WIP, it already allows for live updates as well as filtering, which is a neat improvement.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927245-d4f98b09-0cc4-448d-9752-f939987f9e3c.png)\r\n\r\n\r\n## Auto-empty Dock related features\r\n\r\nIf you own a Dreame Z10, you're now able to enable/disable the automatic dust collection via the Swagger UI.\r\nFurthermore, you can also trigger it manually via either the UI, the REST API or MQTT, meaning that you can now fully customize the collection interval by using e.g. Home Assistant automations.\r\n\r\n## Misc\r\n\r\n### Obstacle Avoidance\r\n\r\nYou can now disable the Obstacle Avoidance Feature of your Dreame L10/Z10 via the Swagger UI if you experience issues such as the robot refusing to drive onto a carpet.\r\n\r\n### Consumables UI\r\n\r\nThe new UI now also features a consumables section with a neat hover feature hopefully helping newcomers better understand the consumables.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927281-cd81083a-be3f-415f-bf78-81818a0c26af.png)\r\n\r\n\r\n### Runtime Information UI\r\n\r\nThe new UI about section has been extended to display data returned by the runtime information endpoint.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927292-91c520e9-210e-40c4-89a1-3c0fce037ad9.png)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** AutoEmptyDockAutoEmptyControlCapability ([eeeb46c](https://github.com/Hypfer/Valetudo/commit/eeeb46c8a2152049392b7df06c952dc44b101d98))\r\n* **core:** AutoEmptyDockManualTriggerCapability ([5678d4f](https://github.com/Hypfer/Valetudo/commit/5678d4fd8e3dab9364182fa8f40fa09465bc77eb))\r\n* **core:** ObstacleAvoidanceControlCapability ([e5fab92](https://github.com/Hypfer/Valetudo/commit/e5fab92172dd6c024201218bbe4889a770c3f7c2))\r\n* **core:** Robot properties ([b1713df](https://github.com/Hypfer/Valetudo/commit/b1713dff26a2bcfd707bd88fa0dcf3acbde4faa1))\r\n* **MockRobot:** MockAutoEmptyDockManualTriggerCapability ([31cb972](https://github.com/Hypfer/Valetudo/commit/31cb972d89cba474c3c8732e969015a5bb5d9851))\r\n* **ui:** Add button to trigger dock auto empty manually ([#1087](https://github.com/Hypfer/Valetudo/issues/1087)) ([fa2def7](https://github.com/Hypfer/Valetudo/commit/fa2def7c65a2641ec6321fcdfb4c3975e607867d))\r\n* **ui:** Consumables in new UI ([#1093](https://github.com/Hypfer/Valetudo/issues/1093)) ([144d6ed](https://github.com/Hypfer/Valetudo/commit/144d6edacdf264b5a835ee184c1639f982231d25))\r\n* **ui:** Implement MQTT config ui ([#1080](https://github.com/Hypfer/Valetudo/issues/1080)) ([2dd83e3](https://github.com/Hypfer/Valetudo/commit/2dd83e3a8c8e8c1629f873b9d20a52f7337fbcd9))\r\n* **ui:** Implement timer ui ([#1077](https://github.com/Hypfer/Valetudo/issues/1077)) ([abd6345](https://github.com/Hypfer/Valetudo/commit/abd63454588e510d23d55c4f08a1caad1cc7c649))\r\n* **ui:** Log with SSE and display log in new UI ([#1092](https://github.com/Hypfer/Valetudo/issues/1092)) ([1721df7](https://github.com/Hypfer/Valetudo/commit/1721df7dd6969fba8acd63d726a8ca14d1977afd))\r\n* **ui:** Navigation and Events in UI ([#1090](https://github.com/Hypfer/Valetudo/issues/1090)) ([27fd2ba](https://github.com/Hypfer/Valetudo/commit/27fd2ba97e98f534c20ca6e22b0d46510f355706))\r\n* **ui:** Show MQTT config defaults ([711c312](https://github.com/Hypfer/Valetudo/commit/711c312cc41fff57867e5b97d4e867b3ef41b4c3))\r\n* **ui:** Show MQTT topic preview ([#1082](https://github.com/Hypfer/Valetudo/issues/1082)) ([865905e](https://github.com/Hypfer/Valetudo/commit/865905ea58bfff9187c7463fce3a312b738a1e90))\r\n* **ui:** Show runtime info on about page ([#1089](https://github.com/Hypfer/Valetudo/issues/1089)) ([ece2dc9](https://github.com/Hypfer/Valetudo/commit/ece2dc9d6d5baafa4d0aa291565087bf2e1f6148))\r\n* **vendor.dreame:** DreameAutoEmptyDockAutoEmptyControlCapability ([a1fa6d8](https://github.com/Hypfer/Valetudo/commit/a1fa6d8a14bad572aca4ce6af714cacb9d4e1760))\r\n* **vendor.dreame:** DreameAutoEmptyDockManualTriggerCapability ([b7aed1a](https://github.com/Hypfer/Valetudo/commit/b7aed1afa217ebd90f411c91844a28f05946460d))\r\n* **vendor.dreame:** DreameDoNotDisturbCapability ([60972ca](https://github.com/Hypfer/Valetudo/commit/60972ca6dd8d8200d8c25a2e4e084c04f97ef8ce))\r\n* **vendor.dreame:** DreameObstacleAvoidanceControlCapability ([ca9a499](https://github.com/Hypfer/Valetudo/commit/ca9a49939d9499dddfc9f77aede70c655758031a))\r\n* **webserver:** Provide mqtt config properties ([7e6962b](https://github.com/Hypfer/Valetudo/commit/7e6962bd8094120168c960d550027efbf3a53d73))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Accepting/rejecting a pending map change should always invalidate a pending event ([94c8da2](https://github.com/Hypfer/Valetudo/commit/94c8da29c6f3f3adc3e9f02b546dd258e4bd30bc))\r\n* **timers:** Prevent timer drift ([#1078](https://github.com/Hypfer/Valetudo/issues/1078)) ([105d02a](https://github.com/Hypfer/Valetudo/commit/105d02a67d502ba727e90251f2b9325837833ebd))\r\n* **ui:** Improve word breaks in MQTT topic preview ([#1088](https://github.com/Hypfer/Valetudo/issues/1088)) ([8736f7f](https://github.com/Hypfer/Valetudo/commit/8736f7fc9ee1d76dcb8a5c21975f85040fbfd723))\r\n* **ui:** Make timers use correct time zone offset ([#1079](https://github.com/Hypfer/Valetudo/issues/1079)) ([f790db3](https://github.com/Hypfer/Valetudo/commit/f790db3ec1eadcaa91726a75ac994b5d527058f4))\r\n* **ui:** Remove staleTime: Infinity for queries that should actually refresh automatically ([b53d428](https://github.com/Hypfer/Valetudo/commit/b53d428846f3013768827296b193ed68f4ca0255))\r\n* **ui:** Show old ui timer page even when there's no DoNotDisturbCapability ([ac19d5d](https://github.com/Hypfer/Valetudo/commit/ac19d5d2c1751c12d614ebf2c8cb701cdc7a0473))\r\n* **ui:** Timer action controls Memo dependency ([#1091](https://github.com/Hypfer/Valetudo/issues/1091)) ([7ebbafc](https://github.com/Hypfer/Valetudo/commit/7ebbafce307fc5b3e07f73f3652d154a63d3a248))\r\n* **ValetudoEvents:** Resetting a consumable should also set its event to processed ([d705c5b](https://github.com/Hypfer/Valetudo/commit/d705c5bc67cff5cb4b085893f428bf7794a26bb1)), closes [#1096](https://github.com/Hypfer/Valetudo/issues/1096)\r\n* **webserver:** Remove obsolete mqtt config password stripping ([c4f6fab](https://github.com/Hypfer/Valetudo/commit/c4f6fabc62c69b6573782e31511f8df02ea2e7a3))\r\n* **webserver:** Strip credentials from mqtt config REST response and remove ssh key upload ([5b66887](https://github.com/Hypfer/Valetudo/commit/5b6688778bd3efb884e027b51d2989e28c7252af))\r\n* **webserver:** Terminate SSE connections on shutdown for a clean shutdown ([bfbf4dd](https://github.com/Hypfer/Valetudo/commit/bfbf4dd7192a443ca7e49d9efa0f382040370741))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967" + } + }, + { + "version": "2021.09.0", + "releaseTimestamp": "2021-09-09T18:00:31.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.09.0

\r\n
\r\n\r\nThis release features some more bugfixes and some breaking config changes\r\n\r\n## New UI\r\n\r\nIf you haven't seen it already, check out [the previous release notes](https://github.com/Hypfer/Valetudo/releases/tag/2021.08.1).\r\n\r\n## MQTT changes\r\n\r\n### Config Schema\r\nThis release features a much cleaner mqtt configuration schema. Now, one can actually understand what the options are for.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/132738325-10a47c75-f321-4c79-94ec-374484d7b7f4.png)\r\n\r\n\r\n\r\nSince this a **breaking change**, Valetudo will likely reject your old config file and create a new one.\r\nDon't worry though. The old one is backed up meaning that you can simply copy-paste your timers, presets etc.\r\nJust check the Log for more information.\r\n\r\n### Identifier\r\n\r\nValetudo will now use the autogenerated machine identifier as the mqtt identifier and friendly name.\r\nIf you've been using the defaults until now, you'll either want to manually configure the identifier or update your scripts, delete your Vacuum Device in Home Assistant etc.\r\n\r\nThe autogenerated unique machine identifier can be found in the Log.\r\nIt will sorta look like this: `ModestFewChinchilla`\r\n\r\n### Home Assistant Map Data\r\n\r\nThe Map data camera image has been replaced with a nicer looking one that will also hopefully lead to less confusion for newcomers.\r\nIt looks like this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/132737756-efba2973-0ed7-47cb-bae4-6b6ca18acf67.png)\r\n\r\n\r\n## Out-of-Memory Issues\r\n\r\nThe out of memory issues causing Valetudo to shut down have been fixed again even though that they were already fixed.\r\nFor some reason, npm started installing the old and unpatched dependency. Probably some weirdness regarding the `package-lock.json` or something like that.\r\n\r\nThis has been solved by reimplementing what the dependency did in Valetudo itself. Fortunately, this allowed us to add logging to that.\r\nIf you're seeing something like `[WARN] Stale SSE connection to the Map SSE Hub detected. Terminating.` in your log, the mitigation is working.\r\n\r\n## Updated Robot Docs\r\n\r\nI've added some notes for each implementation to the [Supported Robots Page](https://valetudo.cloud/pages/general/supported-robots.html) to make it easier for people to choose a robot to buy.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Log autogenerated system ID ([2cc365c](https://github.com/Hypfer/Valetudo/commit/2cc365c60415f68e3ec7d454eda8387adf8c9842))\r\n* **ui:** make toggle group full width ([#1060](https://github.com/Hypfer/Valetudo/issues/1060)) ([dfdd7f7](https://github.com/Hypfer/Valetudo/commit/dfdd7f7de54ad84f0f4fd52e34692879ce0116ff))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** reduce loglevel of user ack timeout spam messages ([3f81d4c](https://github.com/Hypfer/Valetudo/commit/3f81d4c063595f129d7b08114377b6b4703628e1))\r\n* **mqtt:** Poll robot state every refreshInterval to mitigate stale data on lost cloud connections ([95ce4bb](https://github.com/Hypfer/Valetudo/commit/95ce4bb333911f67afadd769af4104d8286dae6b))\r\n* **openapi:** Fix examples schema for ManualControlCapability ([b22ceb7](https://github.com/Hypfer/Valetudo/commit/b22ceb7288f87540492182eba58f821fe44a544e))\r\n* **ui:** Change path color to black for better visibility ([2454a85](https://github.com/Hypfer/Valetudo/commit/2454a85a650a9323293dd9190cf5a955b8b2e7f8))\r\n* **vendor.viomi:** catch set_timezone errors ([c2cbd45](https://github.com/Hypfer/Valetudo/commit/c2cbd4588dede2b4d6a86c7d0807b16d7308d0f2))\r\n\r\n### Reverts\r\n\r\n* Revert \"fix(vendor.viomi): Poll state every 30s to fix stale mqtt data\" ([b55e4a5](https://github.com/Hypfer/Valetudo/commit/b55e4a58edc20d3d7e3f67274891d46967f0fd8d))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984" + } + }, + { + "version": "2021.08.1", + "releaseTimestamp": "2021-08-30T19:15:34.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.08.1

\r\n
\r\n\r\nThis release features the new React-based UI by @Jomik as well as some MQTT config changes\r\n\r\n## New UI\r\n\r\nThe new UI has been merged and is now available as a usable preview.\r\nThere's still a lot to do, however that should be much easier now that it is merged.\r\n\r\nUntil everything has been ported over, the old UI will still be the default.\r\n\r\nYou can open the new one via the menu, which now also houses a shortcut to the Swagger UI as well:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392121-d28f2ae6-278d-49a3-a51e-2ca338107ec6.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392013-d984ab62-b3c4-4590-9081-f7f457b8ad11.png)\r\n\r\n\r\nThere's a drop-down where you can select a zone preset to clean in the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392187-40648196-50be-4c23-8cea-4ed1864decd5.png)\r\n\r\n\r\nFuthermore, there's also a button, which lets you set the iteration count for segment cleanups.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392224-31302e3d-c8dc-43ce-823f-8c82732a6ffd.png)\r\n\r\n\r\n\r\nThis marks a huge step forward for the project, which has been due since years. Thanks again to @Jomik ❤\r\n\r\n## MQTT config changes\r\n\r\nThis release removes all mqtt settings where I couldn't find a reasonable explanation for why they exist.\r\nIf you're missing something, please let me know in the comments and include an explanation _why_ it was needed.\r\n\r\n## Dreame Z10 Pro Support\r\n\r\nIf you're looking for a Valetudo-supported and affordable Vacuum Robot featuring an Auto-Empty Dock, you can now buy\r\nthe Dreame Z10 Pro. I didn't know that I needed an auto-empty dock before I got one, but I definitely needed one.\r\n\r\nDo note that it's supported on the feature level of the L10 Pro, meaning that you can't control the Dock yet.\r\nThat shouldn't matter though as it is on by default and doesn't strictly require any interactions.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Add link to swagger ui to menu ([513bd8c](https://github.com/Hypfer/Valetudo/commit/513bd8c2778ae2f26186ae48f69030bbfde59628))\r\n* **ui:** Added html title to symbols in various map views ([#1026](https://github.com/Hypfer/Valetudo/issues/1026)) ([98d0f1e](https://github.com/Hypfer/Valetudo/commit/98d0f1e617cae48cbd44a171b5aa9178f0677a0b))\r\n* **ui:** Display system host info ([54df5ca](https://github.com/Hypfer/Valetudo/commit/54df5ca4f6b53a280bad52f0a73f074e1d5122f3))\r\n* **ui:** Support segment cleanup iteration count selection in map view ([f798ff5](https://github.com/Hypfer/Valetudo/commit/f798ff5d040e08a7b2f4d2606e61d8c5000957f5))\r\n* **vendor.dreame:** Add Dreame Z10 Pro ([4127ccd](https://github.com/Hypfer/Valetudo/commit/4127ccdc413155c5f3d03a29b51fc7c2f10a1353))\r\n* **vendor.dreame:** Log rootfs on startup if embedded ([cbde5a4](https://github.com/Hypfer/Valetudo/commit/cbde5a4873be1113b0dc5cfee0c1164cdc5bedf4))\r\n* **vendor.roborock:** Log rootfs on startup if embedded ([8d09fd6](https://github.com/Hypfer/Valetudo/commit/8d09fd6dab8413b3b5e9aa89921014ef267b3f23))\r\n* New React UI ([9acb2cd](https://github.com/Hypfer/Valetudo/commit/9acb2cd529a1b84dd7db333778dd523d8487c4e7))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Add proper shutdown methods to dummycloud and retrywrapper ([f0676ef](https://github.com/Hypfer/Valetudo/commit/f0676efa6d81535069f156dab2611b63b7e4d27c))\r\n* **miio:** Reduce loglevel for non-pending messages ([dbabe0b](https://github.com/Hypfer/Valetudo/commit/dbabe0b3a8e9540aff2d6f8f76dfdea2b68c767f))\r\n* **mqtt:** Catch exceptions on connect reconfiguration ([0e3bebd](https://github.com/Hypfer/Valetudo/commit/0e3bebda27553ee7f7b3796a4b89dbd53eec1ccb))\r\n* **mqtt:** Fix 100% cpu consumable fetch recursion ([ae163a9](https://github.com/Hypfer/Valetudo/commit/ae163a95e95b384e4e3e2804f9a4792c9e9793e9))\r\n* **mqtt:** Remove refreshInterval setting ([83d2a45](https://github.com/Hypfer/Valetudo/commit/83d2a45eb0d21cc15cc58cdf1734833688de0fac))\r\n* **networkadvertisement:** Hopefully fix valetudo crashing due to network issues ([4ace37e](https://github.com/Hypfer/Valetudo/commit/4ace37e0aaf88e5bb53dfbab5fbb4bf1d43c685e))\r\n* **ui:** Fix minor issues discovered by deepscan ([ee8b58b](https://github.com/Hypfer/Valetudo/commit/ee8b58b646ce006d8c1d6a5cca2f27d6af32392c))\r\n* **ui:** Only dark mode (for now?) ([db985f3](https://github.com/Hypfer/Valetudo/commit/db985f39fcfdf1bc9048d50a3e2d7d75bc42f3da))\r\n* **vendor.dreame:** Add error code 68 mapping ([741c711](https://github.com/Hypfer/Valetudo/commit/741c7114d4b88760cd30ab7e50697816f968ed2a))\r\n* **vendor.dreame:** Fix incorrect status mapping for powersave mode ([343c749](https://github.com/Hypfer/Valetudo/commit/343c749a107fdaa4f016965984065585c0872616))\r\n* **vendor.dreame:** Ignore \"event_occured\" cloud messages ([4d3f4ac](https://github.com/Hypfer/Valetudo/commit/4d3f4acf8fd864d690850070328b5f9b115934d4))\r\n* **vendor.roborock:** Handle more events ([972e4df](https://github.com/Hypfer/Valetudo/commit/972e4df9fc840c85324de7ef926763a521bd225d))\r\n* **vendor.viomi:** Poll state every 30s to fix stale mqtt data ([fdb315a](https://github.com/Hypfer/Valetudo/commit/fdb315a33beb6690a68f34a131bd7484802ded7d))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654" + } + }, + { + "version": "2021.08.0", + "releaseTimestamp": "2021-08-13T19:05:50.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.08.0

\r\n
\r\n\r\nThis release contains mostly bugfixes and code cleanup.\r\nAlso, ordered cleanup and iterations for MQTT segment cleaning.\r\n\r\n## Dreame root public release\r\n\r\nRooting Dreame robots has been made publicly available with Dennis' DEF CON 29 Talk\r\n[Robots with lasers and cameras but no security Liberating your vacuum](https://youtu.be/EWqFxQpRbv8?t=1525).\r\n\r\nFor more information, consider joining the [Dreame Robot Vacuum Telegram Usergroup](https://t.me/joinchat/zgRioVBpWHliNGZi).\r\n\r\n## MQTT Segment Cleaning options\r\n\r\nThis release allows you to specify an iteration count when calling Segment Cleanups via MQTT.\r\nFurthermore, you can also request it to respect the order you've provided. e.g. Kitchen then Living Room then Bathroom.\r\n\r\nThis requires firmware support and is also a **breaking change.**\r\nYou'll have to update your MQTT scripts/automations/whatever.\r\n\r\n[The docs](https://valetudo.cloud/pages/integrations/home-assistant-integration.html) contain an example payload.\r\n\r\n## KeyLockCapability\r\n\r\nIf you have children, cats or drunk roommates who like to mess with your robot vacuum, you can now lock the buttons via Valetudo.\r\nThis of course needs firmware support. Something that seems to be available on most Dreame-made robots.\r\n\r\nPlease note that there's no UI toggle for it yet, meaning that you'll have to use the Swagger UI (http://ROBOT_IP/swagger/) to enable it.\r\n\r\n## _valetudo._tcp bonjour service\r\n\r\nValetudo 2021.08.0 and up will publish a bonjour service, which should make it easy to auto-discover a Valetudo instance.\r\nThis will likely be useful in the future.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** KeyLockCapability ([4e2b97b](https://github.com/Hypfer/Valetudo/commit/4e2b97b3f214d239af3ef4d032c9a123fad1a816))\r\n* **networkadvertisement:** Publish _valetudo._tcp service ([cb1c34f](https://github.com/Hypfer/Valetudo/commit/cb1c34fc3c0083d5405c2c638120e498a0ef5151))\r\n* **vendor.dreame:** 1C Manual Control ([afded40](https://github.com/Hypfer/Valetudo/commit/afded402a5f26c5bcdf409b41f22d3f6d8b7272b))\r\n* **vendor.dreame:** DreameKeyLockCapability ([36e3598](https://github.com/Hypfer/Valetudo/commit/36e3598d50efc04515809f909a1600aa8575a5ac))\r\n* **vendor.dreame:** Manual Control ([4cfddd4](https://github.com/Hypfer/Valetudo/commit/4cfddd4ca17e40187d2e6f2e4557e122349978ac))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Improve unhandledRejection event handler ([a8720b9](https://github.com/Hypfer/Valetudo/commit/a8720b931a4a89b4748470786a0fe0b9b4fd64c4))\r\n* **mqtt:** Catch exceptions when handling MQTT commands ([33b9dc3](https://github.com/Hypfer/Valetudo/commit/33b9dc3cfcd6f66d3805c662766c36c494bbad69))\r\n* **mqtt:** Fix weirdness on disconnect ([be033b6](https://github.com/Hypfer/Valetudo/commit/be033b6efe1806b382a47609802e28a2004130fb))\r\n* **mqtt:** Only try to publish state when connected ([e61cf98](https://github.com/Hypfer/Valetudo/commit/e61cf9840d73a08edd44e1368339afb3d4fecef5))\r\n* **mqtt:** Publish named as well as unnamed segments ([b5ff0b4](https://github.com/Hypfer/Valetudo/commit/b5ff0b47061d997ce2439292e6f11ceea8405de0))\r\n* **vendor.dreame:** Add error code 64 for Dreame robots ([#1017](https://github.com/Hypfer/Valetudo/issues/1017)) ([4ed64d2](https://github.com/Hypfer/Valetudo/commit/4ed64d2f2ccf66994c71091b06d9531f8b603244))\r\n* **vendor.dreame:** Error 11 Mapping for CombinedVirtualRestrictions ([491ed4b](https://github.com/Hypfer/Valetudo/commit/491ed4b4f6f670f1f148383084de0f7b2528a816))\r\n* **vendor.dreame:** Fix cleaning order of segments ([d7cfd07](https://github.com/Hypfer/Valetudo/commit/d7cfd07b681e9e8c76efcaf0257b31f0c54dfcd4))\r\n* **vendor.dreame:** Handle more segment-related error codes ([57fe90a](https://github.com/Hypfer/Valetudo/commit/57fe90afebebf93519eabd7a80bf74390e0ca4da))\r\n* **vendor.dreame:** Ignore some FDS uploads ([f1930b3](https://github.com/Hypfer/Valetudo/commit/f1930b30228e34f9c123031f0e559fcd3704a532))\r\n* **vendor.dreame:** Update error code mapping ([d1699b2](https://github.com/Hypfer/Valetudo/commit/d1699b24d9631e22e4fd189c1f054a10949e4a36))\r\n* Fix invalid use of .finally() ([770f977](https://github.com/Hypfer/Valetudo/commit/770f977a1e4c76f056e1a83c9aeca76cb45b57ab))\r\n* **vendor.dreame:** Remove logging of raw data on failed parse ([11fec98](https://github.com/Hypfer/Valetudo/commit/11fec98920afae8b7d99914158706bad38f5f082))\r\n* **vendor.roborock:** Fix unhandled rejection in virtual restrictions ([4a76029](https://github.com/Hypfer/Valetudo/commit/4a760293473e57cf49217e9b901f013e2637370b))\r\n* **vendor.viomi:** Fix unhandled rejection in virtual restrictions ([af4704f](https://github.com/Hypfer/Valetudo/commit/af4704f8846cb95630debdabd1753e61a7c76ab5))\r\n* Fix more various minor issues found by deepscan ([c6c1a7f](https://github.com/Hypfer/Valetudo/commit/c6c1a7f0dd89656b3d2385ffee648e03a5956511))\r\n* Fix various minor issues found by deepscan ([37cc55f](https://github.com/Hypfer/Valetudo/commit/37cc55f4431eb01d1b2036ddc9cf1bf458368487))", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402" + } + }, + { + "version": "2021.07.1", + "releaseTimestamp": "2021-07-29T17:46:33.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.07.1

\r\n
\r\n\r\nThis release includes, SSDP and Zeroconf advertisement, an Event/Notification feature some bugfixes and lowmem optimizations.\r\nFurthermore, 2021.07.1 fixes a race condition which was present in 2021.07.0 causing crashes on reboot.\r\n\r\n## Network advertisement\r\n\r\nTo make using Valetudo a bit easier and more straight-forward, advertisement of the Service via both SSDP/UPnP as well as Zeroconf was added.\r\n\r\nIf you're on Windows, opening \"Network\" in the File Explorer should look similar to this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/127387044-da7e8c18-390f-40bc-88b1-3ff316e4e6cf.png)\r\n\r\n\r\nIf you're on a Mac, I'm sure that there's also something.\r\nFurthermore, Valetudo will log the `.local` domain it's using, which might be useful in some setups.\r\n\r\n## ValetudoEvents\r\n\r\nStarting with this release, we now have something that will deal with everything that would've been a push notification\r\nwhen using the regular app. Utilizing this, the \"Bin Full\" notification on roborock vacuum robots may finally happen.\r\n\r\nThere's no UI for it just yet, however it will be implemented eventually.\r\n\r\n## Runtime Reuse\r\n\r\nAs storage space can be quite limited on these devices, it is now possible to use the NodeJS runtime bundled with\r\nValetudo for other things as well.\r\n\r\nThis can be helpful if one would e.g. want to implement a Microservice, which also runs on the Robot, talks to Valetudo\r\nand provides Telegram connectivity.\r\n\r\nJust add the `--ignore-payload` flag plus another JS file:\r\n`./valetudo --ignore-payload repl.js`\r\n\r\nThe baked-in v8 options will still apply when reusing the runtime.\r\nThat however shouldn't be an issue for most use-cases.\r\n\r\n## S5 Max Map issues\r\n\r\nApparently, the Map Reset on the S5 Max never worked. That might explain some issues users of this Robot were seeing.\r\nIt should be fixed now.\r\n\r\n## Memory-related changes\r\n\r\nDuring the development of 2021.07.0, a lot of time was spent optimizing Valetudo for use in lowmem environments\r\nsuch as the Roborock S5 Max or Dreame D9.\r\n\r\nIt was discovered that there were issues with the SSE Map update feature, which lead to Valetudo being killed by the\r\nKernel OOM killer. This was the cause of the confusing \"Hey my Valetudo is just.. gone\" reports.\r\n\r\nWhile this was fixed by introducing limits there, Valetudo was also extended to watch its own Memory usage\r\nand shut down if it exceeds 1/3 of system memory. This should provide an additional failsafe.\r\n\r\nFurthermore, Valetudo will also set its OOM score to a rather high value by itself, so that the Kernel OOM killer\r\nwill always kill Valetudo and nothing else.\r\n\r\nStill, if you can, please buy a 512mb or more RAM robot.\r\n\r\n## Misc\r\n\r\n- To help with debugging, you can now enable an option in the config file to store all uploaded maps in the filesystem.\r\n- Resetting the Map will now also invalidate the map cached by Valetudo to reduce confusion.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Network Announcement via SSDP/UPnP and mDNS/Zeroconf/Bonjour ([c158d77](https://github.com/Hypfer/Valetudo/commit/c158d7718c33d4b14b8710e636a25616c8e1acad))\r\n* **core:** MappingPassCapability ([1b09cde](https://github.com/Hypfer/Valetudo/commit/1b09cdec4ab4d3605ae2572f1f3eb187dfd2e1d5))\r\n* **core:** PendingMapChangeHandlingCapability ([ed0455d](https://github.com/Hypfer/Valetudo/commit/ed0455d66a46b7adc16e91d34daff2da3e784417))\r\n* **miio:** Add easy way to store uploaded maps for debugging purposes ([547f8c1](https://github.com/Hypfer/Valetudo/commit/547f8c13271f684d3285490b2365f161415b357d))\r\n* **vendor.dreame:** Add Support for the L10 Pro ([2f618c0](https://github.com/Hypfer/Valetudo/commit/2f618c030edf2bd27d254992940ac7514dd4b3c3))\r\n* **vendor.dreame:** DreamePendingMapChangeHandlingCapability ([d972121](https://github.com/Hypfer/Valetudo/commit/d972121d93f6cd552d868ae0935d698efba28d6b))\r\n* **vendor.dreame:** Handle more properties ([421e7de](https://github.com/Hypfer/Valetudo/commit/421e7dea340c8e364e82bb35770958b0c7b0792f))\r\n* **vendor.dreame:** MappingPassCapability ([7f9322b](https://github.com/Hypfer/Valetudo/commit/7f9322b060d354df13d3238328d99cb29ce2df43))\r\n* Set OOM Score Adj when embedded ([6de2f06](https://github.com/Hypfer/Valetudo/commit/6de2f06ba87f1884e74acab32976437cf34cf2c2))\r\n* ValetudoEvents ([aa15238](https://github.com/Hypfer/Valetudo/commit/aa152381d1c4b73e594b1dd36c04ccfc32de3f87))\r\n* **vendor.dreame:** Map fast mapping status ([021213e](https://github.com/Hypfer/Valetudo/commit/021213e8cd3b932685b590d896dcf640c311a2fc))\r\n* **vendor.dreame:** Sensor consumable ([4c1e319](https://github.com/Hypfer/Valetudo/commit/4c1e31980af77492f634fbaad375cd20d1fb8a2d))\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Catch uncaught exceptions for an orderly shutdown ([5cf19c4](https://github.com/Hypfer/Valetudo/commit/5cf19c426734acb08f38b86a88a7743c7db770db))\r\n* **core:** Reverse event order ([a829ba5](https://github.com/Hypfer/Valetudo/commit/a829ba54ab95ea0e00c9e855467d715a98ba4055))\r\n* **networkadvertisement:** Don't crash on reboots + human-friendly URL ([3cb1cb8](https://github.com/Hypfer/Valetudo/commit/3cb1cb8dae25b472ab6b79653ea2c8ba59e2c0df))\r\n* **vendor.dreame:** Fix segment cleanup via mqtt ([5dbb9d0](https://github.com/Hypfer/Valetudo/commit/5dbb9d0474b441a3285cae22140d82ecd71fb3d6))\r\n* **vendor.dreame:** Fix status mapping and ignore irrelevant property change ([68c1c0c](https://github.com/Hypfer/Valetudo/commit/68c1c0ceb0e13609b32b9637ee07addc67330c45)), closes [#969](https://github.com/Hypfer/Valetudo/issues/969)\r\n* **vendor.dreame:** Handle more properties ([6a834c8](https://github.com/Hypfer/Valetudo/commit/6a834c8ff888ab2c24516048c899f3bf42ec0290))\r\n* **vendor.dreame:** Handle sensor consumable push ([cc8b7a5](https://github.com/Hypfer/Valetudo/commit/cc8b7a5bc86014f61a6e792c69826e7ebed653db))\r\n* **vendor.dreame:** Handle sensor consumable push ([4276c36](https://github.com/Hypfer/Valetudo/commit/4276c3648e06a6951df9ee4f576db7cb1e5821bc))\r\n* **vendor.dreame:** Handle uploaded multi-map jsons ([01486b8](https://github.com/Hypfer/Valetudo/commit/01486b80292ddbafb9cae61f43ac19a0520e0a78))\r\n* **vendor.dreame:** Revert Fix status mapping ([8db8b6f](https://github.com/Hypfer/Valetudo/commit/8db8b6fd0dc22fc1b0cb23ec1052e1fa2e2ceae1))\r\n* **vendor.dreame:** Segments from rism might not apply in some situations ([e1161cf](https://github.com/Hypfer/Valetudo/commit/e1161cf6816db67306eff7ecf4935d36b2497347))\r\n* **vendor.dreame:** There actually is a difference between pause and stop ([6da5dc4](https://github.com/Hypfer/Valetudo/commit/6da5dc46a24b622b093af15024b729252b3c2e1d))\r\n* **vendor.roborock:** Add filename to map upload url ([90b7346](https://github.com/Hypfer/Valetudo/commit/90b73465159e65f89d94fce1096cf915b4903985))\r\n* **vendor.roborock:** Enable S7 Water Pump Control + No-Mop-Zones ([f699a55](https://github.com/Hypfer/Valetudo/commit/f699a558d49523f2683c08027538466c01b61ecc))\r\n* **vendor.roborock:** MapSnapshots are only available on Gen2 robots ([0752de2](https://github.com/Hypfer/Valetudo/commit/0752de2b862f697943171b4b56ba67ea0db3f203))\r\n* **vendor.roborock:** MapSnapshots IDs are strings in valetudo but numbers for roborock ([361dffa](https://github.com/Hypfer/Valetudo/commit/361dffacea59b76726ac93eb7a3296bb6905c763))\r\n* **vendor.roborock:** Multi-Map capable roborock robots use a different command for map resets ([2bbd86f](https://github.com/Hypfer/Valetudo/commit/2bbd86f9df27baeccb46580e3a24b08b02e28ab6))\r\n* **webserver:** Remove unused parameter ([d27e3b1](https://github.com/Hypfer/Valetudo/commit/d27e3b1f626e935dcc1e279d300abc4517f45517))\r\n* Fix missing git commit id ([40ca9cb](https://github.com/Hypfer/Valetudo/commit/40ca9cb55884153c4ad582fd377cff863666d9f2))\r\n* Fix OOM-issues caused by SSE connections ([a0371f4](https://github.com/Hypfer/Valetudo/commit/a0371f4909b58403bf88fabecf2969d400c5487c))\r\n* Further tweak forced garbage collection ([c70393a](https://github.com/Hypfer/Valetudo/commit/c70393a4f19e296642ab1dd4540a3f4a64f931b4))\r\n* Further tweak SSE settings ([8eae178](https://github.com/Hypfer/Valetudo/commit/8eae1786c9d85a10c3222144e1a9561141c10746))\r\n* Further tweak SSE settings ([40d16f5](https://github.com/Hypfer/Valetudo/commit/40d16f5332f746f0d589ac530007c170eaa5a024))\r\n* Further tweak SSE settings ([cb8e01e](https://github.com/Hypfer/Valetudo/commit/cb8e01e20b195146b901f405fd87b3e45b3d69b6))\r\n* Resetting the map should also clear the Map cached by Valetudo ([e70041f](https://github.com/Hypfer/Valetudo/commit/e70041fd0318b4f8389db7b78bb4dc6bb6a75a05))\r\n* **vendor.viomi:** Set correct env variables ([#979](https://github.com/Hypfer/Valetudo/issues/979)) ([5fd4a6a](https://github.com/Hypfer/Valetudo/commit/5fd4a6a618d6ea9b93991618a3f586ca4df76903))\r\n* **vendor.viomi:** Set correct ssh key location ([b15c707](https://github.com/Hypfer/Valetudo/commit/b15c707a8a7d9b344ba314a2109bc52531f0b395))\r\n* Try logging everything we can get about process memory before committing sudoku ([6578a99](https://github.com/Hypfer/Valetudo/commit/6578a99344a6d087450a0e4b45a630398fb3a544))\r\n* Tweak forced garbage collection ([d905864](https://github.com/Hypfer/Valetudo/commit/d905864f5e2b07579a0bcf6a13be649ec9e5c785))\r\n\r\n\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769" + } + }, + { + "version": "2021.06.0", + "releaseTimestamp": "2021-06-24T18:42:47.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.06.0

\r\n
\r\n\r\nThis release features Swagger UI for proper REST API Documentation.\r\nAlso bugfixes and stability + performance improvements like the changelog of every single android app you have installed.\r\n\r\n## Swagger UI\r\n\r\n![image](https://user-images.githubusercontent.com/974410/123315997-9f21c580-d52c-11eb-8271-3f5ffd81931b.png)\r\n\r\n\r\nIn a tedious and brain-melting process, OpenAPI documentation was added to Valetudo.\r\nBy navigating to `ROBOT_IP/swagger/` you now have an interactive overview for the REST API, which directly lets you interface with the robot.\r\nThe schemas made for this are also used by the backend to validate every incoming request.\r\n\r\nSince staring at JSON Schemas all day is a pretty mind-numbing task, I didn't manage to also add examples for all responses and requests.\r\n\r\nI did however add examples for the Timers Endpoint, meaning that it is now easier to use those again.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/123316039-ab0d8780-d52c-11eb-9c17-34f20c944c16.png)\r\n\r\nUI support of course coming soon.\r\n\r\n## Config file Schema Validation\r\n\r\nThe new schemas are also used to validate the configuration file loaded by Valetudo.\r\nIf any errors arise, Valetudo will backup the config and create a new one using the defaults.\r\nThis will prevent issues with Valetudo not starting due to invalid configuration data.\r\n\r\nThe log will tell you what exactly was wrong in your config and where you can find the backup.\r\n\r\n\r\n## Other noteworthy changes\r\n\r\n### NodeJS v16.4.0\r\n\r\nThe Runtime was upgraded to v16.4.0 which brings v8 9.1 including the new Sparkplug thingy, which may result in CPU performance improvements.\r\n\r\n### MQTT ignores retained messages\r\n\r\nA common rookie mistake is that command MQTT messages are sent with the retain flag causing the robot to receive them on every reconnect.\r\nThis effectively executed a cleanup on each reboot at 4am.\r\n\r\nTo combat this, Valetudo will now simply ignore all retained messages received and complain about them in the logfile.\r\n\r\n### System REST Endpoints\r\n\r\nThere are new REST Endpoints providing system statistics such as Memory or CPU usage.\r\n\r\n`/api/v2/system/host/info`\r\n```json\r\n{\r\n \"hostname\": \"rockrobo\",\r\n \"arch\": \"arm\",\r\n \"mem\": {\r\n \"total\": 522792960,\r\n \"free\": 358219776,\r\n \"valetudo_current\": 59215872,\r\n \"valetudo_max\": 59699200\r\n },\r\n \"uptime\": 61036,\r\n \"load\": [\r\n 0.255,\r\n 0.2725,\r\n 0.28\r\n ]\r\n}\r\n```\r\n\r\n### Code Compression\r\n\r\nDue to the switch to `vercel/pkg` 5.3.0, Valetudo now uses the code compression feature, which results in smaller binaries.\r\n\r\n### Memory Usage\r\n\r\nMQTT Map compression is now streamed, which may or may not improve memory usage on 256mb ram robots.\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Ignore received retained message to work around common user errors ([26d8a4c](https://github.com/Hypfer/Valetudo/commit/26d8a4cd4c36410afabfda6f9e87e08fd01e9a28))\r\n* **mqtt:** Stream map serialization to improve memory usage with large maps ([98b2757](https://github.com/Hypfer/Valetudo/commit/98b2757aec0af94392038577eead7749ef659e17))\r\n* **timers:** Add endpoint which returns timer actions supported by this robot ([fe1fa88](https://github.com/Hypfer/Valetudo/commit/fe1fa88d715e1002d3ee607ce9646b8d8b2cdb9d))\r\n* **timers:** add ValetudoGoToTimerAction ([#953](https://github.com/Hypfer/Valetudo/issues/953)) ([d8a523e](https://github.com/Hypfer/Valetudo/commit/d8a523e40138f679411d2b8c33db3057d5f6c8d8))\r\n* **vendor.roborock:** Add support for the Roborock S7 ([c9ccb4a](https://github.com/Hypfer/Valetudo/commit/c9ccb4a11dc546da82684c5f2a80e96847ff2639))\r\n* **webserver:** Add SystemRouter ([efc46e6](https://github.com/Hypfer/Valetudo/commit/efc46e69001a2533077b1e30fd1d8f6de910e263))\r\n* **webserver:** Normalize reported system load ([b384ac3](https://github.com/Hypfer/Valetudo/commit/b384ac3038857f3e8677bac5859b8c1de99f80be))\r\n* **webserver:** Streamed compression of some heavy requests ([0d7d836](https://github.com/Hypfer/Valetudo/commit/0d7d8364b98e950d186d961062b81fbfff5e920a))\r\n* **webserver:** Validate actual endpoint existence against openApi schema ([f7cee31](https://github.com/Hypfer/Valetudo/commit/f7cee31eb20cba824d3fd2ed47cdb73a242de3f9))\r\n* Swagger Docs ([7842d9e](https://github.com/Hypfer/Valetudo/commit/7842d9ec0957a9a45f6c83ab357a901884b11ba1)), closes [#892](https://github.com/Hypfer/Valetudo/issues/892)\r\n* Validate configuration file and create a new one on error ([39e4613](https://github.com/Hypfer/Valetudo/commit/39e46137872f6774d2ebaf1120a10d0cddfff45b))\r\n\r\n### Bug Fixes\r\n\r\n* **configuration:** Add migration for invalid mqtt port type ([1220aa5](https://github.com/Hypfer/Valetudo/commit/1220aa5622dbf200ef2be88612f1e503ec887328))\r\n* **miio:** Allow setting new wifi credentials when provisioned ([32a12cf](https://github.com/Hypfer/Valetudo/commit/32a12cf82c698b64b3cc037a869f058fb4588f26)), closes [#657](https://github.com/Hypfer/Valetudo/issues/657)\r\n* **mqtt:** Calling GoTo Presets should use regular strings and not json strings ([ec975aa](https://github.com/Hypfer/Valetudo/commit/ec975aaec40c9857e7b35622253128ef75be3fbe)), closes [#960](https://github.com/Hypfer/Valetudo/issues/960)\r\n* **mqtt:** Use semaphore to avoid reconfigure race condition ([5b4b377](https://github.com/Hypfer/Valetudo/commit/5b4b377f98c5030aa13f2133b5a220c3366fae57))\r\n* **ntpclient:** Reduce loglevel of more error codes to avoid confusion ([ec4ee08](https://github.com/Hypfer/Valetudo/commit/ec4ee082eaba88d51d8948ebc97c0cb6e4347ed1))\r\n* **ui:** Allow resetting map when PersistentMapControl is unavailable ([#954](https://github.com/Hypfer/Valetudo/issues/954)) ([bc8feb9](https://github.com/Hypfer/Valetudo/commit/bc8feb936d373757093b79ed40ccd8b7318e8f67))\r\n* **ui:** Hide defunct zones button ([ae7c059](https://github.com/Hypfer/Valetudo/commit/ae7c05948c9cf7252bfedd1fe935c65d69a986b3))\r\n* **vendor.dreame:** Handle some previously unhandled messages ([810a212](https://github.com/Hypfer/Valetudo/commit/810a21226bb1580ed2afae9e2a2fad2b6faa475d))\r\n* **webserver:** Fix SystemRouter units ([fd908f6](https://github.com/Hypfer/Valetudo/commit/fd908f6da756d3d5a6f8350e1a4f4041990a6cf9))\r\n* **webserver:** os.freemem() isn't what it appears to be ([80743f4](https://github.com/Hypfer/Valetudo/commit/80743f455dd20d2abc316260308b9d322c33e284))\r\n* **webserver:** Properly report memory info for kernels older than 3.14 but newer than 2.6 ([9000f51](https://github.com/Hypfer/Valetudo/commit/9000f51eaf818ca465ad0b2ef9f91ca421ac2da4))\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083" + } + }, + { + "version": "2021.05.0", + "releaseTimestamp": "2021-05-26T11:04:43.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.05.0

\r\n
\r\n\r\nThis release features mostly bugfixes, unfinished features and a hostile takeover.\r\n\r\n## MQTT Rewrite\r\n\r\nDue to the scale of the MQTT rewrite that happened with 2021.04.0, some new bugs were introduced, which have been fixed with this release.\r\n\r\nFurthermore, this release removes the migration logic of the old mqtt config format so if you're planning on upgrading from something other than 2021.04.0, make sure to upgrade to that before installing 2021.05.0.\r\n\r\nAs always, reading all the release notes is strongly recommended during upgrades.\r\n\r\n## Not-yet finished things\r\n\r\nNot everything in this section is already part of this release.\r\n\r\n### UI Rewrite\r\n\r\n@jomik is still working on the rewrite of the Valetudo UI. It's already looking fantastic:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/119648987-635ae980-be22-11eb-82c9-3b1c999303c4.png)\r\n![image](https://user-images.githubusercontent.com/974410/119649000-6655da00-be22-11eb-831a-cb816a3991be.png)\r\n\r\n\r\nIf you're a frontend dev, a design person etc., feel free to join in. :)\r\nWe'll definitely need some design input, custom icons and much more stuff.\r\n\r\n### Timers\r\n\r\nA simple scheduler feature has been added to the backend for setups where a full-blown home automation system isn't required.\r\nThese shall be understood as WIP and can currently only be controlled [via REST API calls](https://github.com/Hypfer/Valetudo/discussions/824#discussioncomment-761574).\r\n\r\n### Dreame Support\r\n\r\nPublic root coming soon™, again.\r\n\r\nThe beta test has been expanded to more users. If you want to take part in that, make sure to join the [Telegram Dreame Usergroup](https://t.me/joinchat/2qGFUaQ2pV9hNzUy) and check out the pinned form.\r\nCurrently, the announcement of the Dreame W10 and Z10 is delaying the release of the rooting method.\r\n\r\n## Freenode hostile takeover\r\n\r\nAs you might've heard, Freenode, the FOSS IRC network has been taken over by the crown prince of korea, who decided to have some fun with it.\r\n\r\nToday, the #Valetudo Freenode channel was also taken over:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/119649150-97360f00-be22-11eb-9508-2dfb93ea39be.png)\r\n\r\n\r\nThere are other and much more popular victims of this:\r\n\r\n- https://mastodon.sdf.org/@kline/106299403921451814\r\n- https://news.ycombinator.com/item?id=27286628\r\n- https://twitter.com/fosdem/status/1397454352835653632\r\n\r\nI've left the network and strongly advice you to do the same.\r\n[https://libera.chat/](https://libera.chat/) is the continuation of Freenode with a different name, but the same Team that has been running Freenode for the last 20 years.\r\n\r\nFreenode on the other hand is just the same name but with completely different people.\r\n\r\nStick to the community. Not to the brand.\r\n\r\nFor more information, check out some of the resignation letters of the former freenode and current libera staff:\r\n\r\n- kline: https://www.kline.sh/\r\n- jess: https://gist.github.com/jesopo/45a3e9cdbe517dc55e6058eb43b00ed9\r\n- Md: https://blog.bofh.it/debian/id_461\r\n- niko: https://coevoet.fr/freenode.html\r\n- edk: https://gist.github.com/edk0/478fb4351bc3ba458288d6878032669d\r\n- emilsp: https://gist.github.com/pinkisemils/39d4ded8b1639b6f39dcab15618649f5\r\n- mniip: https://mniip.com/freenode.txt\r\n- Swant: https://swantzter.se/freenode-resignation/\r\n- JonathanD: https://gist.github.com/JonathanD82/6518b93708e0aaf4b8f92c8e7200816d\r\n\r\nThere's also a neat FAQ by @joepie91: https://gist.github.com/joepie91/df80d8d36cd9d1bde46ba018af497409\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **vendor.dreame:** Add iteration count to MapSegmentationCapability ([05b338f](https://github.com/Hypfer/Valetudo/commit/05b338f069feb7c311dcc11d7b50d91e310e79d3))\r\n* Timers ([7b8c37a](https://github.com/Hypfer/Valetudo/commit/7b8c37ad1006aec62e1f19e5aec83d54da94189d))\r\n* **ntpClient:** Keep track of the current state and enable configuration via REST ([e350eba](https://github.com/Hypfer/Valetudo/commit/e350eba43ab36076d406c02f933c7be108cc8e99))\r\n* **vendor.dreame:** 1C: Add/fix various Map & Volume capabilities ([#915](https://github.com/Hypfer/Valetudo/issues/915)) ([c88df12](https://github.com/Hypfer/Valetudo/commit/c88df12de41ec05797adeb4c5215bf4d18456c9b))\r\n* **vendor.roborock:** Add support for ordered segment cleanup with multiple iterations ([2541113](https://github.com/Hypfer/Valetudo/commit/25411138688454d43026d07c12e46b5eab5e9269))\r\n* **vendor.viomi:** Implement DND capability ([#877](https://github.com/Hypfer/Valetudo/issues/877)) ([dd05c51](https://github.com/Hypfer/Valetudo/commit/dd05c51f4dfa45ffdf973b95e6b4851e423a176c))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Better map upload logline ([0e7ce7c](https://github.com/Hypfer/Valetudo/commit/0e7ce7c7486498c55dd0443dd9cb0251fde1dab2))\r\n* **mqtt:** Allow strings as segment IDs ([#891](https://github.com/Hypfer/Valetudo/issues/891)) ([3e30414](https://github.com/Hypfer/Valetudo/commit/3e304146980c8dc2a394a54e7346528ec5a07620)), closes [#889](https://github.com/Hypfer/Valetudo/issues/889)\r\n* **mqtt:** Always publish state ([6a041c6](https://github.com/Hypfer/Valetudo/commit/6a041c62cfff4d2b04eb48e15ee20373512838fe))\r\n* **mqtt:** Only migrate HAss topics if enabled ([#912](https://github.com/Hypfer/Valetudo/issues/912)) ([eb2edaf](https://github.com/Hypfer/Valetudo/commit/eb2edaf969a175648cb0f53405b1780f0ac799d2))\r\n* **mqtt:** Publish state for both hass and homie, as the hass device availability_topic is set to the same topic ([#860](https://github.com/Hypfer/Valetudo/issues/860)) ([219bc34](https://github.com/Hypfer/Valetudo/commit/219bc348e95d78ff7dd279c52d498401b5e9d28c))\r\n* **mqtt:** Remove unnecessary availability_topic ([#859](https://github.com/Hypfer/Valetudo/issues/859)) ([aa85205](https://github.com/Hypfer/Valetudo/commit/aa85205fe09007b4b411ef9de754513dda98a4a0)), closes [#858](https://github.com/Hypfer/Valetudo/issues/858)\r\n* **ntpClient:** Support disabling the ntpClient ([949d8e3](https://github.com/Hypfer/Valetudo/commit/949d8e306b5de34c3a3755532f269f009eb50c51)), closes [#925](https://github.com/Hypfer/Valetudo/issues/925)\r\n* **timers:** Copy-paste antipattern ([e331eda](https://github.com/Hypfer/Valetudo/commit/e331eda332e12a138cd1d7e8b8994208f714833a))\r\n* **timers:** Fix zoned scheduled cleanup ([34443b3](https://github.com/Hypfer/Valetudo/commit/34443b3bea4feac5c48844554cd9a816df6f60ff))\r\n* **ui:** DND should be rendered as localtime but stored as UTC ([fd79163](https://github.com/Hypfer/Valetudo/commit/fd79163c3e9328562346a789ad5cec6e73bfe52d))\r\n* **vendor.dreame:** Ignore uploaded multi-map data ([6f3dcc5](https://github.com/Hypfer/Valetudo/commit/6f3dcc5a9a2a39eed6dcc73f2f08d1f438b09cac))\r\n* **vendor.roborock:** Handle DND as UTC ([8fc9ea8](https://github.com/Hypfer/Valetudo/commit/8fc9ea88d81505259f53e0dad5be3ed0e05d5d6f))\r\n* **vendor.roborock:** Roborock only accepts int coordinates ([c7efd6a](https://github.com/Hypfer/Valetudo/commit/c7efd6af1379de2e94594c440c126b74a36a7962))\r\n* Print error message when failing to load config file ([#914](https://github.com/Hypfer/Valetudo/issues/914)) ([9ebda7e](https://github.com/Hypfer/Valetudo/commit/9ebda7eb52185c5d8474344f0e25a653003c1d87))\r\n* **vendor.roborock:** Remove invalid RoborockCombinedVirtualRestrictionsCapability from V1 robot ([5a2bae4](https://github.com/Hypfer/Valetudo/commit/5a2bae404dfebf5e641a3e490e50f7bd254f633b))\r\n* **vendor.viomi:** Fix system timezone in init script ([#876](https://github.com/Hypfer/Valetudo/issues/876)) ([908d5dd](https://github.com/Hypfer/Valetudo/commit/908d5ddc16b03dbe92e1aafe9e0d4f755312e3d4))\r\n* **vendor.viomi:** Syntax error in init script ([2d53b7c](https://github.com/Hypfer/Valetudo/commit/2d53b7cf8a4e25764795859f88f6b4bb24a291e1))\r\n* **vendor.viomi:** Viomi minor bugfixes ([#820](https://github.com/Hypfer/Valetudo/issues/820)) ([4742214](https://github.com/Hypfer/Valetudo/commit/47422140a77e4253606e1e0f360eaaaebb6831f7))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/43589051" + } + }, + { + "version": "2021.04.0", + "releaseTimestamp": "2021-04-25T17:40:22.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.04.0

\r\n
\r\n\r\nThis release features a complete rewrite of the MQTT interface, which brings superior OpenHAB support by fully\r\nimplementing the Homie specification, Segment renaming, Water Usage Controls, No-Mop-Zones, UI improvements and better\r\nstability in low-mem environments such as the Roborock S5 Max\r\n\r\n## Newcomer Guide\r\n\r\nTo answer common questions newcomers or people that haven't actively been following the project may have, there's now\r\nthe [Valetudo Newcomer Guide Early 2021 Edition](https://valetudo.cloud/pages/general/newcomer_guide_early_2021.html) in the docs.\r\n\r\n## MQTT Rewrite\r\n\r\n@depau has spent countless hours completely rewriting the MQTT Interface of Valetudo.\r\nNote that this is a breaking change and will require additional attention from you on upgrade.\r\n\r\nWe're now fully [Homie-compatible](https://homieiot.github.io) which brings much better support for Home Automation systems other than Home Assistant such as [OpenHAB](https://www.openhab.org/) which has recently been completely overhauled.\r\nMake sure to check out [their new demo](https://demo.openhab.org/) as well as the [Valetudo OpenHAB integration docs](https://valetudo.cloud/pages/integrations/openhab-integration.html).\r\n\r\nIf you're using something else such as FHEM or ioBroker, the new Homie MQTT implementation should also be much easier to work with.\r\nDocumentation on the new MQTT schema can be found in the [MQTT Docs](https://valetudo.cloud/pages/integrations/mqtt.html).\r\n\r\nDavide also went the extra mile and wrote an excellent [developer documentation for the new MQTT feature](https://valetudo.cloud/pages/development/mqtt.html) which is a must-read if you want to contribute to that part of Valetudo.\r\n\r\n### Home Assistant MQTT Rewrite FAQ\r\n\r\nValetudo will try its best to auto-migrate your configuration file and Home Assistant configuration.\r\nHowever, the latter may not work 100% all the time. Therefore, here's an FAQ for Home Assistant users migrating to Valetudo 2021.04.0\r\n\r\nQ: Home Assistant now shows everything as unavailable.\r\nA: Refresh the page\r\n\r\nQ: The consumables do not update in Home Assistant\r\nA: Wait one minute, or open valetudo and navigate to the consumables page\r\n\r\nQ: ICBINV does not seem to be retrieving the map\r\nA: The map topic changed, it is now TOPIC_PREFIX/IDENTIFIER/MapData/map-data, update your ICBINV config and ICBINV to 2021.04.0\r\n\r\nQ: Some stuff is still not detected by Home Assistant\r\nA: Reset the autodiscovery configuration by performing the following:\r\n1. Go to the MQTT settings\r\n2. Disable MQTT, enable \"Delete autodiscovery on shutdown\" under \"Home Assistant Autodscovery\".\r\n3. Save MQTT configuration\r\n4. Check Hass to ensure everything has disappeared, refresh the page as needed.\r\n5. Enable MQTT, disable \"Delete autodiscovery on shutdown\" under \"Home Assistant Autodscovery\".\r\n6. Save MQTT configuration\r\n\r\nQ: `vacuum.send_command` doesn't work anymore\r\nA: Yep. The docs will be updated shortly with information on how to achieve the same stuff now\r\n\r\n## Segment Renaming\r\n\r\nValetudo now supports (re-)naming segments and cleaning them from the UI Homepage in the same way you'd trigger a\r\nZonePreset cleanup.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/116003253-844ed580-a5fd-11eb-9ef1-4325a0104996.png)\r\n\r\n## Water Usage Control and No-Mop Zones\r\n\r\nIt is now possible to control the water grades of your robot using Valetudo, which is a completely new feature\r\nthat never appeared elsewhere before :^)\r\n\r\nFurthermore, no-mop-zones are back as well.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/116003434-38e8f700-a5fe-11eb-8273-39f8f713479d.png)\r\n![image](https://user-images.githubusercontent.com/974410/116003272-9d578680-a5fd-11eb-9c4d-8d954bec7913.png)\r\n\r\n\r\n## Lowmem enhancements\r\n\r\nAs it turns out, running nodejs in very resource-limited embedded environments such as vacuum robots isn't exactly\r\nthe intended core use-case of the runtime, which is why we seem to be pushing the limits especially on devices with\r\nonly 256mb ob ram such as the Roborock S5 Max.\r\n\r\nAnother surprising discovery is that Nodejs Buffers are not part of the configured heap, which is why even though we've\r\nset the maximum heap size to under 40mb, in some cases, the rss of Valetudo grew to over 100mb, which then caused some\r\nrobots to go out of memory.\r\n\r\nFor some reason, the garbage collector simply doesn't care about old and unused Buffers even if the memory pressure rises.\r\nTherefore, for now, we're forcing a manual garbage collection if the memory usage seems odd.\r\n\r\nThis significantly improved the stability on the S5 Max and is now enabled for all builds.\r\nStill, I'd recommend choosing the lowmem build for 256mb ram roborock robots.\r\n\r\n## UI\r\n\r\nStuff such as Virtual Walls will now snap to reasonable angles on creation so that you don't get virtual walls that are infuriatingly almost straight but not quite.\r\n\r\n## Musl\r\n\r\nThanks to recent changes in vercel/pkg, the nodejs base binaries used are now statically linked against musl instead of glibc,\r\nwhich apart from being neat enables us to drop the DNSHack.\r\n\r\nAlso, we've upgraded the runtime to Node v14.16.1\r\n\r\n## Dreame Support\r\n\r\nThe Dreame 1c support has been greatly improved thanks to the help of @frankZZ\r\n\r\nPublic root coming soon™\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Collect our own garbage ([3c3df9a](https://github.com/Hypfer/Valetudo/commit/3c3df9a584cdb7193715b583fbb90c9dcd8591ca))\r\n* **core:** MapSegmentRenameCapability ([6371291](https://github.com/Hypfer/Valetudo/commit/63712911c5a81584fc6482ac94d587aa35e5bfbb))\r\n* **MockRobot:** add GoToLocationCapability and MockMap ([2957e25](https://github.com/Hypfer/Valetudo/commit/2957e25bb57c9f9c8f8c68dcf4691900b4e68544))\r\n* **MockRobot:** add MapResetCapability ([531498b](https://github.com/Hypfer/Valetudo/commit/531498b47327ddf4be6337806e68020eafa597eb))\r\n* **MockRobot:** Add MockCarpetModeControlCapability ([#759](https://github.com/Hypfer/Valetudo/issues/759)) ([5bd5fb7](https://github.com/Hypfer/Valetudo/commit/5bd5fb7a99988cc6f0db7d2ed2d39b16d756cca7))\r\n* **MockRobot:** Add MockConsumableMonitoringCapability ([6d8b8e0](https://github.com/Hypfer/Valetudo/commit/6d8b8e092ad31190c111c7a0b12f5acbcb319b5b))\r\n* **MockRobot:** Add MockDoNotDisturbCapability ([f85194c](https://github.com/Hypfer/Valetudo/commit/f85194c0192a8a0d5b6b0058f6250841eb08d89f))\r\n* **MockRobot:** Add MockWifiConfigurationCapability ([accba05](https://github.com/Hypfer/Valetudo/commit/accba051906cdb111e734bf1950484f918562e9c))\r\n* **MockRobot:** add PersistentMapControlCapability ([f91e8e7](https://github.com/Hypfer/Valetudo/commit/f91e8e7e38d0a14de7f22fd432ef14cb8dd5d09f))\r\n* **MockRobot:** Add speaker capabilities ([12d1a27](https://github.com/Hypfer/Valetudo/commit/12d1a27119fad31a9f4d3b56c3a73b9f0cde24f2))\r\n* **mqtt:** Add MapSegmentationCapabilityMqttHandle ([#842](https://github.com/Hypfer/Valetudo/issues/842)) ([0534888](https://github.com/Hypfer/Valetudo/commit/0534888b23295d031fac7358a1846a0355b7b504))\r\n* **mqtt:** Add vacuum error state description property ([#850](https://github.com/Hypfer/Valetudo/issues/850)) ([14793c7](https://github.com/Hypfer/Valetudo/commit/14793c7744aa38f83de5c8eab88b0abfebd1edb1)), closes [#816](https://github.com/Hypfer/Valetudo/issues/816)\r\n* **mqtt:** Await MQTT disconnect before proceeding with shutdown ([1c0410c](https://github.com/Hypfer/Valetudo/commit/1c0410c1d6fe0554609baaaa521ebe9d300fe5f3))\r\n* **mqtt:** Provide segment information ([f104189](https://github.com/Hypfer/Valetudo/commit/f1041890164d451d7ee9e6c8a991a8f360bd394c))\r\n* **mqtt:** Remove increase/decrease from intensity capability ([#843](https://github.com/Hypfer/Valetudo/issues/843)) ([e6fd6e4](https://github.com/Hypfer/Valetudo/commit/e6fd6e4534db0366078b7cd7797dc0f0051ade99))\r\n* **ui:** Add dialog for renaming segments ([#772](https://github.com/Hypfer/Valetudo/issues/772)) ([306b8ba](https://github.com/Hypfer/Valetudo/commit/306b8ba9c27331bb79f886b468b0edadd86c1e70))\r\n* **ui:** add Segments on home ([2129e22](https://github.com/Hypfer/Valetudo/commit/2129e2278362424f42eab7c2062094461911f720)), closes [#773](https://github.com/Hypfer/Valetudo/issues/773)\r\n* **ui:** capitalize robot states in UI ([#765](https://github.com/Hypfer/Valetudo/issues/765)) ([c988e69](https://github.com/Hypfer/Valetudo/commit/c988e6992d85b84a1d24c1f01b097d7734ac6603))\r\n* **ui:** Generate consumables list dynamically ([#764](https://github.com/Hypfer/Valetudo/issues/764)) ([05d658b](https://github.com/Hypfer/Valetudo/commit/05d658bc90fb8a4fee13a81caae4fb2a0fb5de8c))\r\n* **ui:** Snap zones and walls to grid and reasonable angles to implement [#796](https://github.com/Hypfer/Valetudo/issues/796) ([25836e8](https://github.com/Hypfer/Valetudo/commit/25836e87b70e9065d943daf1ce85478bee179074))\r\n* **ui:** Toggle button states depending on Robot Capabilities ([#769](https://github.com/Hypfer/Valetudo/issues/769)) ([cc66d52](https://github.com/Hypfer/Valetudo/commit/cc66d5292f1ba0306e8b5362b63860d177fb5b0f))\r\n* **ui:** Water Usage Control ([cf375ce](https://github.com/Hypfer/Valetudo/commit/cf375ceeb65ace4f0cbe99a7ef58d865426e6e07))\r\n* **vendor.dreame:** 1C voicepack install support ([#795](https://github.com/Hypfer/Valetudo/issues/795)) ([b72ca53](https://github.com/Hypfer/Valetudo/commit/b72ca53f99bfa94f693c1b9c36a904cc417c2533))\r\n* **vendor.dreame:** Add Dreame F9 ([4fe0ff7](https://github.com/Hypfer/Valetudo/commit/4fe0ff7fd952533a073cd51432626f99aeadd856))\r\n* **vendor.dreame:** Add more 1C variants ([9e2e194](https://github.com/Hypfer/Valetudo/commit/9e2e194bcdacc141fc87e5c49489eb669de9c8a9))\r\n* **vendor.dreame:** Add MOVA Z500 ([0107932](https://github.com/Hypfer/Valetudo/commit/01079324727b71acd17eb8d8b16a2547663179b3))\r\n* **vendor.dreame:** DreameCarpetModeControlCapability ([2d674d4](https://github.com/Hypfer/Valetudo/commit/2d674d4d6381f9ca7f146d71445e671f14195773))\r\n* **vendor.dreame:** DreameMapResetCapability ([f60fe24](https://github.com/Hypfer/Valetudo/commit/f60fe242ba8b2bba4560a7c91443ba0c07dbd133))\r\n* **vendor.dreame:** DreameWaterUsageControlCapability ([8be7cd4](https://github.com/Hypfer/Valetudo/commit/8be7cd437bcd2cb938ea5798f767b112c22f87b5))\r\n* **vendor.viomi:** Add viomi.vacuum.v6 to supported devices ([#849](https://github.com/Hypfer/Valetudo/issues/849)) ([a18633c](https://github.com/Hypfer/Valetudo/commit/a18633c97bb3897ecf60d6736b68ab9f9477a3ed)), closes [#848](https://github.com/Hypfer/Valetudo/issues/848)\r\n* **webserver:** Add X-Valetudo-Version header ([d494510](https://github.com/Hypfer/Valetudo/commit/d494510e0209f743e5f8bc8bef898a9e787bf9db))\r\n* Debug capability ([#813](https://github.com/Hypfer/Valetudo/issues/813)) ([4866475](https://github.com/Hypfer/Valetudo/commit/48664757035ebd0a6493c3de5433c02eb197800e))\r\n* Remove DNSHack since we're using musl now ([79194b6](https://github.com/Hypfer/Valetudo/commit/79194b690d27d4ba012536564ed35cad4d3df3b4))\r\n* SSE Endpoints for State and StateAttributes ([c90d426](https://github.com/Hypfer/Valetudo/commit/c90d426cb96c26b2326d64e2a7da27694ea08014))\r\n* **vendor.dreame:** 1C active zone & segments ([2281701](https://github.com/Hypfer/Valetudo/commit/22817015de62d93a9aaf46fb9fa4304d66603d6e))\r\n* **vendor.dreame:** DreameMapSegmentRenameCapability ([1470c53](https://github.com/Hypfer/Valetudo/commit/1470c539d3fb0425906b989f59adaad4b9efa739))\r\n* **vendor.dreame:** Implement/setup most capabilities of the 1C ([256b907](https://github.com/Hypfer/Valetudo/commit/256b9076a3727e3f85bfc8412e296e8009a42052))\r\n* **vendor.dreame:** Update 1C properties_changed handling ([83dddfe](https://github.com/Hypfer/Valetudo/commit/83dddfe402183456d50781435b154281d03acf1e))\r\n* **vendor.dreame:** Use currently configured water grade and fanspeed when starting a zone or segment cleanup ([200b13b](https://github.com/Hypfer/Valetudo/commit/200b13b5c8434375db486b93067278ddca490a42))\r\n* **vendor.roborock:** RoborockManualControlCapability ([59b9bd5](https://github.com/Hypfer/Valetudo/commit/59b9bd5e7a315c21f459613a9f09e8f50787ab7b))\r\n* **vendor.roborock:** RoborockMapSegmentRenameCapability ([4d6a1a4](https://github.com/Hypfer/Valetudo/commit/4d6a1a415c67c2d4e43f8220f7babe18e322e641))\r\n* **vendor.roborock:** RoborockWaterUsageControlCapability ([fdebd3c](https://github.com/Hypfer/Valetudo/commit/fdebd3c45df68797b353866dfd7a1e8684600a99))\r\n* **vendor.viomi:** Add MapResetCapability ([#785](https://github.com/Hypfer/Valetudo/issues/785)) ([696d76b](https://github.com/Hypfer/Valetudo/commit/696d76be682a905c809298c86032041243a2e1fe))\r\n* **vendor.viomi:** Add ViomiMapSegmentationCapability ([#762](https://github.com/Hypfer/Valetudo/issues/762)) ([1a9eef4](https://github.com/Hypfer/Valetudo/commit/1a9eef40b34fe991ed26989033daafdd8ace856d))\r\n* **vendor.viomi:** Add ViomiMapSegmentRenamenCapability ([0123f24](https://github.com/Hypfer/Valetudo/commit/0123f245bf6b7cedabaebf61da15f1959727c9e8))\r\n* **vendor.viomi:** Manual control capability ([#740](https://github.com/Hypfer/Valetudo/issues/740)) ([a5324e8](https://github.com/Hypfer/Valetudo/commit/a5324e8ece40709be7168730ef77978c3f971d94))\r\n* **vendor.viomi:** ViomiMapSegmentEditCapability ([#766](https://github.com/Hypfer/Valetudo/issues/766)) ([a210b0e](https://github.com/Hypfer/Valetudo/commit/a210b0edcadc29e7ab82e29258b2594fc622c53c))\r\n* no-mop zones ([f011023](https://github.com/Hypfer/Valetudo/commit/f0110231fe84f9ae7d7ed219bcece1bf387f2088))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Add name to ValetudoMapSegment ([e9da2cf](https://github.com/Hypfer/Valetudo/commit/e9da2cf5ea2cc408365fc96fb34430fcf73585d4))\r\n* **core:** Lowmem enhancements ([5787afa](https://github.com/Hypfer/Valetudo/commit/5787afa34d281e709dbe7e5f81af33e5623154e0))\r\n* **core:** Segment IDs should be strings ([97c832e](https://github.com/Hypfer/Valetudo/commit/97c832ea527665459ad9e3eb2c8f562f70a08478))\r\n* **miio:** Improve error message on missing keys in device.conf ([7ed177a](https://github.com/Hypfer/Valetudo/commit/7ed177a85ac50ec23a913c5265511e9adf839f8a))\r\n* **mqtt:** Await close event before considering MQTT closed ([1afa717](https://github.com/Hypfer/Valetudo/commit/1afa717d6e4815ba773200523324a8e835cc382d))\r\n* **mqtt:** Do not disconnect on cfg reload if not connected ([5c74342](https://github.com/Hypfer/Valetudo/commit/5c74342f94774333b42398c9a4373015bf9bbc4d))\r\n* **mqtt:** Handle nested reconfiguration ([#841](https://github.com/Hypfer/Valetudo/issues/841)) ([c0ff5ce](https://github.com/Hypfer/Valetudo/commit/c0ff5ce03fdcdf282f56adfabf3362bae5de38c6))\r\n* **mqtt:** Make BasicCtl actually home when HOME is sent ([8272dd5](https://github.com/Hypfer/Valetudo/commit/8272dd59e0fcbfd75ad75c0b992b56469cab2c53))\r\n* **mqtt:** Map zone presets to zones ([#839](https://github.com/Hypfer/Valetudo/issues/839)) ([8ac882f](https://github.com/Hypfer/Valetudo/commit/8ac882f75e3b4c67bc2a9192f28074e4609aaa58))\r\n* **mqtt:** Remove test leftovers from consumable monitoring ([#831](https://github.com/Hypfer/Valetudo/issues/831)) ([ec289a0](https://github.com/Hypfer/Valetudo/commit/ec289a08de38f4e24bfab61f2467cee9d99e2cba))\r\n* **ui:** instead of hiding settings based on capabilities at page load, unhide at page load ([#774](https://github.com/Hypfer/Valetudo/issues/774)) ([e5f0f4f](https://github.com/Hypfer/Valetudo/commit/e5f0f4fe2494ab7faf6825f54bfd38b8217d40e1))\r\n* **vendor.roborock:** do not send empty layers ([#809](https://github.com/Hypfer/Valetudo/issues/809)) ([a2e1c21](https://github.com/Hypfer/Valetudo/commit/a2e1c21bcc3dbf12a83fdaea84701b98d9387c17))\r\n* **vendor.roborock:** Don't store null to this.state.map on map parse failure ([ae4bf24](https://github.com/Hypfer/Valetudo/commit/ae4bf248d6c3848abae0a6ebc039aa2f0efc6bbc))\r\n* **vendor.roborock:** Fix segment rename ([0bed81a](https://github.com/Hypfer/Valetudo/commit/0bed81ab4f0ddccdad044ce805dda3af8736eb96))\r\n* **vendor.roborock:** Fix V1 capabilities ([6cdcc1e](https://github.com/Hypfer/Valetudo/commit/6cdcc1eb00a414d5f450c83f27f0267c082e7099))\r\n* **vendor.roborock:** Renaming map segments always requires the full list of names ([559d1ad](https://github.com/Hypfer/Valetudo/commit/559d1ada913e04258217134f3c7aa148d7eb7e21))\r\n* **vendor.roborock:** Roborock expects a number as the segmentId ([1e6db81](https://github.com/Hypfer/Valetudo/commit/1e6db81e71d43bf2060dec7ff90173a4cdc6e150))\r\n* **vendor.viomi:** Don't store paths with zero points ([77e7128](https://github.com/Hypfer/Valetudo/commit/77e712813191bc427306c80bf79f1b81f47202fd))\r\n* **vendor.viomi:** Fix \"Unknown water grade\" ([#784](https://github.com/Hypfer/Valetudo/issues/784)) ([04f2df4](https://github.com/Hypfer/Valetudo/commit/04f2df4c1cb546d195f3414c79557fcf0d320ae1))\r\n* **vendor.viomi:** Fix basic control functionality ([#782](https://github.com/Hypfer/Valetudo/issues/782)) ([a0fa7f4](https://github.com/Hypfer/Valetudo/commit/a0fa7f49f7f0779357c3ce61d354badd5bac07ed))\r\n* **vendor.viomi:** Fix last clean time ([#822](https://github.com/Hypfer/Valetudo/issues/822)) ([21b5876](https://github.com/Hypfer/Valetudo/commit/21b5876362939fc2e0d7ee7edbb4651411be39da))\r\n* **vendor.viomi:** Fix map issues (hopefully) ([#819](https://github.com/Hypfer/Valetudo/issues/819)) ([07a1c7a](https://github.com/Hypfer/Valetudo/commit/07a1c7ad78e3593b90e12ba0bb8286ed0c4f58e1))\r\n* **vendor.viomi:** Fix operation mode selection ([710758d](https://github.com/Hypfer/Valetudo/commit/710758d4840b06b3bff3bfb1e7dd521e48fa3d3b))\r\n* **vendor.viomi:** Fix water grade controlling fan speed instead ([#791](https://github.com/Hypfer/Valetudo/issues/791)) ([3f4d844](https://github.com/Hypfer/Valetudo/commit/3f4d844c2979527624623bb2ff67654a0961f768))\r\n* **vendor.viomi:** Increase timeout for set_timezone ([#806](https://github.com/Hypfer/Valetudo/issues/806)) ([a128a91](https://github.com/Hypfer/Valetudo/commit/a128a91499d94f0e75d17f87396571f6c889a7ac)), closes [#799](https://github.com/Hypfer/Valetudo/issues/799)\r\n* **vendor.viomi:** Raise default miIO timeout ([#817](https://github.com/Hypfer/Valetudo/issues/817)) ([5f6068d](https://github.com/Hypfer/Valetudo/commit/5f6068d7790a8f3f322f4825493608605ed80a63))\r\n* **vendor.viomi:** replace fanSpeeds with waterGrades ([#825](https://github.com/Hypfer/Valetudo/issues/825)) ([2b5d3e6](https://github.com/Hypfer/Valetudo/commit/2b5d3e69b9ea9a1ab966efc67652f55e638bf0f4))\r\n* **vendor.viomi:** Viomi segment edit fixes ([#821](https://github.com/Hypfer/Valetudo/issues/821)) ([5c8495c](https://github.com/Hypfer/Valetudo/commit/5c8495ce2eff247a667e87b2649c98ee13bddf28))\r\n* Improve state handling in MockConsumableMonitoringCapability ([1138c84](https://github.com/Hypfer/Valetudo/commit/1138c8466ca776960e0dc6030b1efe5f6e8343f2))\r\n* MapParsers should not return empty path map entities ([371ceea](https://github.com/Hypfer/Valetudo/commit/371ceea9e4e7b591b19b0dc3d4887feca3ab8692))\r\n* Typo in ConsumableStateAttribute ([7d64a1a](https://github.com/Hypfer/Valetudo/commit/7d64a1a90407d555cdd84eca6d1fae2ed828d5e2))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/41971628" + } + }, + { + "version": "2021.03.0", + "releaseTimestamp": "2021-03-15T18:15:42.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.03.0

\r\n
\r\n\r\nThis release features segment editing, SVG path and icon rendering, and a cool new companion service.\r\n\r\n## Segment editing\r\n\r\nYep. It's finally here.
\r\nStarting with this release, you can split and merge your Segments, which you might also refer to as Rooms.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201031-a565e480-85c2-11eb-8650-ec0b46d9b348.png)\r\n\r\n\r\nIf this was the only thing holding you back from switching back to Valetudo: Welcome back.\r\n\r\n## SVG Path + Icons\r\n\r\nThe map rendering was reworked. It's still a canvas but everything that isn't pixel-based is now drawn as an SVG, which results in greatly improved visual fidelity.\r\nSee for yourself:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201075-b31b6a00-85c2-11eb-894e-877a136a84e6.png)\r\n\r\n\r\nFurthermore, this might also improve performance. In any case, I'm quite happy with how good zooming in looks now.\r\n\r\n## Valeronoi\r\n\r\n@ccoors built a companion service which connects to Valetudo and generates a Wifi signal strength heatmap.
\r\nYou should definitely check that out. It's great!\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201122-be6e9580-85c2-11eb-9d7c-3dcdcf7cd8f3.png)\r\n\r\n\r\nIts repo can be found here: [https://github.com/ccoors/Valeronoi](https://github.com/ccoors/Valeronoi)\r\n\r\nI'm looking forward to seeing more companion services appear in the near future.\r\n\r\n## More Valetudo Builds\r\n\r\nStarting with this release, there's more than one Valetudo binary available for download in the releases section.
\r\nThe regular `valetudo` binary has been renamed to `valetudo-armv7` so just take that one if you're upgrading.\r\n\r\nThere's also a `valetudo-armv7-lowmem` with a slightly decreased heap size. I haven't testet that very much yet so feel free to do that\r\nespecially if your robot only has 256mb or less of ram available.\r\n\r\nAnd finally there's now a `valetudo-aarch64` binary to support robots with that cpu architecture.\r\n\r\nWhile doing that, I've also upgraded the Valetudo nodejs base binaries to `v14.16.0` which should include performance, stability and security improvements.\r\n\r\n## Misc\r\n\r\n### VoicePacks\r\n\r\n@depau added a way to install new VoicePacks. There's no UI support for that and the request required might vary from vendor to vendor.
\r\nUsually, it should be sufficient to provide an URL to the VoicePack + its hash and it should install fine.\r\n\r\n\r\n### MockRobot\r\n\r\n@alexkn added a `MockRobot` to make development easier and enable you to contribute to Valetudo even if you don't have a robot around.\r\n\r\n### ID Button\r\n\r\nFurthermore, I've added an ID button to the Zone and Location Preset map edit view, which shows you the ID of the preset you're editing so that you can\r\nuse it via MQTT.\r\nIt's pretty much a hack but that's better than nothing ¯\\_(ツ)_/¯\r\n\r\n### Git Commit UI Info\r\n\r\nThe info section of the UI will now also contain your currently running git commit id, which should make debugging a bit easier in certain situations.\r\n\r\n### Docs\r\n\r\nThe Docs at [valetudo.cloud](https://valetudo.cloud) have been improved and now feature an autogenerated overview of all supported robots\r\nplus a page that explains all available capabilities.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Log and display git commit id ([2d94408](https://github.com/Hypfer/Valetudo/commit/2d9440832a0f0c5efa83e5a8d065907e1d9b89b2))\r\n* **MockRobot:** add BatteryStateAttribute ([584bfcb](https://github.com/Hypfer/Valetudo/commit/584bfcb1ba7e782d0697c36d4a3fd467451c9d6c))\r\n* **MockRobot:** add ModelName ([db643c6](https://github.com/Hypfer/Valetudo/commit/db643c687f9fb1d43a4a29b41ffe18af93542c78))\r\n* **MockRobot:** add returning state to BasicControlCapability ([721cd78](https://github.com/Hypfer/Valetudo/commit/721cd78b053ac72fdcbe01df83e7a741f0204a2b))\r\n* **MockRobot:** introduce MockRobot ([96c4bae](https://github.com/Hypfer/Valetudo/commit/96c4bae2750971d121e3165b9aff3cc6f76398ca))\r\n* **MockRobot:** MockLocateCapability ([#752](https://github.com/Hypfer/Valetudo/issues/752)) ([5c41d49](https://github.com/Hypfer/Valetudo/commit/5c41d499b2478b09007a1af1a395f3a946dcb2ea))\r\n* **ui:** Add info button which shows the id of a zone or location preset ([ea7cce4](https://github.com/Hypfer/Valetudo/commit/ea7cce4a27c54412a6818e4b969d294d0190493c))\r\n* **ui:** Draw path as SVG ([48e5d54](https://github.com/Hypfer/Valetudo/commit/48e5d54417fb0e11cb92ea82930ce81580f70743))\r\n* **ui:** Nice rounded paths ([59aaee3](https://github.com/Hypfer/Valetudo/commit/59aaee3bf9d2cdfd3823ef0f91566d17b388af1d))\r\n* **ui:** Render icons as SVGs ([12f2907](https://github.com/Hypfer/Valetudo/commit/12f290741bb16c05530294a934f8167069288675))\r\n* **ui:** Segment editing ([e306569](https://github.com/Hypfer/Valetudo/commit/e306569d2daaa6f8ab7cfe75d3cd4a99b37faa8b))\r\n* **vendor.dreame:** DreameVoicePackManagementCapability ([f9d6ab1](https://github.com/Hypfer/Valetudo/commit/f9d6ab13ad8939b5fbdb09372b2f8b3fc3ac5187))\r\n* **vendor.dreame:** Fully implemented segment joining + splitting ([82e4fe3](https://github.com/Hypfer/Valetudo/commit/82e4fe3609b706c7a38efd47086604d5e92c1f36))\r\n* **vendor.roborock:** Add support for the S4 Max ([#699](https://github.com/Hypfer/Valetudo/issues/699)) ([f7eb451](https://github.com/Hypfer/Valetudo/commit/f7eb45105751827d371661e78b44b5e2d8c190d6))\r\n* **vendor.roborock:** RoborockVoicePackManagementCapability ([d81befc](https://github.com/Hypfer/Valetudo/commit/d81befc121116864faad129a06327325bf3b8dd4))\r\n* **vendor.viomi:** Ensure timezone is UTC ([#732](https://github.com/Hypfer/Valetudo/issues/732)) ([bafa158](https://github.com/Hypfer/Valetudo/commit/bafa158814c3185cffbbaa9c9529227883f13071)), closes [#728](https://github.com/Hypfer/Valetudo/issues/728)\r\n* **vendor.viomi:** initial implementation of ViomiZoneCleaningCapability class ([#675](https://github.com/Hypfer/Valetudo/issues/675)) ([f760137](https://github.com/Hypfer/Valetudo/commit/f7601370353659ce8a35e6c2a942c48d4f614226))\r\n* **vendor.viomi:** Speaker control capabilities ([#738](https://github.com/Hypfer/Valetudo/issues/738)) ([630d2ab](https://github.com/Hypfer/Valetudo/commit/630d2ab4f7c52c5c26d306e2b4e34d518123e64d))\r\n* **vendor.viomi:** ViomiCarpetModeControlCapability ([#739](https://github.com/Hypfer/Valetudo/issues/739)) ([fe31438](https://github.com/Hypfer/Valetudo/commit/fe3143854ff94de1b11d5c86720b97dbeff44058))\r\n* **webserver:** Fully implemented MapSegmentationCapabilityRouter ([eda7dcd](https://github.com/Hypfer/Valetudo/commit/eda7dcd071ac6d5438fbd1124c5b78704a8dc2ed))\r\n* Add os.freemem() to debug memoryStats ([5c7dfc3](https://github.com/Hypfer/Valetudo/commit/5c7dfc37392467602acea038407a12ccb39244e3))\r\n* Add voice pack managemenet capability ([#725](https://github.com/Hypfer/Valetudo/issues/725)) ([c953e2b](https://github.com/Hypfer/Valetudo/commit/c953e2b558b7bce5eace00655c3fb2f3ad30b0d6))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Fix map canvas size ([3c05e2d](https://github.com/Hypfer/Valetudo/commit/3c05e2d9917e222a777a9d86207712d3b798dbec))\r\n* Fix default map ([25eac7c](https://github.com/Hypfer/Valetudo/commit/25eac7c57eb6b761ac6124fe6278cc628aad24a0))\r\n* **dnshack:** Don't try resolving ip addresses ([b8c456d](https://github.com/Hypfer/Valetudo/commit/b8c456d20cfe27946390aa528a7c99ab0a02801d))\r\n* **logger:** Use the windows equivalent of /dev/null on windows machines ([fa8f909](https://github.com/Hypfer/Valetudo/commit/fa8f9097496111d4664600553538729e105d8858))\r\n* **miio:** Bind dummycloud after setting event listeners ([#741](https://github.com/Hypfer/Valetudo/issues/741)) ([2aba77e](https://github.com/Hypfer/Valetudo/commit/2aba77e1330690bb7b422e29a79951c06d62e671))\r\n* **miio:** Discard handshake packets with older stamps to avoid endless loops with 100% cpu ([e274cf1](https://github.com/Hypfer/Valetudo/commit/e274cf145b635e2cd421657da29e53e54c8e521a))\r\n* **miio:** Fix broken development token refresh ([9217f70](https://github.com/Hypfer/Valetudo/commit/9217f70702eec6fe5ba0b2e41382eaaf42482d08))\r\n* **miio:** Fix Valetudo crashing due to missing onMessage function ([4512fe0](https://github.com/Hypfer/Valetudo/commit/4512fe08a3c9bbb46aa734a625261fa8418ba6e1))\r\n* **miio:** Various fixes related to Valetudo crashing in some situations ([a62d7e3](https://github.com/Hypfer/Valetudo/commit/a62d7e35745180260d4a8a28d0b40332e7cf1f66))\r\n* **mqtt:** Log on command-less custom command json ([3fa8232](https://github.com/Hypfer/Valetudo/commit/3fa823212fe97cb62704f04c560bce365a5dfd23))\r\n* **ui:** Decouple svg path generation from rendering to eliminate flicker ([9ebee25](https://github.com/Hypfer/Valetudo/commit/9ebee2515df021ddffac52ae1ed537430e9239f1))\r\n* **ui:** do not cache API responses ([#698](https://github.com/Hypfer/Valetudo/issues/698)) ([6e3b462](https://github.com/Hypfer/Valetudo/commit/6e3b462a36db49819718d47d58cb708728477360))\r\n* **ui:** Fix copy-paste error ([4479777](https://github.com/Hypfer/Valetudo/commit/4479777743df99ce4f042f5f641ee6a22e09f292))\r\n* **ui:** Fix initial map offset ([#711](https://github.com/Hypfer/Valetudo/issues/711)) ([a408edc](https://github.com/Hypfer/Valetudo/commit/a408edce5139f4aa2d767d52da0bb527eec8160f))\r\n* **ui:** Fix log UI only working once ([#718](https://github.com/Hypfer/Valetudo/issues/718)) ([2d02570](https://github.com/Hypfer/Valetudo/commit/2d02570f0c85c078941e67020e5e02a89fa62894))\r\n* **ui:** Fix new zone placement ([036752a](https://github.com/Hypfer/Valetudo/commit/036752a58ae73fd7180d4c46ef0424d38b52dc48))\r\n* **ui:** Only show presets if the robot is capable of having those ([d996beb](https://github.com/Hypfer/Valetudo/commit/d996beb4291146e71c90971dc3654926ed72f698))\r\n* **ui:** Reduce path render resolution ([aa64016](https://github.com/Hypfer/Valetudo/commit/aa64016c29151499cad8f7fef11d8826e7cd58ad))\r\n* **ui:** Reduce path render solution and render charger + robot as locations ([1c4e4f3](https://github.com/Hypfer/Valetudo/commit/1c4e4f3374251d64f3c79689747050c469a02ad7))\r\n* **ui:** Remove old paths if they vanish from the map data ([eef055e](https://github.com/Hypfer/Valetudo/commit/eef055ed42b208deb1caaf0d2fe1b16cd48ca046))\r\n* **ui:** Various scaling-related issues ([fb92c16](https://github.com/Hypfer/Valetudo/commit/fb92c162cff7f6f42099781596cd82e9afeeca4d))\r\n* **vendor.dreame:** Maps are always persistent ([3630fa3](https://github.com/Hypfer/Valetudo/commit/3630fa36d3137516245b738ee0102721fb4f217c))\r\n* **vendor.roborock:** Fix map not being available on a fresh boot for another 60s ([f4c4c1a](https://github.com/Hypfer/Valetudo/commit/f4c4c1a0784b4930bd6913cd9da6f092e1f0aa03))\r\n* **vendor.roborock:** Fix S4 detection logic ([#729](https://github.com/Hypfer/Valetudo/issues/729)) ([75974a5](https://github.com/Hypfer/Valetudo/commit/75974a5be0735035193118594f0ee3362d3e2a43))\r\n* **vendor.roborock:** RoborockS4 actually needs the MultiMapPersistentMapControlCapability ([6279831](https://github.com/Hypfer/Valetudo/commit/6279831f16c60a8115c9a2849e1c1258d75e2477))\r\n* **vendor.viomi:** Use marketing model name for viomi.v8 ([#742](https://github.com/Hypfer/Valetudo/issues/742)) ([7987168](https://github.com/Hypfer/Valetudo/commit/79871685bec0b4afb89d6b8e41f13d5db4dd8042))\r\n* **vendor.viomi:** Wait a few seconds after cloud connected before fixing TZ ([#736](https://github.com/Hypfer/Valetudo/issues/736)) ([f9bfb00](https://github.com/Hypfer/Valetudo/commit/f9bfb001c68f20f9438ad7703f4bbb3dd9e84626))\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/39835836" + } + }, + { + "version": "2021.02.0", + "releaseTimestamp": "2021-02-16T22:37:28.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.02.0

\r\n
\r\n\r\nThis release features Home Assistant MQTT Autoconfig for the Map Data, an NTP Client and more.\r\n\r\n## Map Autodiscovery\r\n\r\nThe Valetudo Map Data is now optionally (on by default) provided as embedded and compressed text of a PNG file.
\r\nThis is not only easy due to the nature of the PNG file format but also 100% according to specs.\r\nWe're actually publishing a completely valid PNG to MQTT containing the full Map as a JSON.\r\n\r\nThis enables Valetudo to do Home Assistant Autoconfiguration for the Map as well since camera entities aren't persistent to the HA database and therefore no user interaction regarding the exclusion of the map entity from the recorder is needed.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/108130382-de886300-70af-11eb-9dca-146b677cad18.png)\r\n\r\n\r\nI'm quite happy with this approach because there's no added CPU load to Valetudo since we're just sandwiching the deflated Map JSON between other PNG chunks.\r\nFurthermore, providing the raw map data instead of an image enables better interactions with the map such as\r\n- better zooming\r\n- custom colors\r\n- custom icons\r\n- mouseover things\r\n- click-to-select things\r\n\r\netc.\r\n\r\n\r\nThe [lovelace-valetudo-map-card](https://github.com/TheLastProject/lovelace-valetudo-map-card) is required to extract and render\r\nthe map data from the camera image.\r\n\r\nIf you were already using the Valetudo Map in Home Assistant, you will need to revise your setup.
\r\nNo worries though. It is much easier now :)\r\n\r\n## NTP Client\r\n\r\nDuring \"normal\" cloud operation, miio-based robots receive the time via the miio protocol. This of course resulted in\r\nthe robots syncing their time to their time, which doesn't make much sense and may even interfere with some features.\r\n\r\nAlso, not all robot firmwares contain a build of `ntpd` and cross-compiling can be hard.\r\n\r\nTherefore, there's now a simple NTP Client integrated into Valetudo, which by default fetches the time from `pool.ntp.org` on startup\r\nand every 8 hours after a successful sync.\r\n\r\nIt can be disabled via the configuration file and doesn't do anything if Valetudo isn't running in `embedded`-mode.\r\n\r\nOf course, you can also change the ntp server to a different one in the configuration file if you happen to own a\r\nstratum-0 cesium atomic clock or even a fritzbox with an integrated ntp server.\r\n\r\n## UI-Accessible Logs\r\n\r\nThanks to @ccoors, you will now find the contents of your Valetudo logfile under Settings > Info in the Web UI.\r\nNo need for SSH anymore.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/108130399-e516da80-70af-11eb-8b15-57649eac37af.png)\r\n\r\n\r\nIt is also possible to temporarily increase the Loglevel there until the next reboot.\r\n\r\n\r\nIf you're looking for stuff like the firmware version or your local token, the log viewer is the right place for you.\r\n\r\n## Misc\r\n\r\n@bensweet86 ported even more capabilities over to the new capabilities system. Starting with this release, Valetudo is now\r\nable to both control the volume and the carpet mode setting again.\r\n\r\nFurthermore, he also fixed a long outstanding bug regarding pinch to zoom on iOS devices.\r\n\r\n\r\n\r\nDreame support has been improved as well.\r\nPublic root for those is still TBA.\r\n\r\n\r\n\r\nThere were also quite a few changes regarding the cloud redirection in this release.\r\nPlease make sure to follow the official upgrade instructions so that you don't run into any issues.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Log config and logfile location to logfile ([0171a8d](https://github.com/Hypfer/Valetudo/commit/0171a8d1ba12c96045124d0e1f5b1b215655c314))\r\n* Add Valetudo log to UI ([#690](https://github.com/Hypfer/Valetudo/issues/690)) ([89320f4](https://github.com/Hypfer/Valetudo/commit/89320f45c4b7e49d8246f9b2508bdacd4c549efb))\r\n* Log the firmware version if embedded ([4bd09c8](https://github.com/Hypfer/Valetudo/commit/4bd09c8b8ad0d2f411630430a88dacd3e6230063))\r\n* **core:** Change the interface of the SpeakerVolumeControlCapability and add the SpeakerTestCapability ([56b0637](https://github.com/Hypfer/Valetudo/commit/56b06378a8c183d488eb503056bee39ff8872486))\r\n* **mqtt:** Home Assistant Autodiscovery for Maps by embedding the map data in a png ([83d1d13](https://github.com/Hypfer/Valetudo/commit/83d1d13bc47bb7a16f1a9ed8937ce616a0f2b5ec))\r\n* **vendor.dreame:** Consumable monitoring ([e986687](https://github.com/Hypfer/Valetudo/commit/e986687f649e0f3c061653aac9d362b74bde5065))\r\n* **vendor.dreame:** D9 error codes ([669f192](https://github.com/Hypfer/Valetudo/commit/669f19273eb9e849b578508adaa7e37f99d79fed))\r\n* **vendor.dreame:** Improve handling of RISM maps ([186abd3](https://github.com/Hypfer/Valetudo/commit/186abd34852d62b3ab418216a500bfbb72423b85))\r\n* **vendor.dreame:** Minor improvements for D9 Firmware 1072 ([ef949be](https://github.com/Hypfer/Valetudo/commit/ef949be485ba97bd8c65066ff5c3f427fbf35f6e))\r\n* **vendor.dreame:** Virtual Restrictions ([3f1f494](https://github.com/Hypfer/Valetudo/commit/3f1f4940c582534f6fb5d18442e21e1183498378))\r\n* **vendor.dreame:** Volume Control + Volume Test ([1509be3](https://github.com/Hypfer/Valetudo/commit/1509be361552f76148c4f38b3d7ec1da3c400735))\r\n* **vendor.roborock:** Roborock/Capability Carpet Mode ([#661](https://github.com/Hypfer/Valetudo/issues/661)) ([54ca606](https://github.com/Hypfer/Valetudo/commit/54ca6068dbe8f09cf8105fd11c50b9107c2b739f)), closes [#656](https://github.com/Hypfer/Valetudo/issues/656)\r\n* **vendor.roborock:** Volume Control + Volume Test ([4a47939](https://github.com/Hypfer/Valetudo/commit/4a47939ebea220e19ed9da3b4427c53da429e700))\r\n* NTPClient ([8b54c7d](https://github.com/Hypfer/Valetudo/commit/8b54c7d0066d7b4b306aaf1b096ce1027651998c))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **logger:** Default loglevel should be info ([3e23678](https://github.com/Hypfer/Valetudo/commit/3e2367875b364d4ca63ea98548fbc3c2e841ee15))\r\n* **logger:** Do not log twice if logfile is the same as stdout redirection ([#691](https://github.com/Hypfer/Valetudo/issues/691)) ([2bd4c82](https://github.com/Hypfer/Valetudo/commit/2bd4c820a5f46e77383d9d489867494d4696fc09))\r\n* **logger:** Logger should log 🪵 ([58515d9](https://github.com/Hypfer/Valetudo/commit/58515d97559b 8bd2ab2ac12ddfbadd4fad576d9f))\r\n* **miio:** Don't get confused by the system clock doing weird things ([5e6d8df](https://github.com/Hypfer/Valetudo/commit/5e6d8df224d845da5218d0836f20f7eb4027d39c))\r\n* **miio:** http_dns: Block ott.io.mi.com requests ([#671](https://github.com/Hypfer/Valetudo/issues/671)) ([852683b](https://github.com/Hypfer/Valetudo/commit/852683b25815a05235b580a313a2464714786f4c))\r\n* **miio:** One failing message should not kill the process 20 minutes later ([e5fd0a5](https://github.com/Hypfer/Valetudo/commit/e5fd0a54ab1e040c2c82c60a4c5c310f4709fc6e))\r\n* **miio:** Set ServerSocket to disconnected on timeouts to prevent valetudo breaking on wifi issues ([e14935d](https://github.com/Hypfer/Valetudo/commit/e14935dfa9ef06a15871b3bd7683c55956b4db52))\r\n* **mqtt:** Fix home assistant vacuum.send_command functionality ([97ac35e](https://github.com/Hypfer/Valetudo/commit/97ac35e7e34fc7da3dbc3e4774f1f9ecbe7afe64))\r\n* **ntpClient:** Intercept dns lookup calls for our ntp server as well ([c7095a7](https://github.com/Hypfer/Valetudo/commit/c7095a7a340cfad293385a37f6f9dcf04a477e61))\r\n* **ui:** Fix for pinch zoom bug in IOS / Safari ([#683](https://github.com/Hypfer/Valetudo/issues/683)) ([3c0a644](https://github.com/Hypfer/Valetudo/commit/3c0a644da402f1e392fe7f088ba7fd3da4dafc69))\r\n* **ui:** SSE Map updates should use a relative path ([54bc2b7](https://github.com/Hypfer/Valetudo/commit/54bc2b71d99c0d2c411e807a2365107eb7949b36))\r\n* **vendor.dreame:** Don't store empty MapLayers ([1230c08](https://github.com/Hypfer/Valetudo/commit/1230c082b50f9264a27219f4f8e211de54541caf))\r\n* **vendor.dreame:** Proper angles ([43aa8c6](https://github.com/Hypfer/Valetudo/commit/43aa8c60ded5ed1bf52fdfce406c6bb0933f1cc1))\r\n* **vendor.dreame:** Properly parse map with correct rotation, offsets etc ([5e037c2](https://github.com/Hypfer/Valetudo/commit/5e037c22dfb27be9f3cdfa50b6d18911998da913))\r\n* **vendor.roborock:** calculation of max elements for virtual restrictions ([#681](https://github.com/Hypfer/Valetudo/issues/681)) ([2e4421b](https://github.com/Hypfer/Valetudo/commit/2e4421b0e27adc563a40ab9c8d2e3b804128ce57))\r\n* **vendor.viomi:** consumables command fix for viaomi.v8 ([#677](https://github.com/Hypfer/Valetudo/issues/677)) ([bef609e](https://github.com/Hypfer/Valetudo/commit/bef609efbe772632b270c67efb660ef2b8f06c0f))\r\n* **vendor.viomi:** Resolve [#672](https://github.com/Hypfer/Valetudo/issues/672): Fix viomi fan speed control ([#673](https://github.com/Hypfer/Valetudo/issues/673)) ([be0efca](https://github.com/Hypfer/Valetudo/commit/be0efca344ea7fe53858b9a28c7097ad4c99dea1))\r\n* **vendor.viomi:** Various fixes for 2020.01.1 ([a38987a](https://github.com/Hypfer/Valetudo/commit/a38987affba30f37e0cd09a67627a51adf695679)), closes [#641](https://github.com/Hypfer/Valetudo/issues/641)\r\n* **webserver:** Fix handleHttpDnsRequest scope ([8226e4a](https://github.com/Hypfer/Valetudo/commit/8226e4ad3e840539f13a358d817ec1b9217a2085))\r\n* **webserver:** Rate-limit logfile access ([8fd53a5](https://github.com/Hypfer/Valetudo/commit/8fd53a5237bc847708b7ee631da4afbd8fe7b950))\r\n\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/38135830" + } + }, + { + "version": "2021.01.1", + "releaseTimestamp": "2021-01-27T09:10:00.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

2021.01.1

\r\n
\r\n\r\n**Be advised: This release will break (almost) everything that you're currently using.**
\r\n\r\nConfig format, HTTP API and MQTT have changed significantly in this release.
\r\nYou will need to recreate your Zone presets as well as your Home Assistant Robot entity.\r\n\r\nMake sure to disable any Timers you might've configured before upgrading, since there's no way to delete/configure them in this release anymore!\r\n\r\nAlso, note that this release comes with fewer features than the previous, because not everything has been ported to the new structures yet.\r\n\r\n## Core rewrite (Capabilities)\r\n\r\nTo support a growing number of Vacuum Robots with different feature sets made by different Vendors, the core infrastructure\r\nof Valetudo was completely rewritten.\r\n\r\nNow, instead of having robots that inherit from other robots, there are so-called `capabilities` as an abstraction of features.
\r\nThere's always a generic base class for each feature (e.g. `GoToLocationCapability`) which is extended by multiple vendor-specific\r\nimplementations (e.g. `RoborockGoToLocationCapability`, `ViomiGoToLocationCapability` etc).\r\n\r\nThis approach completely encapsulates vendor-specific implementation details and makes them invisible for e.g. the webinterface or other\r\nusers of the HTTP API which has also been rewritten.\r\n\r\nOverall, I'm quite happy with how it turned out. Time will tell whether this abstraction was generic enough to deal with\r\nall possible vendor-specific differences.\r\n\r\n## New HTTP REST Interface\r\n\r\nAs mentioned, the REST interface was rewritten and is now an official way of communicating with Valetudo.
\r\n\r\nAll endpoints are dynamically generated according to which capabilities are available for the robot implementation Valetudo is using.\r\nFor example basic controls such as \"start\", \"stop\" or \"home\" are done via a PUT request to `/api/v2/robot/capabilities/BasicControlCapability`.\r\n\r\nTo find out more about all possible endpoints for your Valetudo instance, a meta-endpoint has also been added.
\r\nAt `/api/v2/` you will get JSON containing all endpoints as well as their accepted methods.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436664-9061f200-4c1e-11eb-8541-5c8ed6ccc4c2.png)\r\n\r\n## New MQTT Interface\r\n\r\nThe MQTT interface was also rewritten to support different subsets of capabilities.\r\nInstead of having a single topic, which contains all the information available, data is now split up onto different topics\r\nbased on capabilities.\r\n\r\nThis also means that you will have multiple entities for your robot in Home Assistant:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436641-44af4880-4c1e-11eb-8a9f-019d17398359.png)\r\n\r\nFurthermore, Wi-Fi information is now also available over MQTT so in theory, one could build a microservice which subscribes\r\nto both map and Wi-Fi data updates and build a Wi-Fi heatmap of their home by mapping the measurements to the position in the map.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436651-5f81bd00-4c1e-11eb-99f9-9efe6875d5b3.png)\r\n\r\n\r\nNote that the default identifier changed from `rockrobo` to `robot`, since Valetudo is not just dealing with Roborock anymore.
\r\nTherefore when reconfiguring this release, you may want to change that back to the old value if your setup relies on it.\r\n\r\n## New Config Schema + Location\r\n\r\nTo support different robots with different folder structures (some of them being read-only), the configuration location\r\nhad to be made configurable, which is a chicken/egg problem, because the information on where to find the configuration\r\nwould be configured within the configuration.\r\n\r\nTo solve this, Valetudo is now using the environment variable `VALETUDO_CONFIG_PATH` and defaults to `os.tmpdir()` if it isn't set.\r\n\r\nDue to the fact that the configuration schema also changed significantly, **you will need to reconfigure Valetudo on upgrade**.\r\n\r\nYou will also need to update your means of running valetudo to include this ENV variable since otherwise your configuration will vanish on each reboot.\r\nThis can be done either by building a new firmware image or copying the changes required from these commits\r\n\r\n[Roborock](https://github.com/zvldz/vacuum/commit/5981577aa8e8f75c4fbea7045bf4484066881b55)\r\n\r\n[Viomi](https://github.com/Hypfer/Valetudo/commit/923f941e76e2e41be7a714e47f3a08428d09cfd4)\r\n\r\n## Dreame Support\r\n\r\nWith the launch of the Dreame D9, there's now a promising successor to the Roborock S5 regarding both pricing and ease of installation.\r\nThis release already contains support for basic controls, Map Rendering, Segment Cleaning and Zoned Cleaning.\r\n\r\nRooting instructions will follow soon-ish. :)\r\n\r\nIt looks like this code should also be adaptable to the F9. We'll see about that if/when I get my hands on one\r\n\r\n## Misc\r\n\r\n**Viomi note:** If you're upgrading on a Viomi, make sure to change the cloud IP used for redirection to `203.0.113.1` which is now hardcoded.
\r\nThe docs have been updated to reflect that.\r\n\r\nValetudo is now using the CalVer versioning scheme, because it better fits the constantly changing scope of the project.\r\n\r\nI'd like to especially thank @depau for his port of the Viomi robot to the new infrastructure using only the half-finished capabilities branch\r\nand no documentation whatsoever as a reference.\r\n\r\nFurthermore, thanks to @bensweet86 for porting more capabilities to the new framework.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Publish ValetudoGoToLocations & ValetudoZonePresets ([76a9c52](https://github.com/Hypfer/Valetudo/commit/76a9c5234dfbcce864d70d1d6db781af86d6a98b))\r\n* **ui:** Bring back consumable monitoring & resetting for now ([fde2ffd](https://github.com/Hypfer/Valetudo/commit/fde2ffd8d3c7b5869f221870774a2032232d6c54))\r\n* **vacuum.roborock:** Add support for no-mopping zones on S5 Max and S6 ([#630](https://github.com/Hypfer/Valetudo/issues/630)) ([61902ed](https://github.com/Hypfer/Valetudo/commit/61902edd8b185d116dd27a02827866e3defd01b1)\r\n)\r\n* **vacuum.roborock:** Re-added support for S6 Pure ([0226cd5](https://github.com/Hypfer/Valetudo/commit/0226cd56a6f245e307944dab623d28bda8fcc288))\r\n* **vacuum.viomi:** Virtual Walls & No-Go Areas ([96462ac](https://github.com/Hypfer/Valetudo/commit/96462ac752b025a3385e31d4ea0cfbea268b207c))\r\n* **vendor.dreame:** Basic Dreame D9 support ([7c5e231](https://github.com/Hypfer/Valetudo/commit/7c5e231326bc8ca454e303b31c647f14f6773cd8))\r\n* **vendor.dreame:** Re-add support for 1c as well as more dreame capabilities ([cd76abe](https://github.com/Hypfer/Valetudo/commit/cd76abe952cda43fd260eda2b217aff677b98d29))\r\n* **vendor.roborock:** Do not disturb capability ([#659](https://github.com/Hypfer/Valetudo/issues/659)) ([4b3ed97](https://github.com/Hypfer/Valetudo/commit/4b3ed974d064b788f470c9439a719a3f3ed95cb9))\r\n* **vendor.roborock:** Use the lo alias approach for more robots ([58a2618](https://github.com/Hypfer/Valetudo/commit/58a26186f34e5331fe5373e231e97f403e15e147))\r\n* Add properties to capability ([7114fcc](https://github.com/Hypfer/Valetudo/commit/7114fccb502305e3176b350973f1ba0825e98845))\r\n* Configure authorized_keys location via ENV variable ([d06520d](https://github.com/Hypfer/Valetudo/commit/d06520da114f45778527e54446eed70df38e66ba))\r\n* Viomi capabilities port ([8486f04](https://github.com/Hypfer/Valetudo/commit/8486f04fdd9176af6e4e7be684bb3eecebaa39e1))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Only report a new token from handshake if it is actually new ([b373703](https://github.com/Hypfer/Valetudo/commit/b37370349514fea07fc8b27b89637a44e6df668e))\r\n* Fix map layer dimensions calculation for empty layers ([216c347](https://github.com/Hypfer/Valetudo/commit/216c3474e7680b90859b47e2ea5308ced8d1c7ff))\r\n* **ui:** fix [#565](https://github.com/Hypfer/Valetudo/issues/565) ui not working with safari and basic auth ([252c22d](https://github.com/Hypfer/Valetudo/commit/252c22dc9d457aa69bdbee0829930aa156430a9b))\r\n* **vendor.dreame:** Fix map parser tests ([a81b8e9](https://github.com/Hypfer/Valetudo/commit/a81b8e94a6db0c39b0881bbb29122ca62f5a2247))\r\n* **vendor.roborock:** Use lo alias cloud redirection approach for S6 & S5Max with miio_client 3.5.8 ([71bc1f8](https://github.com/Hypfer/Valetudo/commit/71bc1f8b91b47503a45b3771c3217655cc30a7fd))\r\n* Set VALETUDO_CONFIG_PATH variable for Upstart ([#648](https://github.com/Hypfer/Valetudo/issues/648)) ([f75b70d](https://github.com/Hypfer/Valetudo/commit/f75b70d7f7d3092f724555090db99aea4bccf6d9))\r\n* **mqtt:** missing / in set_fan_speed topic ([26ceb95](https://github.com/Hypfer/Valetudo/commit/26ceb95a71154396d14adfb01b6fb1d198fa3490))\r\n* **vacuum.roborock:** Fix broken cloud connectivity on newer roborock vacuums caused by missing region ([28483ab](https://github.com/Hypfer/Valetudo/commit/28483abd4431cf0d38953aefeb3995e9d45ea2b8))\r\n* **vacuum.viomi:** Added model names for viomi.v8 ([20d86c3](https://github.com/Hypfer/Valetudo/commit/20d86c3c005ac78d36bab29a78946e17f163f2c3))\r\n* **vacuum.viomi:** Fix fan speed state parsing ([3ca7450](https://github.com/Hypfer/Valetudo/commit/3ca745054d3c159023edb632e198126e89d7494a))\r\n* **vacuum.viomi:** Fix invalid property access ([6da2822](https://github.com/Hypfer/Valetudo/commit/6da282201172b3fb5efa1969aac6192d5ead5842))\r\n* **vacuum.viomi:** Segments + Docs ([#600](https://github.com/Hypfer/Valetudo/issues/600)) ([89a5485](https://github.com/Hypfer/Valetudo/commit/89a5485f17e7ac68e7b8d97ae9a8381d2f0a7767))\r\n* Improved dnshack to catch all problematic dns.lookup requests ([8609612](https://github.com/Hypfer/Valetudo/commit/8609612e03bc756194982d35b4389d27557842ac))\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/36957518" + } + }, + { + "version": "0.6.1", + "releaseTimestamp": "2020-07-30T10:51:41.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

0.6.1

\r\n
\r\n\r\nThis is merely a small fix release.\r\n\r\nWith 0.6.1, valetudo doesn't segfault anymore when using a domain name as the mqtt host.\r\nFurthermore, zones are now back to being cleaned once instead of ten times.\r\n\r\nIf you've arrived at this release and haven't seen the [0.6.0 release notes](https://github.com/Hypfer/Valetudo/releases/tag/0.6.0) yet, I strongly encourage you to do so now.\r\n\r\n\r\nAutogenerated changelog:\r\n\r\n### Features\r\n\r\n* **mqtt:** Added sw_version to mqtt autodiscovery to fix [#568](https://github.com/Hypfer/Valetudo/issues/568) ([a23d5af](https://github.com/Hypfer/Valetudo/commit/a23d5af95b7986c21e3487eb5e2d4f93c16c8ba3))\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix segfault on mqtt hostname resolution ([b2410ff](https://github.com/Hypfer/Valetudo/commit/b2410ff5eda5a67f02ff5fcad7ef7c30e498674c))\r\n* **mqtt:** Fixed [#571](https://github.com/Hypfer/Valetudo/issues/571) mqtt pause status ([8b06203](https://github.com/Hypfer/Valetudo/commit/8b06203de22871c47be97bc8e353118796636853))\r\n* **ui:** Fix mqtt settings checkboxes ([039b741](https://github.com/Hypfer/Valetudo/commit/039b7411325b74c2b4abbe58a91134fd1d1b9982))\r\n* **ui:** Restore context after drawing active zone ([4f7ec2c](https://github.com/Hypfer/Valetudo/commit/4f7ec2c44e8da163bf30c097df26a3df37380f04))\r\n* **vacuum.roborock:** Don't multiply iterations by 10 to fix [#573](https://github.com/Hypfer/Valetudo/issues/573) ([f3cc935](https://github.com/Hypfer/Valetudo/commit/f3cc9354d6da3149a69ef5476c922d97df0eb8a3))\r\n* override dns.lookup to mitigate static nodejs segfaults ([41f3e98](https://github.com/Hypfer/Valetudo/commit/41f3e981a590e76261e7d57ccff8d97b3d4b94ad))", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/29111413" + } + }, + { + "version": "0.6.0", + "releaseTimestamp": "2020-07-26T17:15:02.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

0.6.0

\r\n
\r\n\r\n## New Data Format\r\nI've finally found the time to rework the Map Data format as well as the robot state format.\r\nBoth previously being heavily influenced by roborock, the new and improved formats are a huge step for easier adaption\r\nof Valetudo to new Vacuums as well as implementation of new features.\r\n\r\nIn fact it has already proven itself in other work that has been done for this release and decreased memory pressure quite a bit.\r\n\r\nThis change is also of course a **breaking change**.\r\nMake sure to update any dependant applications/integrations/etc. as well.\r\n\r\n\r\n## (Initial) Support for many more Vacuums + a new Vendor\r\nThe list of _technically_ supported roborock vacuums has grown quite a bit.\r\nEspecially since Dennis released his guide on how to root the S6 which you can find [here](https://www.youtube.com/playlist?list=PL9PoaNtZCJRZc61c792VCr_I6jQK_IdSb).\r\n\r\nFurthermore, Valetudo has also received initial support for a dreame-made xiaomi vacuum robot: **Xiaomi MiJia 1C**\r\n\r\nThere's no map parsing yet though. Contributions much appreciated.\r\n\r\nPlease note that there's no dreame rooting guide available yet.\r\nThese release notes will be updated when it becomes available.\r\n\r\n\r\n## Segment Cleaning via the Web and MQTT\r\nOwners of room-cleaning capable roborock vacuums can now use Valetudo to do so.\r\n\r\nSimply select the segments you want to clean and start the cleanup like you would start a zoned cleanup.\r\nCurrently cleaned segments are denoted by a rotated icon.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485125-f3ff3980-cf73-11ea-87f2-dbe85508c5e1.png)\r\n\r\nIf you zoom in on a segment marker, it will display both it's segment id as well as the segments' area in `m²`.\r\nThe latter also being a benefit of the new Map Data format.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485127-fd88a180-cf73-11ea-819c-cdd60b3b062c.png)\r\n\r\nSegment cleaning is of course also available via MQTT.\r\nCheck out the updated Home Assistant docs for an example on how to use it.\r\n\r\nSince this is a generic implementation, support for other vacuum vendors will follow.\r\nYou just need to open a PR for that.\r\n\r\n### UI enhancements\r\nDynamic zones now display their size in meters which is also a helpful addition if you quickly want to measure something without leaving your desk.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485140-109b7180-cf74-11ea-82cf-23da553ae201.png)\r\n\r\nFurthermore, it is now impossible for you to break the map by zooming out too far.\r\n\r\n\r\n## Misc\r\n* The map renderer has been updated by @aa-ko to always color adjacent segments in a different color thanks to math™\r\n* MQTT supports client certificate authentication thanks to @mqtt-fan\r\n\r\nand of course there's the autogenerated changelog:\r\n\r\n### Features\r\n\r\n* Segment cleanup via WebUI + MQTT ([f14f6cc](https://github.com/Hypfer/Valetudo/commit/f14f6cc253766e11f9a95dfe6cbff7cfafc73e70))\r\n* **entities.state:** Added Charging/Charged/Discharging status to BatteryStateAttribute ([97b5cdf](https://github.com/Hypfer/Valetudo/commit/97b5cdfd93bc4f562752a0a890f1b972b620119c))\r\n* **mqtt:** add support for client certificate ([#549](https://github.com/Hypfer/Valetudo/issues/549)) ([33f94ec](https://github.com/Hypfer/Valetudo/commit/33f94ec6614d15876b5e1f77446500001185b317))\r\n* **roborock:** Experimental support for even more roborock vacuums ([2450ceb](https://github.com/Hypfer/Valetudo/commit/2450ceb3f5cb2653ee32dd3d5ef0fbf2c7e69645))\r\n* **ui:** Added zone size display, proper icon/text scaling and limited scaling ([6b61ca8](https://github.com/Hypfer/Valetudo/commit/6b61ca816f377c07c784cb9075be43e838ecb405))\r\n* **ui:** Use math (four color theorem) to properly color segments ([d462f65](https://github.com/Hypfer/Valetudo/commit/d462f65e8fe57de43daf098f295d987a11990f9d))\r\n* **vacuum.dreame:** Initial basic support for the dreame.vacuum.mc1808 ([f73c7c6](https://github.com/Hypfer/Valetudo/commit/f73c7c61dfe786131704fa90fd93e632263b982d))\r\n* **vacuum.viomi:** add support for viomi.vacuum.v8 + mop enhancements ([#543](https://github.com/Hypfer/Valetudo/issues/543)) ([17bb01e](https://github.com/Hypfer/Valetudo/commit/17bb01efe088a494563f6037076ade6e13c8c553)), closes [#541](https://github.com/Hypfer/Valetudo/issues/541) [#538](https://github.com/Hypfer/Valetudo/issues/538) [#548](https://github.com/Hypfer/Valetudo/issues/548)\r\n* Experimental support(?) for S6 MaxV ([88de212](https://github.com/Hypfer/Valetudo/commit/88de212274872eca0ca97c3b0dfadb70d2a4baa5))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **entities.map:** Fixed MapLayer area calculation ([ac86c84](https://github.com/Hypfer/Valetudo/commit/ac86c84c8fa75408b52067306f7e0c4a201e9725))\r\n* **mqtt:** Check DNS resolution before connecting to mqtt broker to fix [#563](https://github.com/Hypfer/Valetudo/issues/563) ([38a0af8](https://github.com/Hypfer/Valetudo/commit/38a0af82db66428b8a6e7340dfaac394bbfcb2ac))\r\n* **ui:** Default to colorIndex 0 if solver can't find the segment in its graph ([e1565d0](https://github.com/Hypfer/Valetudo/commit/e1565d073642c87c084d93c56e031ebbec1160bd))\r\n* **ui:** Fix map coloring ([#567](https://github.com/Hypfer/Valetudo/issues/567)) ([890120c](https://github.com/Hypfer/Valetudo/commit/890120c76930bb8941459a7e0d1baa0af8577d83))\r\n* **ui:** Fixed zone dimensions ([0ca13e3](https://github.com/Hypfer/Valetudo/commit/0ca13e328d6e4943a444f750eb35365748dd5523))\r\n* **vacuum.roborock:** Changed set_lab_status payload for S6 to fix [#540](https://github.com/Hypfer/Valetudo/issues/540) ([19e141e](https://github.com/Hypfer/Valetudo/commit/19e141efc0b6e9f4798a9bff2482feaa10f3772f))\r\n* **vacuum.roborock:** Fix map parsing failing for maps with no image data ([f187906](https://github.com/Hypfer/Valetudo/commit/f1879064b15ea978df32a12f8a23b346ba2e3e39))\r\n* **vacuum.viomi:** Hackishly fixed map parsing for viomi v6 + fan speed settings for all viomi ([ffbb8e7](https://github.com/Hypfer/Valetudo/commit/ffbb8e75ffc4ce06bab6baa6f7328877cf66659b))\r\n* **vacuum.viomi:** Hackishly fixed path + angle ([fdd80d2](https://github.com/Hypfer/Valetudo/commit/fdd80d24c577a66ecb358f838e675126abd0c084))\r\n\r\n\r\n", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/28964045" + } + }, + { + "version": "0.5.3", + "releaseTimestamp": "2020-06-14T14:04:32.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

0.5.3

\r\n
\r\n\r\nWith this release, Valetudo is upgraded to a stripped NodeJS 14.4.0 runtime, which brings both smaller binary size as well as enhanced performance.\r\n\r\nFurthermore, the long awaited cleaning of multiple zones via the Web Interface is finally here.\r\n\r\nIf you had root access to your Roborock S6/T6/S4/T4 or M1S, you could now use Valetudo as well.\r\nThere will be a guide on how to do that in the near future. Be aware, that no new features beyond those which are already available on the S5 are supported yet.\r\n\r\nIf you're a Valetudo developer, your life has become a lot easier with 0.5.3.\r\nRobot Model, Webserver Port and all the relevant settings are now configured via the config.json. No more messing around with ENV variables.\r\n\r\n\r\nHere's the autogenerated changelog:\r\n\r\n### Features\r\n\r\n* Initial Support for Roborock T/S4 and M1S ([24579f7](https://github.com/Hypfer/Valetudo/commit/24579f7acd98e276f4a85344919c4e8a8d356381))\r\n* Try to write a backup in case we're overwriting an invalid configuration file. ([#537](https://github.com/Hypfer/Valetudo/issues/537)) ([e738491](https://github.com/Hypfer/Valetudo/commit/e7384917354efa7e1d1b730b746966d4e46d87f2))\r\n* **ui:** Allow select of multiple zones for zone clean ([#535](https://github.com/Hypfer/Valetudo/issues/535)) ([1a29155](https://github.com/Hypfer/Valetudo/commit/1a29155094cdd76e02c5cbea28739d4637d90c00))\r\n* Added debug config option to continuously log memory usage ([d96eb15](https://github.com/Hypfer/Valetudo/commit/d96eb15c8f299ff49d98f9d6661c6f44225bc633))\r\n* Added option to fully configure model information via the config file ([#497](https://github.com/Hypfer/Valetudo/issues/497)) ([e241c1d](https://github.com/Hypfer/Valetudo/commit/e241c1d9b0dd1870f759fd8ebd1f1e7ec1f7cf61))\r\n* Initial support for S6 T6 and S5 Max ([f417b4d](https://github.com/Hypfer/Valetudo/commit/f417b4de3f27b0664552471c05adb220592f5c51))\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Removed unnecessary availability topic mitigation ([b76ce14](https://github.com/Hypfer/Valetudo/commit/b76ce144b4a3eb920a1dbab1991c83cf87ee7967))\r\n* Always assume embedded operation unless specified otherwise ([#536](https://github.com/Hypfer/Valetudo/issues/536)) ([7585f86](https://github.com/Hypfer/Valetudo/commit/7585f86e9fb1ec196b4b710454e1414673482081))\r\n* Removed useless app_get_locale functionality to fix [#532](https://github.com/Hypfer/Valetudo/issues/532) ([ffc06d6](https://github.com/Hypfer/Valetudo/commit/ffc06d65ba788cfbc3aee33b8e3d9d9e3fe647f9))\r\n* Simplify embedded logic now that 'auto' is gone. [#536](https://github.com/Hypfer/Valetudo/issues/536) ([b9097a6](https://github.com/Hypfer/Valetudo/commit/b9097a6f128aa947e4bb4a05fb3d79453f0f9e71))\r\n* **mqtt:** Update availability topic on each attribute topic update to fix false offline status ([af69673](https://github.com/Hypfer/Valetudo/commit/af696739d3119fbd84b1e9ba20b50b3fedce7a12))\r\n* **ui:** Fix [#527](https://github.com/Hypfer/Valetudo/issues/527) not working close and cancel buttons in timer settings ([e2ea1ce](https://github.com/Hypfer/Valetudo/commit/e2ea1ce212c4f85bba492dc273c6b7e75f4768b8))\r\n* **ui:** Hide forbidden zones editor menu item on gen 1 ([#382](https://github.com/Hypfer/Valetudo/issues/382)) ([32e9416](https://github.com/Hypfer/Valetudo/commit/32e94168fb3141fb49721be6019e0611690f3292))", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/27531929" + } + }, + { + "version": "0.5.2", + "releaseTimestamp": "2020-05-28T14:15:20.000Z", + "changelog": "
\r\n \"valetudo\"\r\n

0.5.2

\r\n
\r\n\r\nThis release contains a new and reworked Iconset for the map view as well as support for displaying detected rooms.\r\n\r\nFurthermore, these are the first release notes which feature semi-autogenerated changelogs utilizing [Conventional Commits](https://www.conventionalcommits.org)\r\n### Features\r\n\r\n* **mqtt:** Add availability as last will ([b196625](https://github.com/Hypfer/Valetudo/commit/b196625ac73e4932324b2bd2cf487790d6758711))\r\n* **ui:** Display Model information in Info Page ([8db6ca2](https://github.com/Hypfer/Valetudo/commit/8db6ca271aa63eeded999a377bcd02c94fa6dc16))\r\n* Always log Stacktrace on unclean exit code ([e2a542c](https://github.com/Hypfer/Valetudo/commit/e2a542c95a4abd147b3bb7f1c151247334347d1b))\r\n* **vacuum.roborock:** Add backup map restore to vacuum class ([2b76965](https://github.com/Hypfer/Valetudo/commit/2b7696565b02615a2aaeb73b6bf4bd1bca7885d4))\r\n* **vacuum.roborock:** added more events without handler ([3bbdd80](https://github.com/Hypfer/Valetudo/commit/3bbdd80f99339d8a8efb638f9ae1326399a0dd00))\r\n* log process exit code + debug log process exit stacktrace ([afd7e5a](https://github.com/Hypfer/Valetudo/commit/afd7e5a95781c7429d0d5b4ee2240fc3e26dfd89))\r\n* **mqtt:** added time and area information to mqtt attributes ([9eaf848](https://github.com/Hypfer/Valetudo/commit/9eaf848ef2f25d17ac8e19702abc24bf6ce19c90))\r\n* **ui:** Added and reworked icons, fixed rendering bugs and fully enabled map dark mode ([4c181ae](https://github.com/Hypfer/Valetudo/commit/4c181aee7f9f41a1881267a5a477b1ff499c4875))\r\n* new robot + charger icon ([964b935](https://github.com/Hypfer/Valetudo/commit/964b935a21e5af62e87ec84e32a751e99106b90f))\r\n* Parse and render segments ([386c344](https://github.com/Hypfer/Valetudo/commit/386c344160e5ad17e1d9503121d3ae87abb302b0))\r\n* **mqtt:** split broker_url in multiple fields ([c41f6da](https://github.com/Hypfer/Valetudo/commit/c41f6da874373b36bc670507d24ee488e5252ee8))\r\n* Upgrade MQTT to 4.0.0 ([#518](https://github.com/Hypfer/Valetudo/issues/518)) ([6063775](https://github.com/Hypfer/Valetudo/commit/606377569cfa31eb968e69536baa07617332213b))\r\n\r\n### Bug Fixes\r\n\r\n* **api:** remove passwords from /api/get_config ([18261bb](https://github.com/Hypfer/Valetudo/commit/18261bb1680cc28a80526869c2c2a95974f9072c))\r\n* **ui:** Fixed virtual wall placement ([6724e55](https://github.com/Hypfer/Valetudo/commit/6724e5556f3350c1c3cc6d4d5f09a9e08e8f2a6b))\r\n* **ui:** Removed misleading firmware version which was actually the miio_client version ([ac757b2](https://github.com/Hypfer/Valetudo/commit/ac757b2ba126509c7c61eb7d3aa987b9ea17f95c))\r\n* **vacuum:** missing roborock onStatusChange implementation ([cd42a7e](https://github.com/Hypfer/Valetudo/commit/cd42a7ed50c5b29d586470461f1c1afd9555419f))\r\n* **vacuum.roborock:** getCurrentStatus should return a promise ([dd63d75](https://github.com/Hypfer/Valetudo/commit/dd63d75cf2c15bbc7e65e459da7b865be2a3dffd))\r\n* **vacuum.roborock:** Limit maximum amount of virtual walls according to firmware limits ([6787826](https://github.com/Hypfer/Valetudo/commit/67878263132d3138b2eeb3820ed9c69349d08aea))", + "metaData": { + "githubReleaseUrl": "https://api.github.com/repos/Hypfer/Valetudo/releases/26992913" + } + } +] \ No newline at end of file diff --git a/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/incorrectly_sorted_overview_response.json b/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/incorrectly_sorted_overview_response.json new file mode 100644 index 00000000..21313a13 --- /dev/null +++ b/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/incorrectly_sorted_overview_response.json @@ -0,0 +1,6638 @@ +[ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/35892435", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/35892435/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/35892435/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.01.0b0", + "id": 35892435, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM1ODkyNDM1", + "tag_name": "2021.01.0b0", + "target_commitish": "master", + "name": "Valetudo 2021.01.0b0", + "draft": false, + "prerelease": true, + "created_at": "2021-01-01T09:36:08Z", + "published_at": "2021-01-01T09:47:01Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/30164475", + "id": 30164475, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMwMTY0NDc1", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33117585, + "download_count": 590, + "created_at": "2021-01-01T09:47:37Z", + "updated_at": "2021-01-01T09:47:38Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.01.0b0/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.01.0b0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.01.0b0", + "body": "
\r\n \"valetudo\"\r\n

2021.01.0b0

\r\n
\r\n\r\n**Be advised: This release will break (almost) everything that you're currently using.**
\r\n\r\nConfig format, HTTP API and MQTT have changed significantly in this release.
\r\nYou will need to recreate your Zone presets as well as your Home Assistant Robot entity.\r\n\r\nMake sure to disable any Timers you might've configured before upgrading, since there's no way to delete/configure them in this release anymore!\r\n\r\nAlso, note that this release comes with fewer features than the previous, because not everything has been ported to the new structures yet.\r\n\r\n## Core rewrite (Capabilities)\r\n\r\nTo support a growing number of Vacuum Robots with different feature sets made by different Vendors, the core infrastructure\r\nof Valetudo was completely rewritten.\r\n\r\nNow, instead of having robots that inherit from other robots, there are so-called `capabilities` as an abstraction of features.
\r\nThere's always a generic base class for each feature (e.g. `GoToLocationCapability`) which is extended by multiple vendor-specific\r\nimplementations (e.g. `RoborockGoToLocationCapability`, `ViomiGoToLocationCapability` etc).\r\n\r\nThis approach completely encapsulates vendor-specific implementation details and makes them invisible for e.g. the webinterface or other\r\nusers of the HTTP API which has also been rewritten.\r\n\r\nOverall, I'm quite happy with how it turned out. Time will tell whether this abstraction was generic enough to deal with\r\nall possible vendor-specific differences.\r\n\r\n## New HTTP REST Interface\r\n\r\nAs mentioned, the REST interface was rewritten and is now an official way of communicating with Valetudo.
\r\n\r\nAll endpoints are dynamically generated according to which capabilities are available for the robot implementation Valetudo is using.\r\nFor example basic controls such as \"start\", \"stop\" or \"home\" are done via a PUT request to `/api/v2/robot/capabilities/BasicControlCapability`.\r\n\r\nTo find out more about all possible endpoints for your Valetudo instance, a meta-endpoint has also been added.
\r\nAt `/api/v2/` you will get JSON containing all endpoints as well as their accepted methods.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436664-9061f200-4c1e-11eb-8541-5c8ed6ccc4c2.png)\r\n\r\n## New MQTT Interface\r\n\r\nThe MQTT interface was also rewritten to support different subsets of capabilities.\r\nInstead of having a single topic, which contains all the information available, data is now split up onto different topics\r\nbased on capabilities.\r\n\r\nThis also means that you will have multiple entities for your robot in Home Assistant:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436641-44af4880-4c1e-11eb-8a9f-019d17398359.png)\r\n\r\nFurthermore, Wi-Fi information is now also available over MQTT so in theory, one could build a microservice which subscribes\r\nto both map and Wi-Fi data updates and build a Wi-Fi heatmap of their home by mapping the measurements to the position in the map.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436651-5f81bd00-4c1e-11eb-99f9-9efe6875d5b3.png)\r\n\r\n\r\nNote that the default identifier changed from `rockrobo` to `robot`, since Valetudo is not just dealing with Roborock anymore.
\r\nTherefore when reconfiguring this release, you may want to change that back to the old value if your setup relies on it.\r\n\r\n## New Config Schema + Location\r\n\r\nTo support different robots with different folder structures (some of them being read-only), the configuration location\r\nhad to be made configurable, which is a chicken/egg problem, because the information on where to find the configuration\r\nwould be configured within the configuration.\r\n\r\nTo solve this, Valetudo is now using the environment variable `VALETUDO_CONFIG_PATH` and defaults to `os.tmpdir()` if it isn't set.\r\n\r\nDue to the fact that the configuration schema also changed significantly, **you will need to reconfigure Valetudo on upgrade**.\r\n\r\nYou will also need to update your means of running valetudo to include this ENV variable since otherwise your configuration will vanish on each reboot.\r\nThis can be done either by building a new firmware image or copying the changes required from these commits\r\n\r\n[Roborock](https://github.com/zvldz/vacuum/commit/5981577aa8e8f75c4fbea7045bf4484066881b55)\r\n\r\n[Viomi](https://github.com/Hypfer/Valetudo/commit/923f941e76e2e41be7a714e47f3a08428d09cfd4)\r\n\r\n## Misc\r\n\r\n**Viomi note:** If you're upgrading on a Viomi, make sure to change the cloud IP used for redirection to `203.0.113.1` which is now hardcoded.
\r\nThe docs have been updated to reflect that.\r\n\r\nValetudo is now using the CalVer versioning scheme, because it better fits the constantly changing scope of the project.\r\n\r\nI'd like to especially thank @depau for his port of the Viomi robot to the new infrastructure using only the half-finished capabilities branch\r\nand no documentation whatsoever as a reference.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **vacuum.viomi:** Virtual Walls & No-Go Areas ([96462ac](https://github.com/Hypfer/Valetudo/commit/96462ac752b025a3385e31d4ea0cfbea268b207c))\r\n* Configure authorized_keys location via ENV variable ([d06520d](https://github.com/Hypfer/Valetudo/commit/d06520da114f45778527e54446eed70df38e66ba))\r\n* Viomi capabilities port ([8486f04](https://github.com/Hypfer/Valetudo/commit/8486f04fdd9176af6e4e7be684bb3eecebaa39e1))\r\n* **mqtt:** Publish ValetudoGoToLocations & ValetudoZonePresets ([76a9c52](https://github.com/Hypfer/Valetudo/commit/76a9c5234dfbcce864d70d1d6db781af86d6a98b))\r\n* **vacuum.roborock:** Add support for no-mopping zones on S5 Max and S6 ([#630](https://github.com/Hypfer/Valetudo/issues/630)) ([61902ed](https://github.com/Hypfer/Valetudo/commit/61902edd8b185d116dd27a02827866e3defd01b1))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** fix [#565](https://github.com/Hypfer/Valetudo/issues/565) ui not working with safari and basic auth ([252c22d](https://github.com/Hypfer/Valetudo/commit/252c22dc9d457aa69bdbee0829930aa156430a9b))\r\n* **vacuum.viomi:** Added model names for viomi.v8 ([20d86c3](https://github.com/Hypfer/Valetudo/commit/20d86c3c005ac78d36bab29a78946e17f163f2c3))\r\n* **vacuum.viomi:** Fix fan speed state parsing ([3ca7450](https://github.com/Hypfer/Valetudo/commit/3ca745054d3c159023edb632e198126e89d7494a))\r\n* **vacuum.viomi:** Fix invalid property access ([6da2822](https://github.com/Hypfer/Valetudo/commit/6da282201172b3fb5efa1969aac6192d5ead5842))\r\n* **vacuum.viomi:** Segments + Docs ([#600](https://github.com/Hypfer/Valetudo/issues/600)) ([89a5485](https://github.com/Hypfer/Valetudo/commit/89a5485f17e7ac68e7b8d97ae9a8381d2f0a7767))\r\n* Improved dnshack to catch all problematic dns.lookup requests ([8609612](https://github.com/Hypfer/Valetudo/commit/8609612e03bc756194982d35b4389d27557842ac))\r\n\r\n\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/29111413", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/29111413/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/29111413/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.6.1", + "id": 29111413, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI5MTExNDEz", + "tag_name": "0.6.1", + "target_commitish": "master", + "name": "Valetudo 0.6.1", + "draft": false, + "prerelease": false, + "created_at": "2020-07-30T10:49:25Z", + "published_at": "2020-07-30T10:51:41Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/23406574", + "id": 23406574, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIzNDA2NTc0", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32380902, + "download_count": 5086, + "created_at": "2020-07-30T10:52:25Z", + "updated_at": "2020-07-30T10:52:26Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.6.1/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.6.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.6.1", + "body": "
\r\n \"valetudo\"\r\n

0.6.1

\r\n
\r\n\r\nThis is merely a small fix release.\r\n\r\nWith 0.6.1, valetudo doesn't segfault anymore when using a domain name as the mqtt host.\r\nFurthermore, zones are now back to being cleaned once instead of ten times.\r\n\r\nIf you've arrived at this release and haven't seen the [0.6.0 release notes](https://github.com/Hypfer/Valetudo/releases/tag/0.6.0) yet, I strongly encourage you to do so now.\r\n\r\n\r\nAutogenerated changelog:\r\n\r\n### Features\r\n\r\n* **mqtt:** Added sw_version to mqtt autodiscovery to fix [#568](https://github.com/Hypfer/Valetudo/issues/568) ([a23d5af](https://github.com/Hypfer/Valetudo/commit/a23d5af95b7986c21e3487eb5e2d4f93c16c8ba3))\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix segfault on mqtt hostname resolution ([b2410ff](https://github.com/Hypfer/Valetudo/commit/b2410ff5eda5a67f02ff5fcad7ef7c30e498674c))\r\n* **mqtt:** Fixed [#571](https://github.com/Hypfer/Valetudo/issues/571) mqtt pause status ([8b06203](https://github.com/Hypfer/Valetudo/commit/8b06203de22871c47be97bc8e353118796636853))\r\n* **ui:** Fix mqtt settings checkboxes ([039b741](https://github.com/Hypfer/Valetudo/commit/039b7411325b74c2b4abbe58a91134fd1d1b9982))\r\n* **ui:** Restore context after drawing active zone ([4f7ec2c](https://github.com/Hypfer/Valetudo/commit/4f7ec2c44e8da163bf30c097df26a3df37380f04))\r\n* **vacuum.roborock:** Don't multiply iterations by 10 to fix [#573](https://github.com/Hypfer/Valetudo/issues/573) ([f3cc935](https://github.com/Hypfer/Valetudo/commit/f3cc9354d6da3149a69ef5476c922d97df0eb8a3))\r\n* override dns.lookup to mitigate static nodejs segfaults ([41f3e98](https://github.com/Hypfer/Valetudo/commit/41f3e981a590e76261e7d57ccff8d97b3d4b94ad))" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/28964045", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/28964045/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/28964045/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.6.0", + "id": 28964045, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI4OTY0MDQ1", + "tag_name": "0.6.0", + "target_commitish": "master", + "name": "Valetudo 0.6.0", + "draft": false, + "prerelease": false, + "created_at": "2020-07-26T17:09:00Z", + "published_at": "2020-07-26T17:15:02Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/23253232", + "id": 23253232, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIzMjUzMjMy", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32381338, + "download_count": 377, + "created_at": "2020-07-26T17:15:32Z", + "updated_at": "2020-07-26T17:15:33Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.6.0/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.6.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.6.0", + "body": "
\r\n \"valetudo\"\r\n

0.6.0

\r\n
\r\n\r\n## New Data Format\r\nI've finally found the time to rework the Map Data format as well as the robot state format.\r\nBoth previously being heavily influenced by roborock, the new and improved formats are a huge step for easier adaption\r\nof Valetudo to new Vacuums as well as implementation of new features.\r\n\r\nIn fact it has already proven itself in other work that has been done for this release and decreased memory pressure quite a bit.\r\n\r\nThis change is also of course a **breaking change**.\r\nMake sure to update any dependant applications/integrations/etc. as well.\r\n\r\n\r\n## (Initial) Support for many more Vacuums + a new Vendor\r\nThe list of _technically_ supported roborock vacuums has grown quite a bit.\r\nEspecially since Dennis released his guide on how to root the S6 which you can find [here](https://www.youtube.com/playlist?list=PL9PoaNtZCJRZc61c792VCr_I6jQK_IdSb).\r\n\r\nFurthermore, Valetudo has also received initial support for a dreame-made xiaomi vacuum robot: **Xiaomi MiJia 1C**\r\n\r\nThere's no map parsing yet though. Contributions much appreciated.\r\n\r\nPlease note that there's no dreame rooting guide available yet.\r\nThese release notes will be updated when it becomes available.\r\n\r\n\r\n## Segment Cleaning via the Web and MQTT\r\nOwners of room-cleaning capable roborock vacuums can now use Valetudo to do so.\r\n\r\nSimply select the segments you want to clean and start the cleanup like you would start a zoned cleanup.\r\nCurrently cleaned segments are denoted by a rotated icon.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485125-f3ff3980-cf73-11ea-87f2-dbe85508c5e1.png)\r\n\r\nIf you zoom in on a segment marker, it will display both it's segment id as well as the segments' area in `m²`.\r\nThe latter also being a benefit of the new Map Data format.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485127-fd88a180-cf73-11ea-819c-cdd60b3b062c.png)\r\n\r\nSegment cleaning is of course also available via MQTT.\r\nCheck out the updated Home Assistant docs for an example on how to use it.\r\n\r\nSince this is a generic implementation, support for other vacuum vendors will follow.\r\nYou just need to open a PR for that.\r\n\r\n### UI enhancements\r\nDynamic zones now display their size in meters which is also a helpful addition if you quickly want to measure something without leaving your desk.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485140-109b7180-cf74-11ea-82cf-23da553ae201.png)\r\n\r\nFurthermore, it is now impossible for you to break the map by zooming out too far.\r\n\r\n\r\n## Misc\r\n* The map renderer has been updated by @aa-ko to always color adjacent segments in a different color thanks to math™\r\n* MQTT supports client certificate authentication thanks to @mqtt-fan\r\n\r\nand of course there's the autogenerated changelog:\r\n\r\n### Features\r\n\r\n* Segment cleanup via WebUI + MQTT ([f14f6cc](https://github.com/Hypfer/Valetudo/commit/f14f6cc253766e11f9a95dfe6cbff7cfafc73e70))\r\n* **entities.state:** Added Charging/Charged/Discharging status to BatteryStateAttribute ([97b5cdf](https://github.com/Hypfer/Valetudo/commit/97b5cdfd93bc4f562752a0a890f1b972b620119c))\r\n* **mqtt:** add support for client certificate ([#549](https://github.com/Hypfer/Valetudo/issues/549)) ([33f94ec](https://github.com/Hypfer/Valetudo/commit/33f94ec6614d15876b5e1f77446500001185b317))\r\n* **roborock:** Experimental support for even more roborock vacuums ([2450ceb](https://github.com/Hypfer/Valetudo/commit/2450ceb3f5cb2653ee32dd3d5ef0fbf2c7e69645))\r\n* **ui:** Added zone size display, proper icon/text scaling and limited scaling ([6b61ca8](https://github.com/Hypfer/Valetudo/commit/6b61ca816f377c07c784cb9075be43e838ecb405))\r\n* **ui:** Use math (four color theorem) to properly color segments ([d462f65](https://github.com/Hypfer/Valetudo/commit/d462f65e8fe57de43daf098f295d987a11990f9d))\r\n* **vacuum.dreame:** Initial basic support for the dreame.vacuum.mc1808 ([f73c7c6](https://github.com/Hypfer/Valetudo/commit/f73c7c61dfe786131704fa90fd93e632263b982d))\r\n* **vacuum.viomi:** add support for viomi.vacuum.v8 + mop enhancements ([#543](https://github.com/Hypfer/Valetudo/issues/543)) ([17bb01e](https://github.com/Hypfer/Valetudo/commit/17bb01efe088a494563f6037076ade6e13c8c553)), closes [#541](https://github.com/Hypfer/Valetudo/issues/541) [#538](https://github.com/Hypfer/Valetudo/issues/538) [#548](https://github.com/Hypfer/Valetudo/issues/548)\r\n* Experimental support(?) for S6 MaxV ([88de212](https://github.com/Hypfer/Valetudo/commit/88de212274872eca0ca97c3b0dfadb70d2a4baa5))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **entities.map:** Fixed MapLayer area calculation ([ac86c84](https://github.com/Hypfer/Valetudo/commit/ac86c84c8fa75408b52067306f7e0c4a201e9725))\r\n* **mqtt:** Check DNS resolution before connecting to mqtt broker to fix [#563](https://github.com/Hypfer/Valetudo/issues/563) ([38a0af8](https://github.com/Hypfer/Valetudo/commit/38a0af82db66428b8a6e7340dfaac394bbfcb2ac))\r\n* **ui:** Default to colorIndex 0 if solver can't find the segment in its graph ([e1565d0](https://github.com/Hypfer/Valetudo/commit/e1565d073642c87c084d93c56e031ebbec1160bd))\r\n* **ui:** Fix map coloring ([#567](https://github.com/Hypfer/Valetudo/issues/567)) ([890120c](https://github.com/Hypfer/Valetudo/commit/890120c76930bb8941459a7e0d1baa0af8577d83))\r\n* **ui:** Fixed zone dimensions ([0ca13e3](https://github.com/Hypfer/Valetudo/commit/0ca13e328d6e4943a444f750eb35365748dd5523))\r\n* **vacuum.roborock:** Changed set_lab_status payload for S6 to fix [#540](https://github.com/Hypfer/Valetudo/issues/540) ([19e141e](https://github.com/Hypfer/Valetudo/commit/19e141efc0b6e9f4798a9bff2482feaa10f3772f))\r\n* **vacuum.roborock:** Fix map parsing failing for maps with no image data ([f187906](https://github.com/Hypfer/Valetudo/commit/f1879064b15ea978df32a12f8a23b346ba2e3e39))\r\n* **vacuum.viomi:** Hackishly fixed map parsing for viomi v6 + fan speed settings for all viomi ([ffbb8e7](https://github.com/Hypfer/Valetudo/commit/ffbb8e75ffc4ce06bab6baa6f7328877cf66659b))\r\n* **vacuum.viomi:** Hackishly fixed path + angle ([fdd80d2](https://github.com/Hypfer/Valetudo/commit/fdd80d24c577a66ecb358f838e675126abd0c084))\r\n\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/27531929", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/27531929/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/27531929/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.5.3", + "id": 27531929, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI3NTMxOTI5", + "tag_name": "0.5.3", + "target_commitish": "master", + "name": "Valetudo 0.5.3", + "draft": false, + "prerelease": false, + "created_at": "2020-06-14T13:39:35Z", + "published_at": "2020-06-14T14:04:32Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/21736930", + "id": 21736930, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIxNzM2OTMw", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32810703, + "download_count": 3114, + "created_at": "2020-06-14T14:05:08Z", + "updated_at": "2020-06-14T14:05:10Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.5.3/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.5.3", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.5.3", + "body": "
\r\n \"valetudo\"\r\n

0.5.3

\r\n
\r\n\r\nWith this release, Valetudo is upgraded to a stripped NodeJS 14.4.0 runtime, which brings both smaller binary size as well as enhanced performance.\r\n\r\nFurthermore, the long awaited cleaning of multiple zones via the Web Interface is finally here.\r\n\r\nIf you had root access to your Roborock S6/T6/S4/T4 or M1S, you could now use Valetudo as well.\r\nThere will be a guide on how to do that in the near future. Be aware, that no new features beyond those which are already available on the S5 are supported yet.\r\n\r\nIf you're a Valetudo developer, your life has become a lot easier with 0.5.3.\r\nRobot Model, Webserver Port and all the relevant settings are now configured via the config.json. No more messing around with ENV variables.\r\n\r\n\r\nHere's the autogenerated changelog:\r\n\r\n### Features\r\n\r\n* Initial Support for Roborock T/S4 and M1S ([24579f7](https://github.com/Hypfer/Valetudo/commit/24579f7acd98e276f4a85344919c4e8a8d356381))\r\n* Try to write a backup in case we're overwriting an invalid configuration file. ([#537](https://github.com/Hypfer/Valetudo/issues/537)) ([e738491](https://github.com/Hypfer/Valetudo/commit/e7384917354efa7e1d1b730b746966d4e46d87f2))\r\n* **ui:** Allow select of multiple zones for zone clean ([#535](https://github.com/Hypfer/Valetudo/issues/535)) ([1a29155](https://github.com/Hypfer/Valetudo/commit/1a29155094cdd76e02c5cbea28739d4637d90c00))\r\n* Added debug config option to continuously log memory usage ([d96eb15](https://github.com/Hypfer/Valetudo/commit/d96eb15c8f299ff49d98f9d6661c6f44225bc633))\r\n* Added option to fully configure model information via the config file ([#497](https://github.com/Hypfer/Valetudo/issues/497)) ([e241c1d](https://github.com/Hypfer/Valetudo/commit/e241c1d9b0dd1870f759fd8ebd1f1e7ec1f7cf61))\r\n* Initial support for S6 T6 and S5 Max ([f417b4d](https://github.com/Hypfer/Valetudo/commit/f417b4de3f27b0664552471c05adb220592f5c51))\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Removed unnecessary availability topic mitigation ([b76ce14](https://github.com/Hypfer/Valetudo/commit/b76ce144b4a3eb920a1dbab1991c83cf87ee7967))\r\n* Always assume embedded operation unless specified otherwise ([#536](https://github.com/Hypfer/Valetudo/issues/536)) ([7585f86](https://github.com/Hypfer/Valetudo/commit/7585f86e9fb1ec196b4b710454e1414673482081))\r\n* Removed useless app_get_locale functionality to fix [#532](https://github.com/Hypfer/Valetudo/issues/532) ([ffc06d6](https://github.com/Hypfer/Valetudo/commit/ffc06d65ba788cfbc3aee33b8e3d9d9e3fe647f9))\r\n* Simplify embedded logic now that 'auto' is gone. [#536](https://github.com/Hypfer/Valetudo/issues/536) ([b9097a6](https://github.com/Hypfer/Valetudo/commit/b9097a6f128aa947e4bb4a05fb3d79453f0f9e71))\r\n* **mqtt:** Update availability topic on each attribute topic update to fix false offline status ([af69673](https://github.com/Hypfer/Valetudo/commit/af696739d3119fbd84b1e9ba20b50b3fedce7a12))\r\n* **ui:** Fix [#527](https://github.com/Hypfer/Valetudo/issues/527) not working close and cancel buttons in timer settings ([e2ea1ce](https://github.com/Hypfer/Valetudo/commit/e2ea1ce212c4f85bba492dc273c6b7e75f4768b8))\r\n* **ui:** Hide forbidden zones editor menu item on gen 1 ([#382](https://github.com/Hypfer/Valetudo/issues/382)) ([32e9416](https://github.com/Hypfer/Valetudo/commit/32e94168fb3141fb49721be6019e0611690f3292))" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/26992913", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/26992913/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/26992913/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.5.2", + "id": 26992913, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI2OTkyOTEz", + "tag_name": "0.5.2", + "target_commitish": "master", + "name": "Valetudo 0.5.2", + "draft": false, + "prerelease": false, + "created_at": "2020-05-28T14:06:02Z", + "published_at": "2020-05-28T14:15:20Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/21144297", + "id": 21144297, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIxMTQ0Mjk3", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 48594687, + "download_count": 1089, + "created_at": "2020-05-28T14:15:57Z", + "updated_at": "2020-05-28T14:15:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.5.2/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.5.2", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.5.2", + "body": "
\r\n \"valetudo\"\r\n

0.5.2

\r\n
\r\n\r\nThis release contains a new and reworked Iconset for the map view as well as support for displaying detected rooms.\r\n\r\nFurthermore, these are the first release notes which feature semi-autogenerated changelogs utilizing [Conventional Commits](https://www.conventionalcommits.org)\r\n### Features\r\n\r\n* **mqtt:** Add availability as last will ([b196625](https://github.com/Hypfer/Valetudo/commit/b196625ac73e4932324b2bd2cf487790d6758711))\r\n* **ui:** Display Model information in Info Page ([8db6ca2](https://github.com/Hypfer/Valetudo/commit/8db6ca271aa63eeded999a377bcd02c94fa6dc16))\r\n* Always log Stacktrace on unclean exit code ([e2a542c](https://github.com/Hypfer/Valetudo/commit/e2a542c95a4abd147b3bb7f1c151247334347d1b))\r\n* **vacuum.roborock:** Add backup map restore to vacuum class ([2b76965](https://github.com/Hypfer/Valetudo/commit/2b7696565b02615a2aaeb73b6bf4bd1bca7885d4))\r\n* **vacuum.roborock:** added more events without handler ([3bbdd80](https://github.com/Hypfer/Valetudo/commit/3bbdd80f99339d8a8efb638f9ae1326399a0dd00))\r\n* log process exit code + debug log process exit stacktrace ([afd7e5a](https://github.com/Hypfer/Valetudo/commit/afd7e5a95781c7429d0d5b4ee2240fc3e26dfd89))\r\n* **mqtt:** added time and area information to mqtt attributes ([9eaf848](https://github.com/Hypfer/Valetudo/commit/9eaf848ef2f25d17ac8e19702abc24bf6ce19c90))\r\n* **ui:** Added and reworked icons, fixed rendering bugs and fully enabled map dark mode ([4c181ae](https://github.com/Hypfer/Valetudo/commit/4c181aee7f9f41a1881267a5a477b1ff499c4875))\r\n* new robot + charger icon ([964b935](https://github.com/Hypfer/Valetudo/commit/964b935a21e5af62e87ec84e32a751e99106b90f))\r\n* Parse and render segments ([386c344](https://github.com/Hypfer/Valetudo/commit/386c344160e5ad17e1d9503121d3ae87abb302b0))\r\n* **mqtt:** split broker_url in multiple fields ([c41f6da](https://github.com/Hypfer/Valetudo/commit/c41f6da874373b36bc670507d24ee488e5252ee8))\r\n* Upgrade MQTT to 4.0.0 ([#518](https://github.com/Hypfer/Valetudo/issues/518)) ([6063775](https://github.com/Hypfer/Valetudo/commit/606377569cfa31eb968e69536baa07617332213b))\r\n\r\n### Bug Fixes\r\n\r\n* **api:** remove passwords from /api/get_config ([18261bb](https://github.com/Hypfer/Valetudo/commit/18261bb1680cc28a80526869c2c2a95974f9072c))\r\n* **ui:** Fixed virtual wall placement ([6724e55](https://github.com/Hypfer/Valetudo/commit/6724e5556f3350c1c3cc6d4d5f09a9e08e8f2a6b))\r\n* **ui:** Removed misleading firmware version which was actually the miio_client version ([ac757b2](https://github.com/Hypfer/Valetudo/commit/ac757b2ba126509c7c61eb7d3aa987b9ea17f95c))\r\n* **vacuum:** missing roborock onStatusChange implementation ([cd42a7e](https://github.com/Hypfer/Valetudo/commit/cd42a7ed50c5b29d586470461f1c1afd9555419f))\r\n* **vacuum.roborock:** getCurrentStatus should return a promise ([dd63d75](https://github.com/Hypfer/Valetudo/commit/dd63d75cf2c15bbc7e65e459da7b865be2a3dffd))\r\n* **vacuum.roborock:** Limit maximum amount of virtual walls according to firmware limits ([6787826](https://github.com/Hypfer/Valetudo/commit/67878263132d3138b2eeb3820ed9c69349d08aea))" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/73473495/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.08.0", + "id": 73473495, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4EYR3X", + "tag_name": "2022.08.0", + "target_commitish": "master", + "name": "Valetudo 2022.08.0", + "draft": false, + "prerelease": false, + "created_at": "2022-08-02T17:45:28Z", + "published_at": "2022-08-02T19:20:05Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482161", + "id": 73482161, + "node_id": "RA_kwDOCGKICM4EYT-x", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31579356, + "download_count": 309, + "created_at": "2022-08-02T19:26:01Z", + "updated_at": "2022-08-02T19:26:02Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482970", + "id": 73482970, + "node_id": "RA_kwDOCGKICM4EYULa", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14444544, + "download_count": 1, + "created_at": "2022-08-02T19:35:53Z", + "updated_at": "2022-08-02T19:35:54Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482158", + "id": 73482158, + "node_id": "RA_kwDOCGKICM4EYT-u", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27935884, + "download_count": 612, + "created_at": "2022-08-02T19:25:57Z", + "updated_at": "2022-08-02T19:25:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482159", + "id": 73482159, + "node_id": "RA_kwDOCGKICM4EYT-v", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27935884, + "download_count": 190, + "created_at": "2022-08-02T19:25:59Z", + "updated_at": "2022-08-02T19:26:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482963", + "id": 73482963, + "node_id": "RA_kwDOCGKICM4EYULT", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11321896, + "download_count": 2, + "created_at": "2022-08-02T19:35:51Z", + "updated_at": "2022-08-02T19:35:52Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482959", + "id": 73482959, + "node_id": "RA_kwDOCGKICM4EYULP", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11321728, + "download_count": 11, + "created_at": "2022-08-02T19:35:50Z", + "updated_at": "2022-08-02T19:35:51Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482979", + "id": 73482979, + "node_id": "RA_kwDOCGKICM4EYULj", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 926, + "created_at": "2022-08-02T19:35:55Z", + "updated_at": "2022-08-02T19:35:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.08.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.08.0", + "body": "
\r\n \"valetudo\"\r\n

2022.08.0

\r\n
\r\n\r\nNew firmwares for dreame robots and some bugfixes\r\n\r\n## New dreame firmwares\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454333-356ba835-4f69-4041-a720-7c2d97eb3209.png)\r\n\r\nIt took quite a lot of time and work, but now we're proud to announce that we've managed to get newer dreame firmwares\r\nto work rooted and with Valetudo. A big thank you to everyone who helped during the beta test!\r\n\r\n**Important**: That does **not** mean that these newer firmwares have become rootable.\r\nYou will need to have an already rooted robot to install these latest rooted firmwares.\r\n\r\nTo update, head over to the dustbuilder at [https://builder.dontvacuum.me/](https://builder.dontvacuum.me/) to build and install a new image.\r\nMake sure to update Valetudo **before** updating the firmware.\r\n\r\n## Other dreame news\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454516-57ef159d-d97e-458a-815d-97a60db689ba.png)\r\n\r\nStarting today, every firmware image built with the dustbuilder will contain a fix for the vanishing Valetudo issue,\r\nwhich occasionally left people with a rooted robot but no Valetudo.\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454599-cab62e88-6179-43da-b907-6ac7236c7d17.png)\r\n\r\nIf a user starts a new mapping pass, the fresh map should now appear instantly.\r\nFurthermore, issues with frozen maps either during cleanups or when editing segments were fixed as well.\r\n\r\n## Robot Coverage View\r\n\r\n[](https://user-images.githubusercontent.com/974410/182455081-879226c5-aa14-4160-bc2f-f9c0f2a2d3d3.png)\r\n\r\n\r\nThe UI has been extended with a view displaying a much thicker path.\r\nThis can be used to better see which areas of the map have been cleaned.\r\n\r\nWhether this view will stick around long-term is yet to be decided. It was pretty easy to implement though.\r\nFeel free to leave your feedback in the comments.\r\n\r\n\r\n## The usual\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454845-cc693f37-a126-4978-b2f0-5c9f77a970d8.png)\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Misc\r\n\r\nThis changelog features artworks generated by DALL-E 2 because I thought it would be neat to have something to look at.\r\nUnfortunately, it doesn't like generating artworks featuring lidar-based vacuum robots (yet?)\r\n\r\nI hope they've nonetheless enhanced your changelog reading experience.\r\nFeel free to leave feedback on that as well.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n- **vendor.dreame**: Newer D9 Firmwares also have a sensor consumable [`17c0d27`](http://github.com/Hypfer/Valetudo/commit/17c0d27fb69b92b5a8028d6bab489e5b97fb4537)\r\n- **ui**: Trim whitespaces when renaming segments [`39d72f4`](http://github.com/Hypfer/Valetudo/commit/39d72f4e787108c75a1cb501995151fb19b4d8b1)\r\n- **ui**: Add robot coverage map [`a9661a0`](http://github.com/Hypfer/Valetudo/commit/a9661a02bcbe642c3e7de46be4015f9532e4ce49)\r\n- **vendor.dreame**: Add mop-only quirk for newer firmwares [`a33afe3`](http://github.com/Hypfer/Valetudo/commit/a33afe351c1b868919bc7b036e2e02a05b8e581c)\r\n- **vendor.dreame**: Add Mop Dock UV-C Toggle Quirk [`7ce4abe`](http://github.com/Hypfer/Valetudo/commit/7ce4abe7353567fd3db6a7a9cc1c767d68a9db93)\r\n\r\n### Fixes\r\n\r\n- **vendor.dreame**: Add support for more features of newer firmwares [`b74c281`](http://github.com/Hypfer/Valetudo/commit/b74c281e1727ca2a007d96915c6fceb3f386bd28)\r\n- **ui**: Add margin to apple touch icon (#1526) [`dc72ef0`](http://github.com/Hypfer/Valetudo/commit/dc72ef05319799020a504a3b20e0b7e6092984ee)\r\n- **vendor.dreame**: Ignore empty maps [`99aad7b`](http://github.com/Hypfer/Valetudo/commit/99aad7be8b20c9459e849dd6b9ce8df5171b9690)\r\n- **networkadvertisement**: Don't crash the process on ssdp multicast membership errors [`bfb96c0`](http://github.com/Hypfer/Valetudo/commit/bfb96c09aa2bc0ff9e151fb6cdab4ac5bbd58a36)\r\n- **miio**: Allow two simultaneous FDS uploads [`6e26374`](http://github.com/Hypfer/Valetudo/commit/6e26374c32e9fe33c93f4f91c189f917c5f884a5)\r\n- **vendor.dreame**: Switch to async map preprocessing to not block the event loop [`3b5743b`](http://github.com/Hypfer/Valetudo/commit/3b5743b41264c3d8d36d8cc0a75da30e90bb7338)\r\n- **miio**: Further improve fds upload timeout handling [`8c1ba9e`](http://github.com/Hypfer/Valetudo/commit/8c1ba9ea2fcc980bf726a4678902afd2577a0191)\r\n- **miio**: Gracefully handle connectivity issues when receiving fds uploads [`8aab94f`](http://github.com/Hypfer/Valetudo/commit/8aab94fa2ab01479997968904e9312fbc8111a83)\r\n- **vendor.dreame**: Ignore timezone update message [`5ecf7fa`](http://github.com/Hypfer/Valetudo/commit/5ecf7fa0842c498a2ad8abfd792a71b420ce34bf)\r\n- **ui**: Allow sending home basic control command while paused [`0dfb4ba`](http://github.com/Hypfer/Valetudo/commit/0dfb4ba59bd1334f994beea211ac17fdf5323f1f)\r\n- **vendor.dreame**: Fix maps for newer firmwares [`5f67103`](http://github.com/Hypfer/Valetudo/commit/5f6710348fd304046a201c2423490555e44d3b20)\r\n- **webserver**: Fix openapi schema for MapSegmentEditCapability [`f106735`](http://github.com/Hypfer/Valetudo/commit/f106735cbae0eed2ebfebaa6843c7da976c5127e)\r\n\r\n### Refactoring\r\n\r\n- **webserver**: Response cleanup [`839310a`](http://github.com/Hypfer/Valetudo/commit/839310ab0941941d68ea4ba0c1fbfc17b8924443)\r\n- **webserver**: Actually make use of the openapi schema validation [`6e2d2e1`](http://github.com/Hypfer/Valetudo/commit/6e2d2e1904040aa891dda5d35909654553e04eb7)\r\n- Introduce RobotFirmwareError and refactor CapabilityRouter for unified error logs [`1d2ad47`](http://github.com/Hypfer/Valetudo/commit/1d2ad47e9d49eac71f0621d2aa0444acf871acec)\r\n\r\n### Chores\r\n\r\n- **release**: 2022.08.0 [`214b5c0`](http://github.com/Hypfer/Valetudo/commit/214b5c0c11c0cf70fa56ff915fda05e064a18355)\r\n- Minor cleanup [`9356ba8`](http://github.com/Hypfer/Valetudo/commit/9356ba8e19825a1602cd842db9487389aa553ccf)\r\n- **vendor.dreame**: Fix tests [`15eee37`](http://github.com/Hypfer/Valetudo/commit/15eee3749e41fc77ddf62fbaf8fc348f8d872672)\r\n- **mqtt**: Minor cleanup [`4ae1d03`](http://github.com/Hypfer/Valetudo/commit/4ae1d0365d2b54f9d27c49caf5e38b915ff47e4c)\r\n- Minor misc cleanups [`7bf3c87`](http://github.com/Hypfer/Valetudo/commit/7bf3c87db34a8f27624fe735737a4ccd17fbf8bc)\r\n- Add eslintrc flavors [`b3843f8`](http://github.com/Hypfer/Valetudo/commit/b3843f8bd3c95346735d674f7df4543ff5f78b81)\r\n- Add close_threads github workflow [`e10313d`](http://github.com/Hypfer/Valetudo/commit/e10313dc75a0f7867d64c195fbd9ef69ca3b199b)\r\n- **ui**: Add missing rel=\"noopener\" tag to menu bar [`a7e6920`](http://github.com/Hypfer/Valetudo/commit/a7e6920c7924b5db43b9eb086a434fddaa276d75)\r\n- **build**: Bump to NodeJS v18.5.0 [`66712f9`](http://github.com/Hypfer/Valetudo/commit/66712f91dd3f16c24b0b22b334a37ecfeb983df9)\r\n- Update wording in VoicepackHelp.ts [`05a6b89`](http://github.com/Hypfer/Valetudo/commit/05a6b89848b5c1e9a04f4a822da58e03cd89b5f8)\r\n- Update issue template [`cebca05`](http://github.com/Hypfer/Valetudo/commit/cebca057ceb05d202f3f76211a2e63290f39b002)", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1537", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495/reactions", + "total_count": 14, + "+1": 0, + "-1": 0, + "laugh": 1, + "hooray": 0, + "confused": 0, + "heart": 10, + "rocket": 3, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/69327065/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.06.0", + "id": 69327065, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4EIdjZ", + "tag_name": "2022.06.0", + "target_commitish": "master", + "name": "Valetudo 2022.06.0", + "draft": false, + "prerelease": false, + "created_at": "2022-06-13T18:02:35Z", + "published_at": "2022-06-13T18:16:34Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368217", + "id": 68368217, + "node_id": "RA_kwDOCGKICM4EEzdZ", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31454413, + "download_count": 726, + "created_at": "2022-06-13T18:22:05Z", + "updated_at": "2022-06-13T18:22:06Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368623", + "id": 68368623, + "node_id": "RA_kwDOCGKICM4EEzjv", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14405897, + "download_count": 5, + "created_at": "2022-06-13T18:29:48Z", + "updated_at": "2022-06-13T18:29:49Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368213", + "id": 68368213, + "node_id": "RA_kwDOCGKICM4EEzdV", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27827381, + "download_count": 1623, + "created_at": "2022-06-13T18:22:02Z", + "updated_at": "2022-06-13T18:22:03Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368215", + "id": 68368215, + "node_id": "RA_kwDOCGKICM4EEzdX", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27827381, + "download_count": 428, + "created_at": "2022-06-13T18:22:03Z", + "updated_at": "2022-06-13T18:22:04Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368622", + "id": 68368622, + "node_id": "RA_kwDOCGKICM4EEzju", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11299441, + "download_count": 13, + "created_at": "2022-06-13T18:29:47Z", + "updated_at": "2022-06-13T18:29:48Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368620", + "id": 68368620, + "node_id": "RA_kwDOCGKICM4EEzjs", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11299577, + "download_count": 10, + "created_at": "2022-06-13T18:29:46Z", + "updated_at": "2022-06-13T18:29:47Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368624", + "id": 68368624, + "node_id": "RA_kwDOCGKICM4EEzjw", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2170, + "created_at": "2022-06-13T18:29:50Z", + "updated_at": "2022-06-13T18:29:50Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.06.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.06.0", + "body": "
\r\n \"valetudo\"\r\n

2022.06.0

\r\n
\r\n\r\nAnother maintenance release featuring upgraded dependencies, refactoring and some bugfixes\r\n\r\n## Bonjour/mDNS fixes\r\n\r\nUsers can now discover multiple robots of the same model in their home network:\r\n\r\n[](https://user-images.githubusercontent.com/974410/173417472-ca0d279e-05f2-4980-9f1b-d46af2897882.png)\r\n\r\nApparently, the Bonjour service name needs to be unique or else _some_ bonjour implementations will deduplicate it.\r\nBecause of this, the companion app only displayed one robot even though there were multiple ones on the network.\r\n\r\n\r\n## Nightly build enhancements\r\n\r\nThe nightly update provider will now display a changelog of all changes since the last release.\r\n\r\n[](https://user-images.githubusercontent.com/974410/173417506-3f156a64-4130-48cc-ab21-6bdabf747707.png)\r\n\r\nYou can switch to the nightly update provider by changing the `updater.updateProvider.type` in your `valetudo_config.json` to `github_nightly`.\r\nPlease keep in mind that nightly builds might be unstable. They should only be used by people that know what they're doing and are willing to handle occasional breakage.\r\n\r\n## UI Improvements\r\n\r\nMultiple issues that caused the live map to stop refreshing have been fixed.\r\n\r\nChecking back on the Valetudo UI after having it in a background tab for a while during a cleanup will now display the latest map data.\r\nAlso, running Valetudo behind a flaky reverse proxy should not interfere with the SSE connection anymore.\r\n\r\n## Boring chores\r\n\r\nThis release features plenty of dependency upgrades, the migration to create-react-app 5 and more.\r\nIt also contains a lot of refactorings that should further improve the code quality.\r\n\r\nWhile all that doesn't offer any directly noticeable benefits to the user, it is worth noting nonetheless, as keeping the project well-maintained is vital to its longevity.\r\n\r\nThe exciting stuff will hopefully happen later this year :-)\r\n\r\n\r\nApart from code changes, I've been busy figuring out how to build statically linked recent versions of common tools that might be added to our robot firmware images. It's all done using dockerfiles to make it easy to understand, document and reproduce.\r\nInterestingly, information on the internet do to just that is rather sparse so this might also be useful to someone with a different embedded use-case.\r\n\r\nYou can find that stuff here: [https://github.com/Hypfer/valetudo-misc](https://github.com/Hypfer/valetudo-misc)\r\nIf you're missing a tool there please let me know\r\n\r\n## Other news\r\n\r\nAs mentioned in the previous release notes, we're currently still pretty busy figuring out how to root new robots and/or firmware versions.\r\nSince that worked well in the past, I shall continue mentioning it here.\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\nThe autogenerated changelog generation has been updated to be even better and less of a hassle to use.\r\nEnjoy\r\n\r\n### Breaking Changes\r\n\r\n- **timers**: Updating timers should be a PUT instead of a POST [`9c57f0c`](http://github.com/Hypfer/Valetudo/commit/9c57f0c6db069eae796b6fb68766ca2f5d16c907)\r\n\r\n### Features\r\n\r\n- **updater**: Add changelog to nightly update provider [`3a874db`](http://github.com/Hypfer/Valetudo/commit/3a874db088f445d03e71f08f9125ac5ce9cbc4d6)\r\n- **mqtt**: Deduplicate mqtt map data as well [`269aa30`](http://github.com/Hypfer/Valetudo/commit/269aa3004f3925e26afe66139109b201133afcfe)\r\n\r\n### Fixes\r\n\r\n- **networkadvertisement**: Bonjour service names need to be unique [`956487e`](http://github.com/Hypfer/Valetudo/commit/956487ee1f06e571371eb237aa87a86e50969356)\r\n- **ui**: Remove obsolete css statement [`6793c67`](http://github.com/Hypfer/Valetudo/commit/6793c67eb12bb4bf90a83adfb22c0dca01b741ef)\r\n- **ui**: Fix map SSE EventSource not reconnecting on error [`d84efd5`](http://github.com/Hypfer/Valetudo/commit/d84efd586122aff81cab8524517cc2c5a0b7b37b)\r\n- **ui**: fix circular chunk dependency [`271e53c`](http://github.com/Hypfer/Valetudo/commit/271e53c6fa6aa659f94e14e4fd10934901857b82)\r\n- **ui**: Fix map not properly redrawing on visibility state change [`bd77d2e`](http://github.com/Hypfer/Valetudo/commit/bd77d2e22adc33813fb4ab5e3897e6b58d5340e2)\r\n- **utils**: hash key instead of value (#1503) [`bae09ab`](http://github.com/Hypfer/Valetudo/commit/bae09ab9f1d09ca98cd54272aab96afac05e52cb)\r\n- **miio**: Fix ERR_HTTP_HEADERS_SENT exception (#1501) [`a47f3b9`](http://github.com/Hypfer/Valetudo/commit/a47f3b9c97c4abd3f8a5c9a61750312ffce05800)\r\n- **vendor.dreame**: The STYTJO6ZHM does not feature a watertank [`9b75974`](http://github.com/Hypfer/Valetudo/commit/9b7597420084cd579ce9990667d1118c8d5a27ed)\r\n- **vendor.roborock**: copy statusflag from previous state on state update (#1497) [`84de0ef`](http://github.com/Hypfer/Valetudo/commit/84de0ef9d869f5150c504fa13bcd49956c71bf4c)\r\n\r\n### Refactoring\r\n\r\n- **updater**: Move type constant to update providers [`5ca525e`](http://github.com/Hypfer/Valetudo/commit/5ca525ec8f6899f577cc21a616e0fbcf26b2c76e)\r\n- **vendor.roborock**: Improve logic legibility in ZoneCleaningCapability [`560a50e`](http://github.com/Hypfer/Valetudo/commit/560a50edfca23c6a80378f0bed9cc3c1a533d8bc)\r\n- **ui**: Port map color finder to typescript [`6c1b126`](http://github.com/Hypfer/Valetudo/commit/6c1b126138f4e8b751913eb4d4c411a22d7f492c)\r\n- **ui**: Make use of webpack 5 and convert the map layer render webworker to typescript [`d17b66d`](http://github.com/Hypfer/Valetudo/commit/d17b66d6be3381a9c14cf3dfe118f560bd5ed408)\r\n- **ui**: Port map touch handling to typescript [`9548012`](http://github.com/Hypfer/Valetudo/commit/95480129dbf4d72eb2e87a7a0ac1d9c18e429369)\r\n- **ui**: Do not monkey patch the 2d context of the map renderer [`212e4f5`](http://github.com/Hypfer/Valetudo/commit/212e4f541b14a9d5a55d4fe10d54a5c173fc2800)\r\n- **ui**: Remove unnecessary nullchecks in the map component [`96ba8cf`](http://github.com/Hypfer/Valetudo/commit/96ba8cf83f6a4d0c9235359b77414e0cbd70d658)\r\n- **vendor.dreame**: Improve mop dock settings handling [`412a65a`](http://github.com/Hypfer/Valetudo/commit/412a65ab4c5cf3c7ba061ea59d61c88c1d345e34)\r\n- **miio**: Unify previously duplicated map poll code [`356d144`](http://github.com/Hypfer/Valetudo/commit/356d144b9cd15840ccd32c2b2a0a21cb0fa011a8)\r\n\r\n### Chores\r\n\r\n- **release**: 2022.06.0 [`3504a4a`](http://github.com/Hypfer/Valetudo/commit/3504a4a6974afe4ff35d52ab1d676104a77ca86b)\r\n- Fix nightly changelog generation [`2c73de3`](http://github.com/Hypfer/Valetudo/commit/2c73de3cb7d4a564c4b3306e37a5bfa3f3755ff2)\r\n- Minor misc code cleanups [`3c3c561`](http://github.com/Hypfer/Valetudo/commit/3c3c5617dfac3b8a48f43e695c005d95593857ac)\r\n- More dependency changes [`0becd44`](http://github.com/Hypfer/Valetudo/commit/0becd4490b397539de3a8a6593e547cbc4fcba15)\r\n- Delete obsolete Events.js [`5176cce`](http://github.com/Hypfer/Valetudo/commit/5176cce43a9dff88d7acfc39038b3b4e7c303a86)\r\n- Bump dependencies [`8ae420c`](http://github.com/Hypfer/Valetudo/commit/8ae420c1576331dd26acfdf2d3e7a83ff05ebf06)\r\n- bump GitHub codeql action to v2 [`643dcc5`](http://github.com/Hypfer/Valetudo/commit/643dcc581c556797bc6b989dde25671e9ad55378)\r\n- **vendor.dreame**: Add documentation on the mop dock settings data format [`881f717`](http://github.com/Hypfer/Valetudo/commit/881f717ac37505c7f113b6c82f6754837e8a9d43)\r\n- typo fix [`41055d1`](http://github.com/Hypfer/Valetudo/commit/41055d1c9a4615fe9664487e66ec7e9a81773428)", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1516", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065/reactions", + "total_count": 7, + "+1": 1, + "-1": 0, + "laugh": 0, + "hooray": 6, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/66310630/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.05.1", + "id": 66310630, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4D89Hm", + "tag_name": "2022.05.1", + "target_commitish": "master", + "name": "Valetudo 2022.05.1", + "draft": false, + "prerelease": false, + "created_at": "2022-05-08T09:21:48Z", + "published_at": "2022-05-08T09:27:12Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843029", + "id": 64843029, + "node_id": "RA_kwDOCGKICM4D3W0V", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31364500, + "download_count": 761, + "created_at": "2022-05-08T09:35:16Z", + "updated_at": "2022-05-08T09:35:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843691", + "id": 64843691, + "node_id": "RA_kwDOCGKICM4D3W-r", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14315984, + "download_count": 14, + "created_at": "2022-05-08T09:45:58Z", + "updated_at": "2022-05-08T09:46:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64842989", + "id": 64842989, + "node_id": "RA_kwDOCGKICM4D3Wzt", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27737468, + "download_count": 2016, + "created_at": "2022-05-08T09:35:12Z", + "updated_at": "2022-05-08T09:35:13Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843007", + "id": 64843007, + "node_id": "RA_kwDOCGKICM4D3Wz_", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27737468, + "download_count": 461, + "created_at": "2022-05-08T09:35:14Z", + "updated_at": "2022-05-08T09:35:16Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843690", + "id": 64843690, + "node_id": "RA_kwDOCGKICM4D3W-q", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11209336, + "download_count": 12, + "created_at": "2022-05-08T09:45:57Z", + "updated_at": "2022-05-08T09:45:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843688", + "id": 64843688, + "node_id": "RA_kwDOCGKICM4D3W-o", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11209384, + "download_count": 18, + "created_at": "2022-05-08T09:45:55Z", + "updated_at": "2022-05-08T09:45:56Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843692", + "id": 64843692, + "node_id": "RA_kwDOCGKICM4D3W-s", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2944, + "created_at": "2022-05-08T09:46:01Z", + "updated_at": "2022-05-08T09:46:01Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.05.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.05.1", + "body": "
\r\n \"valetudo\"\r\n

2022.05.1

\r\n
\r\n\r\nA small incremental release featuring a few UI/UX improvements\r\n\r\n## MQTT/REST Segment/Zone/GoTo improvements\r\n\r\nThis release adds an easy way of getting the payload to automate zoned cleanups, segment cleanups and go-to commands via MQTT or REST.\r\nSimply set up your zones/select your presets as you'd usually do but instead of just clicking the cleanup button, long-press it, and you will receive a dialog containing the copy-pastable payload for MQTT/REST. `ctrl + a` also works :)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/167289945-4b84df5c-8ebd-4dc4-a121-efc997454aab.png)\r\n\r\n\r\n## Client Map Structure Visibility\r\n\r\nThis release adds a shadow to zones drawn onto the map to improve visibility especially when using the light theme.\r\n\r\nBefore:\r\n![image](https://user-images.githubusercontent.com/974410/167289951-151daef5-bbcf-4fbd-b81c-5674ef12c74f.png)\r\n\r\nAfter:\r\n![image](https://user-images.githubusercontent.com/974410/167289957-d6422c64-7feb-4ab1-905f-cb76ffd38d16.png)\r\n\r\n\r\nFurthermore, NoGoAreas and VirtualWalls now are slightly less transparent to improve visibility on orange segments.\r\n\r\n## Map Crispness\r\n\r\nAt some point for some reason, the map renderer canvas lost the `image-rendering: crisp-edges` css property, which caused occasional blurry maps.\r\n\r\nThis has been fixed. We can now all again enjoy crisp edges :)\r\n\r\nUncrisp edges:\r\n![image](https://user-images.githubusercontent.com/974410/167289962-65a5ffc4-0b86-490a-959e-1f27f3570470.png)\r\n\r\nCrisp edges:\r\n![image](https://user-images.githubusercontent.com/974410/167289969-0d3d78cd-b71e-4dd9-8092-2608b43acee4.png)\r\n\r\n\r\n## Node V18\r\n\r\nThe base binaries have been upgraded to the latest NodeJS v18.1.0.\r\nThey're also now built with `-Os`, which decreased our binary size by a few percent.\r\n\r\n## Other news\r\n\r\nAs mentioned in the previous release notes, we're currently still pretty busy figuring out how to root new robots and/or firmware versions.\r\nSince that worked well the last time, I shall continue mentioning it here.\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Get payload of segment/zone cleanup via long-press ([52731bf](https://github.com/Hypfer/Valetudo/commit/52731bf3b218b58f8469342bcdfdb08f9725ccb1))\r\n* **vendor.roborock:** Add support for the M1S ([f234925](https://github.com/Hypfer/Valetudo/commit/f234925aef5415784c9358f39435aa7e01d9ef79))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Limit the maximum fdsUpload filesize ([c1de1c5](https://github.com/Hypfer/Valetudo/commit/c1de1c59084cfe9dfcd9f5659c4be92b153bbfc2))\r\n* **miio:** process _async.stat, _otc.ncstat and _otc.ncinfo messages ([#1488](https://github.com/Hypfer/Valetudo/issues/1488)) ([7cf1fe9](https://github.com/Hypfer/Valetudo/commit/7cf1fe98b7546fa97ad06ce75e04952e436fcbb2))\r\n* **ui:** Add shadow to some client structures for better visibility ([d4e7f83](https://github.com/Hypfer/Valetudo/commit/d4e7f83521b4324bbf9263822d33f7603765d088))\r\n* **ui:** Fix map crispness ([e55a5dc](https://github.com/Hypfer/Valetudo/commit/e55a5dc646e12b3cda2510ff3e792d2d88aa0ee3))\r\n* **ui:** Improve visibility of red virtual restrictions on orange segments ([797143a](https://github.com/Hypfer/Valetudo/commit/797143a1b330c2bcbc44deb4dead656eb381cc56))\r\n* Work around Node v18 breaking os.networkInterfaces ([226dae1](https://github.com/Hypfer/Valetudo/commit/226dae13b9ebd49797d6b0e2f0dacd9ac394cd53))\r\n* **vendor.roborock:** copy metadata from previous state on state update ([#1489](https://github.com/Hypfer/Valetudo/issues/1489)) ([6ecc76b](https://github.com/Hypfer/Valetudo/commit/6ecc76b843e5a582936702f4a5c0fea04a9a4d07))\r\n* **vendor.roborock:** Ignore event.fan_power_reduced ([c56e7a2](https://github.com/Hypfer/Valetudo/commit/c56e7a26df92e628906f78e7b2ee28b243dcd70b))\r\n* **vendor.roborock:** Multiple fixes for Mijia 1S ([#1485](https://github.com/Hypfer/Valetudo/issues/1485)) ([c66798d](https://github.com/Hypfer/Valetudo/commit/c66798db6e19a8a2dac494bf10f444795015872f))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1491", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630/reactions", + "total_count": 8, + "+1": 8, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60507121", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60507121/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/60507121/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.03.0", + "id": 60507121, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4Dm0Px", + "tag_name": "2022.03.0", + "target_commitish": "master", + "name": "Valetudo 2022.03.0", + "draft": false, + "prerelease": true, + "created_at": "2022-02-25T18:10:57Z", + "published_at": "2022-02-25T18:49:08Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926335", + "id": 57926335, + "node_id": "RA_kwDOCGKICM4Dc-K_", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34122221, + "download_count": 46, + "created_at": "2022-02-25T18:55:30Z", + "updated_at": "2022-02-25T18:55:32Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926849", + "id": 57926849, + "node_id": "RA_kwDOCGKICM4Dc-TB", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13802973, + "download_count": 4, + "created_at": "2022-02-25T19:03:25Z", + "updated_at": "2022-02-25T19:03:26Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926332", + "id": 57926332, + "node_id": "RA_kwDOCGKICM4Dc-K8", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964193, + "download_count": 80, + "created_at": "2022-02-25T18:55:27Z", + "updated_at": "2022-02-25T18:55:28Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926333", + "id": 57926333, + "node_id": "RA_kwDOCGKICM4Dc-K9", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964193, + "download_count": 33, + "created_at": "2022-02-25T18:55:29Z", + "updated_at": "2022-02-25T18:55:30Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926848", + "id": 57926848, + "node_id": "RA_kwDOCGKICM4Dc-TA", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13218985, + "download_count": 6, + "created_at": "2022-02-25T19:03:24Z", + "updated_at": "2022-02-25T19:03:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926845", + "id": 57926845, + "node_id": "RA_kwDOCGKICM4Dc-S9", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13219169, + "download_count": 4, + "created_at": "2022-02-25T19:03:23Z", + "updated_at": "2022-02-25T19:03:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926852", + "id": 57926852, + "node_id": "RA_kwDOCGKICM4Dc-TE", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 90, + "created_at": "2022-02-25T19:03:27Z", + "updated_at": "2022-02-25T19:03:28Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.03.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.03.0", + "body": "
\r\n \"valetudo\"\r\n

2022.03.0

\r\n
\r\n\r\nOrdered segment cleanups via the UI, MQTT deduplication and a lot of internal refactoring\r\n\r\n## Ordered segment cleanup\r\n\r\nThe UI now tracks the order in which segments were selected, meaning that if your robots' firmware supports it, they will be cleaned in the order you've specified.\r\n\r\nIf supported, the order will be displayed as a roman numeral above the segment label triangle.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770812-180860d1-44f4-4531-a746-eff91e97e0cf.png)\r\n\r\n## MQTT\r\n\r\nThe MQTT connectivity feature now reports a state to the UI. Furthermore, it also collects some statistics.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770843-92204a3d-23e6-469f-b053-704ff2ec2347.png)\r\n\r\n\r\nBy watching those stats, you will notice that this release also causes less traffic, as most outgoing messages are deduplicated.\r\n\r\nInitially, I didn't want to do that as the solution proposed was to just store every payload in memory and then compare on each mqtt publish.\r\nThat would work, however it comes with a hefty ram overhead as you now have to constantly keep 300+ somewhat long string payloads in memory.\r\nWith each character taking up 2 byte, this approach isn't feasible with the ram budget we have (32 Mbyte or less).\r\n\r\nTo reduce the amount of ram required, we could use a hash function such as md5, however that would still be too much.\r\nAs they'd be saved as hex strings, that would mean 32 characters each with each character taking up 2 bytes, resulting in each pair of topic and payload using 128 byte or more.\r\n\r\nThus, instead we're now using 32-bit CRC32. With object keys being strings, I'd think that these pairs should use around 20 byte each.\r\nThe downside of CRC32 is that the risk of collisions is much higher. However, I highly doubt that that could actually happen in this application.\r\n\r\nTo save CPU time, which is also quite limited on our robots, the (in comparison) huge map data is not being deduplicated.\r\n\r\n## Misc\r\n\r\n- The system information page will now display the current robot firmware version if available\r\n- The UI will now prevent the user from configuring invalid MQTT topic names (containing spaces, # or +)\r\n- The UPnP/SSDP lib was dropped in favour of our own implementation, which should fix some unhandledRejections caused by the lib\r\n- The log viewer now doesn't scroll back down automatically if the user scrolled up\r\n- TotalStatistics should now also work for the Roborock S7\r\n- It is now possible to disable network advertisement (bonjour/mDNS and UPnP/SSDP) via the UI if you so desire\r\n- The nonsensical always-attached dustbin attachment has been removed\r\n- It is now possible to have 50% more virtual restrictions on roborock robots\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Allow setting the order of segments cleaned if support by the robot ([9eec3b6](https://github.com/Hypfer/Valetudo/commit/9eec3b6200dee08d4094fdac47e9200e9585961e))\r\n* NetworkAdvertisementManager UI control ([bd5fa9c](https://github.com/Hypfer/Valetudo/commit/bd5fa9c1d156cab2b499952acb7664ebee554623)), closes [#1168](https://github.com/Hypfer/Valetudo/issues/1168)\r\n* **core:** Remove outdated VirtualWallCapability and RestrictedZoneCapability ([5e24783](https://github.com/Hypfer/Valetudo/commit/5e247835e3772ed57d445c8be82849bcedba6db6))\r\n* **core:** Remove SensorCalibrationCapability ([5b081a7](https://github.com/Hypfer/Valetudo/commit/5b081a78a4dbccf54ad2fb547daaa622ce8c8c7f))\r\n* **mqtt:** Collect runtime metrics and provide them via REST ([dcc1db4](https://github.com/Hypfer/Valetudo/commit/dcc1db4f86265be47242d2f836ba3ffac521ed67))\r\n* **ui:** Display firmware version if available ([e78e9b4](https://github.com/Hypfer/Valetudo/commit/e78e9b4e1dc84b7ce2b60adb36ec35675664ded0))\r\n* **ui:** Display MQTTClient status ([c54ebc8](https://github.com/Hypfer/Valetudo/commit/c54ebc8c1eae6c14a35247e7e55ce2bb2e0d0ccd))\r\n* **vendor.roborock:** Support S7 total statistics ([d1926a9](https://github.com/Hypfer/Valetudo/commit/d1926a9b33dfdbdf53f8b3b53ef0ee695c53c867))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Fix free memory reporting on kernels >= 3.14 ([dceea16](https://github.com/Hypfer/Valetudo/commit/dceea16f5a3fbc7b69ea938dd3c112e12a874019))\r\n* **miio:** Don't throw plain objects on error responses ([e84fe8c](https://github.com/Hypfer/Valetudo/commit/e84fe8c066b3ad3b7576405ee7d8cd8f17fd3d85))\r\n* **miio:** Fix RetryWrapper never handshaking on stale stamp ([326cb4b](https://github.com/Hypfer/Valetudo/commit/326cb4bafda8b558e8eff2937aa034d3ae25306a))\r\n* **mqtt:** Deduplicate outgoing messages ([b835336](https://github.com/Hypfer/Valetudo/commit/b835336089aa02430cdeb7e877353869fd3e363d))\r\n* **networkadvertisement:** Replace ssdp lib with custom implementation ([f5e505a](https://github.com/Hypfer/Valetudo/commit/f5e505ae3c04313237a0648e5a35d04b6af59ef6))\r\n* **ui:** Disallow whitespaces, + and # for mqtt topic customization ([8148736](https://github.com/Hypfer/Valetudo/commit/81487363a0158c643ce55c7d555790d02d35d48a))\r\n* **ui:** Make the logviewer only auto-scroll if it is already scrolled down ([3c24eba](https://github.com/Hypfer/Valetudo/commit/3c24eba7794b01188f8e0446c4b6dc73c23af96c))\r\n* **vendor.dreame:** Mapping passes can only be done by lidar-based robots ([411fab5](https://github.com/Hypfer/Valetudo/commit/411fab5496c9c2eba9f488d7d97a742073ddf3de))\r\n* **vendor.dreame:** Re-enable custom order segment cleanups and hope for the best ([744a4bb](https://github.com/Hypfer/Valetudo/commit/744a4bb8558e2c938c3b163b3916a6408478b23b))\r\n* **vendor.roborock:** Fix roborock virtual restrictions counting vertices incorrectly ([cc5e37b](https://github.com/Hypfer/Valetudo/commit/cc5e37b6d4e81987005760f867f2487c40435073)), closes [#1423](https://github.com/Hypfer/Valetudo/issues/1423)\r\n* **vendor.roborock:** Properly parse and handle lab_status and map_status ([e158ac4](https://github.com/Hypfer/Valetudo/commit/e158ac4b7fc58ad9ee06bbf4bb296d054afb77d9)), closes [#1424](https://github.com/Hypfer/Valetudo/issues/1424)\r\n* Remove nonsensical always-attached dustbin attachment ([b9bd959](https://github.com/Hypfer/Valetudo/commit/b9bd9599c9931940cc7536eaccbbe2f11f25e066))\r\n* SegmentIds should be strings ([6325045](https://github.com/Hypfer/Valetudo/commit/63250452dfeeaae0e477dc66060be3136df5a7c2))\r\n* SegmentIds should be strings pt2 ([a8d314d](https://github.com/Hypfer/Valetudo/commit/a8d314d2e8878c58a16c2fd4f58f5e866b4fcf85))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1429", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60507121/reactions", + "total_count": 3, + "+1": 3, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/58174812/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.02.0", + "id": 58174812, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4Dd61c", + "tag_name": "2022.02.0", + "target_commitish": "master", + "name": "Valetudo 2022.02.0", + "draft": false, + "prerelease": false, + "created_at": "2022-01-28T10:32:30Z", + "published_at": "2022-01-28T10:39:20Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55189921", + "id": 55189921, + "node_id": "RA_kwDOCGKICM4DSiGh", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34276203, + "download_count": 598, + "created_at": "2022-01-28T10:46:14Z", + "updated_at": "2022-01-28T10:46:16Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190622", + "id": 55190622, + "node_id": "RA_kwDOCGKICM4DSiRe", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13956163, + "download_count": 7, + "created_at": "2022-01-28T10:54:30Z", + "updated_at": "2022-01-28T10:54:31Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55189918", + "id": 55189918, + "node_id": "RA_kwDOCGKICM4DSiGe", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32118175, + "download_count": 1828, + "created_at": "2022-01-28T10:46:11Z", + "updated_at": "2022-01-28T10:46:12Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55189920", + "id": 55189920, + "node_id": "RA_kwDOCGKICM4DSiGg", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32118175, + "download_count": 489, + "created_at": "2022-01-28T10:46:13Z", + "updated_at": "2022-01-28T10:46:14Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190621", + "id": 55190621, + "node_id": "RA_kwDOCGKICM4DSiRd", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13373375, + "download_count": 14, + "created_at": "2022-01-28T10:54:29Z", + "updated_at": "2022-01-28T10:54:30Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190619", + "id": 55190619, + "node_id": "RA_kwDOCGKICM4DSiRb", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13373215, + "download_count": 16, + "created_at": "2022-01-28T10:54:28Z", + "updated_at": "2022-01-28T10:54:29Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190626", + "id": 55190626, + "node_id": "RA_kwDOCGKICM4DSiRi", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2526, + "created_at": "2022-01-28T10:54:32Z", + "updated_at": "2022-01-28T10:54:32Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.02.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.02.0", + "body": "
\r\n \"valetudo\"\r\n

2022.02.0

\r\n
\r\n\r\nLots of UI changes and more polishing\r\n\r\n## Quirks\r\n\r\nThis release adds the quirks concept, which shall be understood as a catch-all and/or staging area containing vendor-specific toggles that don't fit the generic abstraction that is Valetudo (yet).\r\nThis should make it fairly easy to quickly implement (some of the) exciting new vendor features without jeopardizing the architecture of Valetudo in the long run.\r\n\r\nHere's an example taken from the Dreame Z10:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532264-ff6b848f-0c5a-4083-af92-d3bc29be77a0.png)\r\n\r\n\r\n## Settings\r\n\r\nRobot, Map and Connectivity settings have been reorganized/redone.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532305-e97a3534-3f8a-44bc-8d4d-dec5537d7c70.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532320-456cda6f-b5f7-4104-95f5-4b258d0b576b.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532335-d0a79b27-b1ae-4114-b5f2-e5f2311ed8e0.png)\r\n\r\n\r\nWi-Fi and NTP state display has been redone as well:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532430-07629c75-e112-4d8c-acb6-5138d0d6de3d.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532445-ba2b34b4-6b25-4a22-9a7b-558054405b3f.png)\r\n\r\n\r\n## Quality of Life\r\n\r\nA _lot_ of help text sections and dialogs have been added all around the application to make usage of Valetudo even easier.\r\nThey should also answer a lot of common support questions, so make sure to read them before asking questions.\r\n\r\nFurthermore, all password fields have been updated to feature a plain-text-display toggle.\r\n\r\n\r\n## Total Statistics\r\n\r\nBecause displaying three numbers is boring, @ccoors had the great idea of adding gamification the total statistics feature.\r\nAfter some iteration on that idea, we've ended up with this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532462-7843b526-9c81-4b7f-bffe-1165d7dd02c9.png)\r\n\r\n\r\nThere's also an overview of all achievements:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532488-d0cfc8d4-c477-4ed6-8d48-edcfe6d6bec7.png)\r\n\r\n\r\nI'm very happy with how this turned out. Now we just need to think of more achievements.\r\nIf you have any ideas, feel free to leave them down in the comments.\r\n\r\n\r\n\r\n## Nightly builds\r\n\r\nThere are now automated nightly builds, which you can install using the updater.\r\n\r\nAs this is meant for people willing to accept and capable of handling breakage, there is no UI toggle to switch to nightly builds.\r\nTo enable them, ssh into your robot and change the update provider to `github_nightly`.\r\n\r\n## Misc\r\n\r\n- Viomi consumables have been fixed by @adrez99\r\n- @schinken fixed local access via IPv6\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** WifiScanCapability ([a4fe895](https://github.com/Hypfer/Valetudo/commit/a4fe895c9944ffe8fae6e621a87e2aa70e9aecde))\r\n* **ui:** Add general help ([ec298dc](https://github.com/Hypfer/Valetudo/commit/ec298dc2cf2d81ca40031dfae455abf490f9fcf8))\r\n* **ui:** Add help for dnd, voice packs and the updater ([84c8c04](https://github.com/Hypfer/Valetudo/commit/84c8c04657778795cb7e7acd76bbef001465ba3a))\r\n* **ui:** Add Map Management Help ([9d62c26](https://github.com/Hypfer/Valetudo/commit/9d62c26318ecda5d5a38e21333f56ac0ff1f70c6))\r\n* **ui:** Add quirks help ([77183ed](https://github.com/Hypfer/Valetudo/commit/77183ed3e63c94d30afbefc6d48cab8bf946b9f2))\r\n* **ui:** Add total statistics page ([#1330](https://github.com/Hypfer/Valetudo/issues/1330)) ([8fd0b2e](https://github.com/Hypfer/Valetudo/commit/8fd0b2eb3c59a5b949da8c9c6f0f4230886d48e6))\r\n* **ui:** Allow display of Wi-Fi passwords entered ([89624eb](https://github.com/Hypfer/Valetudo/commit/89624eb5b6c2b8091ab66821ebf1c3f82f119316))\r\n* **ui:** Allow newlines in confirmation dialog ([df2ee4f](https://github.com/Hypfer/Valetudo/commit/df2ee4f0ac0e209ac537a77705a860c5161f756b))\r\n* **ui:** Another achievement ([0ffbef4](https://github.com/Hypfer/Valetudo/commit/0ffbef4f3d64e1c50ae6663c277ef33d9c2e80ce))\r\n* **ui:** Extend map management help ([e1514bc](https://github.com/Hypfer/Valetudo/commit/e1514bcc59f8c0022aef588b58b10e2cc05c1ef9))\r\n* ValetudoWifiStatus may contain a bssid ([86fe2f2](https://github.com/Hypfer/Valetudo/commit/86fe2f207c2f050ca7351c21bd736de4f2d5d27b))\r\n* **ui:** Allow display of entered passwords for mqtt and basic auth ([4e75531](https://github.com/Hypfer/Valetudo/commit/4e7553100abb4dba247fbb036a6539499c619b89))\r\n* **ui:** Disable edit map tap interaction while not docked to reduce confusion ([b68e444](https://github.com/Hypfer/Valetudo/commit/b68e44428b3c2669cae147c8c4f21bbfc9bc016d))\r\n* **ui:** Improve achievement badges ([7eea13e](https://github.com/Hypfer/Valetudo/commit/7eea13e84950d01c044bc69ef385b33908ee20df))\r\n* **ui:** Improve NTP client state display ([0a265a7](https://github.com/Hypfer/Valetudo/commit/0a265a7dce5468e2948a077bd7e6f364212a285b))\r\n* **ui:** More achievements ([892017e](https://github.com/Hypfer/Valetudo/commit/892017ea38c16eee3ac6bc52d8ff5bde76e87ab1))\r\n* **ui:** Move map-related features to map management page ([ea45f01](https://github.com/Hypfer/Valetudo/commit/ea45f01b6a597f43d6000318500936702c89e397))\r\n* **ui:** Move Wi-Fi settings to connectivity ([dff909c](https://github.com/Hypfer/Valetudo/commit/dff909cae688b2106cc526475247cf0659251e46))\r\n* **ui:** Provide an overview of all achievements ([381e3cd](https://github.com/Hypfer/Valetudo/commit/381e3cd4dab807b85d8066ca4aa9f8628fe599d6))\r\n* **ui:** Rename about page to system information ([ad1dd16](https://github.com/Hypfer/Valetudo/commit/ad1dd1608dc0e2668914d7ab7a2eb68cb6978163))\r\n* **ui:** Restructure connectivity settings ([bfe33e4](https://github.com/Hypfer/Valetudo/commit/bfe33e4d4d929741a1a3191559ae84343dbe9a61))\r\n* **ui:** Restructure robot settings ([5c71be4](https://github.com/Hypfer/Valetudo/commit/5c71be44eb4a9f30674af550e230590b203ea82d))\r\n* **ui:** Restructure routers and add about page ([e3a1f13](https://github.com/Hypfer/Valetudo/commit/e3a1f1303bb8693aea0a8ea7ffb32d8fd658110a))\r\n* **updater:** Add nightly builds ([d1a0d91](https://github.com/Hypfer/Valetudo/commit/d1a0d919a6fd7df93031bdb7da469b1b61cdbc13))\r\n* **vendor.dreame:** Add auto empty interval quirk ([1b6205a](https://github.com/Hypfer/Valetudo/commit/1b6205a467304bcd4c9ce32aa28721fe0fd377f5))\r\n* **vendor.roborock:** Add quirks ([7fc584a](https://github.com/Hypfer/Valetudo/commit/7fc584af029efbe2a7b8e063fb9659afa43d0955))\r\n* **vendor.viomi:** Add quirks ([#1369](https://github.com/Hypfer/Valetudo/issues/1369)) ([b369e4d](https://github.com/Hypfer/Valetudo/commit/b369e4d7a253bd668f354f179a878fd8ce9c0717))\r\n* QuirksCapability ([79deeb1](https://github.com/Hypfer/Valetudo/commit/79deeb14eb855e294f0b9d3197151e8af5cc03ce))\r\n* **webserver:** Allow IPv6 requests from own network ([#1342](https://github.com/Hypfer/Valetudo/issues/1342)) ([165deff](https://github.com/Hypfer/Valetudo/commit/165deff8e033b45ec1e507d4678833dbca8b22d4))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix consumables not being polled by the autorefresh ([58d6267](https://github.com/Hypfer/Valetudo/commit/58d6267e3008c6637725ed7f531f07d182b01ddf)), closes [#1355](https://github.com/Hypfer/Valetudo/issues/1355)\r\n* **networkadvertisement:** Attempt to catch issues of the ssdp lib ([ee3154b](https://github.com/Hypfer/Valetudo/commit/ee3154bfdb6c5caadc22382e0e48e9a42a2df202))\r\n* **ui:** Allow refetching when there are zero quirks ([7f3ed2b](https://github.com/Hypfer/Valetudo/commit/7f3ed2b8b688ecf9f26436209625dda35e654b62))\r\n* **ui:** Allow user-selection of wifi IP addresses ([33c9470](https://github.com/Hypfer/Valetudo/commit/33c9470162ba4fe6ae2bbf5ba2de26ea08f1d47f))\r\n* **ui:** Allow user-selection of wifi IP addresses... again ([2bdcea4](https://github.com/Hypfer/Valetudo/commit/2bdcea4701b8828dfbcdde79aac12823ece07295))\r\n* **ui:** Disable updater buttons when busy ([f82ae1a](https://github.com/Hypfer/Valetudo/commit/f82ae1a0a114c3255c43d2700cab54a9f87067ff))\r\n* **ui:** Don't display updater warning if state is busy ([4d5c781](https://github.com/Hypfer/Valetudo/commit/4d5c7811b74c3a61f3eebaf1064bb18f6a1810a0))\r\n* **ui:** Don't provide the wifi configuration route if there is no wifi configuration capability ([82e954e](https://github.com/Hypfer/Valetudo/commit/82e954e2d072dcf7888aeef7eb732b78a73311f4))\r\n* **ui:** Fix about title ([67a9a05](https://github.com/Hypfer/Valetudo/commit/67a9a051c7d2071099a57a3a6dbf1e4fa101ca31))\r\n* **ui:** Fix display of text in conjunction with controls in Map Management ([1cc76c5](https://github.com/Hypfer/Valetudo/commit/1cc76c55f3c27be5f03e5a7cbfd6cc184ad40675))\r\n* **ui:** Fix logviewer timestamp display for chrome ([56f5ba0](https://github.com/Hypfer/Valetudo/commit/56f5ba08a9bc864eb20df9b17f109c0b1a89226e))\r\n* **ui:** Fix map management not using unique keys for all options ([2305b52](https://github.com/Hypfer/Valetudo/commit/2305b528be28351e3e02f6197ca88135dc95e64c))\r\n* **ui:** Fix menu drawer scrollbars ([4a6c9fa](https://github.com/Hypfer/Valetudo/commit/4a6c9faffcefba07277372a9172aa6f899d795ad))\r\n* **ui:** fix minor typo ([#1341](https://github.com/Hypfer/Valetudo/issues/1341)) ([77e07ec](https://github.com/Hypfer/Valetudo/commit/77e07ec04bb32407176ff184e706a4229cdffced))\r\n* **ui:** Properly implement newlines in ConfirmationDialog ([b8f8eb0](https://github.com/Hypfer/Valetudo/commit/b8f8eb0163b8b3c13b5a2e1bab27837b8ff90811))\r\n* **ui:** Sort total statistics data points ([a568c03](https://github.com/Hypfer/Valetudo/commit/a568c03afa0521779f40c4933935b5315a81bd24))\r\n* **ui:** use relativ paths to allow hosting in a subdirectory .. again ([3007dbb](https://github.com/Hypfer/Valetudo/commit/3007dbb1460596591199ece1d974c3b4e1db58e3))\r\n* **updater:** Add missing return statement ([f5e7451](https://github.com/Hypfer/Valetudo/commit/f5e7451a5877815a8871cdccdbf997f09b4b78ca))\r\n* **vendor.viomi:** Fix Viomi consumables ([#1367](https://github.com/Hypfer/Valetudo/issues/1367)) ([ccfe175](https://github.com/Hypfer/Valetudo/commit/ccfe175886ac41ff58f900de54657967a8f17337))\r\n* **webserver:** Fix missing doctype for error pages ([3d48611](https://github.com/Hypfer/Valetudo/commit/3d486114830eb69ba2f414aa67fdf4494cfefe3c))\r\n* **webserver:** Fix some endpoints never returning anything ([32c0f6a](https://github.com/Hypfer/Valetudo/commit/32c0f6ae922f71a8fd7ac5b035b9f5fffd1cdc8f))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1379", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812/reactions", + "total_count": 8, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 3, + "confused": 0, + "heart": 1, + "rocket": 4, + "eyes": 0 + }, + "mentions_count": 3 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/56229531/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.01.0", + "id": 56229531, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DWf6b", + "tag_name": "2022.01.0", + "target_commitish": "master", + "name": "Valetudo 2022.01.0", + "draft": false, + "prerelease": false, + "created_at": "2021-12-31T12:47:26Z", + "published_at": "2021-12-31T12:50:40Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919159", + "id": 52919159, + "node_id": "RA_kwDOCGKICM4DJ3t3", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34238322, + "download_count": 563, + "created_at": "2021-12-31T12:57:20Z", + "updated_at": "2021-12-31T12:57:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919489", + "id": 52919489, + "node_id": "RA_kwDOCGKICM4DJ3zB", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13918386, + "download_count": 10, + "created_at": "2021-12-31T13:05:24Z", + "updated_at": "2021-12-31T13:05:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919155", + "id": 52919155, + "node_id": "RA_kwDOCGKICM4DJ3tz", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32080294, + "download_count": 1527, + "created_at": "2021-12-31T12:57:17Z", + "updated_at": "2021-12-31T12:57:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919157", + "id": 52919157, + "node_id": "RA_kwDOCGKICM4DJ3t1", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32080294, + "download_count": 481, + "created_at": "2021-12-31T12:57:18Z", + "updated_at": "2021-12-31T12:57:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919485", + "id": 52919485, + "node_id": "RA_kwDOCGKICM4DJ3y9", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13334790, + "download_count": 19, + "created_at": "2021-12-31T13:05:23Z", + "updated_at": "2021-12-31T13:05:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919483", + "id": 52919483, + "node_id": "RA_kwDOCGKICM4DJ3y7", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13334414, + "download_count": 19, + "created_at": "2021-12-31T13:05:22Z", + "updated_at": "2021-12-31T13:05:23Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919492", + "id": 52919492, + "node_id": "RA_kwDOCGKICM4DJ3zE", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1842, + "created_at": "2021-12-31T13:05:27Z", + "updated_at": "2021-12-31T13:05:27Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.01.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.01.0", + "body": "
\r\n \"valetudo\"\r\n

2022.01.0

\r\n
\r\n\r\nQuality of life improvements, bugfixes and more polishing. Also, Happy New Year :)\r\n\r\n## UI/UX Changes\r\n\r\n### Map Management\r\n\r\nThe map management feature has been restructured to be easier to understand especially for newcomers.\r\nFurthermore, there are now help texts available in the editor, which should answer common questions.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824285-2d9337b3-3a50-478a-ae2b-9f216fbcd544.png)\r\n![image](https://user-images.githubusercontent.com/974410/147824293-0c03affb-d343-4f6f-a5ba-4f939c56ec0b.png)\r\n![image](https://user-images.githubusercontent.com/974410/147824290-d1b5f4d2-e4aa-403a-b5a7-82461ec1a6ed.png)\r\n\r\n\r\n### Updater\r\n\r\nThe updater now auto-refreshes its state and provides more feedback.\r\nIt will also display the latest changelog if there's no update available.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824299-49d9aa54-b571-4544-84e9-143a30e5c545.png)\r\n\r\n\r\n### Misc\r\n\r\n- The UI now auto-refreshes if the backend version changed\r\n- Visual consistency has been improved\r\n- The title is now updated based on the page you're on which makes your browser history actually useful\r\n- Hovering over some unlabelled buttons/icons should now give you a tooltip clearing things up\r\n- You can now hover over the progress bars in the about page to get a tooltip for the value as well\r\n- Info boxes answering common questions have been added to the connectivity page\r\n- It should now be possible to use Valetudo in a sub folder of a reverse proxy again\r\n\r\n\r\n## MQTT Changes\r\n\r\n### Home Assistant 2021.12\r\n\r\nValetudo now **requires Home Assistant 2021.12 or newer** as that release introduced the `object_id` field for\r\nMQTT autodiscovery. This allows us to influence the `entity_id` so that the days of `camera.map_data_3` are gone.\r\n\r\nYou might have to delete the device in HA and let it be rediscovered for these changes to be applied.\r\n\r\nIt is worth it though:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824304-96a6d2c9-3ff8-4b6a-965a-dc3ff599ab9f.png)\r\n\r\n\r\n### Bugfixes\r\n\r\nMultiple issues regarding MQTT stability and reliability have been identified and fixed with this release, hopefully\r\nsolving connectivity issues in situations with bad Wi-Fi signal coverage.\r\n\r\n\r\n## External Access\r\n\r\nValetudo now attempts to block access from public-routable IPs to its REST-Interface by default.\r\nThis was necessary, because publicly-accessible Valetudo instances kept appearing \r\non Shodan.io.\r\n\r\nIt is certainly no foolproof solution, but it might at least help a little.\r\nYou can also disable the filter if you absolutely have to, however I'd strongly recommend not doing that.\r\n\r\n## Misc\r\n\r\nAs it turns out, nodes `os.getNetworkInterfaces()` does not return all network interfaces, which led to the unique\r\nsystem identifier randomly changing depending on whether or not the robot had an IP address.\r\nThis has been fixed by the use of the mighty `sysfs`.\r\n\r\nMoreover, Valetudo now polls the network state every 30s in an attempt to catch network changes and restart\r\nthe network advertisement so that the companion app doesn't display `192.168.5.1` right after provisioning.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Remove DebugCapability ([78c84de](https://github.com/Hypfer/Valetudo/commit/78c84ded4eef1ac3b9a3e0d66ef88ebd5d44c19f))\r\n* **ui:** Add hover labels to system ram and load information ([62ed252](https://github.com/Hypfer/Valetudo/commit/62ed252968b97b72662a4a6622f2c0c75bdf2b5b))\r\n* **ui:** Add info boxes answering common questions to the connectivity settings page ([9eae3e3](https://github.com/Hypfer/Valetudo/commit/9eae3e393dda0a7376be79b5b6cdc81c9fc0b27e))\r\n* **ui:** Add link to the docs ([88b810c](https://github.com/Hypfer/Valetudo/commit/88b810c1b454c637c72aa51ab5015f7162e9812a))\r\n* **ui:** Automatically refresh the page when the backend version changed ([905ada1](https://github.com/Hypfer/Valetudo/commit/905ada104441c2283038c4a963a2e197bf511af1))\r\n* **ui:** Change infobox icon ([a82e1df](https://github.com/Hypfer/Valetudo/commit/a82e1df022395e109ddb5ea207be652ce93565e0))\r\n* **ui:** Consolidate paths to a single svg ([82bc46b](https://github.com/Hypfer/Valetudo/commit/82bc46b9e157df21490ad5009beae6277520b564))\r\n* **ui:** Improve first-time usability by adding titles to buttons and more minor changes ([6126718](https://github.com/Hypfer/Valetudo/commit/612671809d2f8ce8018866b2ca8257b34b1d1bbf))\r\n* **ui:** Improve segment edit help ([17e1d5f](https://github.com/Hypfer/Valetudo/commit/17e1d5ffaa0d938317699b89a2244541dd9dad14))\r\n* **ui:** Improve visual consistency ([006b94b](https://github.com/Hypfer/Valetudo/commit/006b94b1c47cbe6376d0340d2c7c0ae82fc26341))\r\n* **ui:** More space for mobile ([6a6ba65](https://github.com/Hypfer/Valetudo/commit/6a6ba65ce7d7d9c4629d39ef9c61ee6e685679bc))\r\n* **ui:** Rework map management ([4f51935](https://github.com/Hypfer/Valetudo/commit/4f51935fe1ea55921c81080c33918355807e23fe))\r\n* **ui:** Use non-swipable drawer for better performance ([25298a0](https://github.com/Hypfer/Valetudo/commit/25298a05ead114dca93c8e4e3b4b39e623838f8d))\r\n* **updater:** Display changelog of latest release when in noUpdateRequired state ([ce0c675](https://github.com/Hypfer/Valetudo/commit/ce0c675eca5548b7bb1fc55a9e2fc40290ce1bb3))\r\n* **updater:** Introduce busy state to provide better user feedback ([4e9ed3d](https://github.com/Hypfer/Valetudo/commit/4e9ed3d0b38a225bb1a93a5d32dee4686b04382b))\r\n* **webserver:** Attempt to block external access to valetudo ([10b1662](https://github.com/Hypfer/Valetudo/commit/10b1662f94d719d03b59c29bd51ab440b7d616dc))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **updater:** fix(updater): Use busy state flag instead of busy state ([d122efcb](https://github.com/Hypfer/Valetudo/commit/d122efcb53f301b124f182ef471e3f9e23c5771b))\r\n* **core:** Use sysfs to reliably determine the unique system identifier in all network conditions ([8d74825](https://github.com/Hypfer/Valetudo/commit/8d74825f4dd8ec3a8414259c3da8671efc694f36))\r\n* **mqtt:** Don't try to publish anything if there is no mqtt connection ([9051ac0](https://github.com/Hypfer/Valetudo/commit/9051ac04156c061f84e50e5e741ab7e65fc8431c))\r\n* **mqtt:** Fix mqtt getting stuck forever requiring a restart ([42a5613](https://github.com/Hypfer/Valetudo/commit/42a5613d19cd46bba0e5243f656d062f8a4d4415))\r\n* **mqtt:** Force disconnect if it takes longer than 1500ms ([ced9ee1](https://github.com/Hypfer/Valetudo/commit/ced9ee1b3312489c0c937723ba8744c21264f540))\r\n* **mqtt:** More .disconnect() fixes ([322efcc](https://github.com/Hypfer/Valetudo/commit/322efcc7cad8e1ae67126ded81b2d327c50bea8d))\r\n* **networkadvertisement:** Attempt to watch for network state changes to fix advertisement after initial provisioning ([7a2c3d1](https://github.com/Hypfer/Valetudo/commit/7a2c3d1a8c32d88562bc2dacec9671e1e756947a))\r\n* **ui:** Redraw map on visibilityState change to fix map not being updated if the tab was invisible for too long ([1c86152](https://github.com/Hypfer/Valetudo/commit/1c861521430e5df4640d614d75dcaa6def09124c))\r\n* **ui:** use relativ paths to allow hosting in a subdirectory ([1e73947](https://github.com/Hypfer/Valetudo/commit/1e73947d2a16bb831bc14d85ebeedb242b7714ef))\r\n* **vendor.dreame:** Ignore more irrelevant property updates ([9e4e202](https://github.com/Hypfer/Valetudo/commit/9e4e2028c69c9a37f661a4c90904311d65c9e90e))\r\n* **webserver:** Handle aborted connections gracefully ([b3e8024](https://github.com/Hypfer/Valetudo/commit/b3e802479e5068df25c951b2e148655c8f7448fa))\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1316", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531/reactions", + "total_count": 10, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 10, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/65762409/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.05.0", + "id": 65762409, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4D63Rp", + "tag_name": "2022.05.0", + "target_commitish": "master", + "name": "Valetudo 2022.05.0", + "draft": false, + "prerelease": false, + "created_at": "2022-05-01T15:55:06Z", + "published_at": "2022-05-01T16:02:49Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64183833", + "id": 64183833, + "node_id": "RA_kwDOCGKICM4D014Z", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33106996, + "download_count": 609, + "created_at": "2022-05-01T16:09:21Z", + "updated_at": "2022-05-01T16:09:22Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184367", + "id": 64184367, + "node_id": "RA_kwDOCGKICM4D02Av", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12787852, + "download_count": 2, + "created_at": "2022-05-01T16:17:51Z", + "updated_at": "2022-05-01T16:17:51Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64183827", + "id": 64183827, + "node_id": "RA_kwDOCGKICM4D014T", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30948968, + "download_count": 1780, + "created_at": "2022-05-01T16:09:18Z", + "updated_at": "2022-05-01T16:09:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64183830", + "id": 64183830, + "node_id": "RA_kwDOCGKICM4D014W", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30948968, + "download_count": 350, + "created_at": "2022-05-01T16:09:19Z", + "updated_at": "2022-05-01T16:09:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184364", + "id": 64184364, + "node_id": "RA_kwDOCGKICM4D02As", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12203608, + "download_count": 6, + "created_at": "2022-05-01T16:17:50Z", + "updated_at": "2022-05-01T16:17:50Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184363", + "id": 64184363, + "node_id": "RA_kwDOCGKICM4D02Ar", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12203536, + "download_count": 11, + "created_at": "2022-05-01T16:17:49Z", + "updated_at": "2022-05-01T16:17:49Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184370", + "id": 64184370, + "node_id": "RA_kwDOCGKICM4D02Ay", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2848, + "created_at": "2022-05-01T16:17:52Z", + "updated_at": "2022-05-01T16:17:53Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.05.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.05.0", + "body": "
\r\n \"valetudo\"\r\n

2022.05.0

\r\n
\r\n\r\nSpring-cleaning 2022: Usability improvements, bugfixes and the removal of zone/goto presets + the old UI\r\n\r\n## Zone/GoTo Preset removal\r\n\r\nValetudo 2022.05.0 removes the Zone Preset/GoTo Location feature that has been deprecated since more than six months now.\r\n\r\nAs a replacement for this feature, the MQTT interface now accepts coordinates instead of preset IDs.\r\nThus, users can just change the place where they store their coordinates from the Valetudo config file to e.g., the Home Assistant config files.\r\n\r\nPlease head over to the MQTT docs to find out how to use it.\r\nIt's the same payload that is used by the REST API. No surprises there.\r\n\r\n
\r\nIf you're unhappy and/or like to know more about why this change was done, feel free to click on this spoiler\r\n\r\n
\r\nFeature removal is delicate topic, since there always will be at least one person that is very upset and unhappy with whatever change was done to a project. See also: XKCD 1172.\r\n\r\nStill, it has to be done once in a while to keep a clean codebase and focus on what is most important.\r\nWithout these kinds of cleanups, projects eventually grow to a point when they start suffocating under their own weight.\r\n\r\nIf you've ever worked with larger legacy enterprise codebases, you should understand the issue.\r\nThey tend to be torn apart by\r\n\r\n- legacy features/behaviour having to stay like they are for existing customers/long-running support contracts\r\n\r\nand\r\n\r\n- management, sales and the market in general demanding newer features that no one could ever have predicted previously\r\n\r\nSee also this anecdote on Oracle 12.2 found on Hackernews.\r\n\r\n\r\nAs avid listeners of my ramblings have likely been aware, I've been very unhappy with that preset feature for more much more than just half a year now.\r\nIt was always a very fragile feature to begin with, given that Valetudo itself would store these coordinates without knowing anything about the underlying map.\r\nThe robot might've decided to rotate the map, leading to them pointing to a completely different location without Valetudo being able to catch that.\r\n\r\nAt the time when it was added, it was the best we had, given that map segments simply weren't invented just yet.\r\nWe didn't even have persistent maps, which is very strange to look back to.\r\n\r\nThat however was almost four years ago. Since then, the market changed a lot as you can tell.\r\nBasically every robot now supports not only persistent maps but also the map segmentation, which is handled by the firmware and not Valetudo.\r\nThose are objectively superior to some rectangles that are drawn onto the map, which is why it was finally time to remove this hack.\r\n\r\n\r\nI know that this may be bad news for V1 owners who do not have segments support and also don't want to use something like Home Assistant.\r\nHowever, I'd like to point out that there is nothing forcing anyone to upgrade to a newer Valetudo version.\r\nThere is no automatic update check that periodically annoys the user.\r\nThere is no cloud that will change its API.\r\nIt just works and will continue to do so.\r\n\r\nTherefore, for those who want to continue using zone presets and goto locations, it is recommended to stick with Valetudo 2022.03.1.\r\nIt also shouldn't be too hard to backport changes to that version. I however simply can't provide that kind of support.\r\nI hope that you will all understand that.\r\n
\r\n
\r\n\r\n## Removal of the old UI\r\n\r\nWith the presets gone, we can finally remove the old frontend entirely, which reduced the binary size by around 1MiB.\r\nWhile this doesn't sound like much given that it's \"only\" 3%, it's important to note that currently, 24MiB of the armv7 build consist of the bundled nodejs runtime. This means that with this update, the size of Valetudo itself shrunk by **15%**!\r\n\r\n## UI improvements\r\n\r\nThe menu opening thingy of the mobile UI now always stays at the bottom of the screen to improve user experience when using long phones.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154092-65a71eec-1af7-4268-83c2-50c827065824.png)\r\n\r\n\r\nThe live map now renders virtual restrictions with more opacity and less bright colors as they were pretty obstructive previously.\r\nThe edit map remains unchanged.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154102-0d9f9700-59a2-42af-a488-6cb953b97add.png)\r\n\r\n\r\nThe log viewer now uses the jetbrains mono font.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154108-8bb2a3ec-4dbe-4ae2-9af9-00eb2a5921f4.png)\r\n\r\n\r\n## Attachments\r\n\r\nYour robot will now only report and display attachments whose state it is able to track. No more always attached dustbins confusing users.\r\n\r\n\r\n## Companion apps\r\n\r\nOver the last weeks, a few new companion applications were built:\r\n\r\n1. valetudo-tray-companion\r\n\r\n A tray icon that allows easy access to Valetudo instances on your network. It's mostly handy when dealing with 4+ robots\r\n\r\n2. valetudo-helper-miioota\r\n\r\n A standalone all-in-one firmware update flasher tool for roborock v1 and s5. The docs have been updated to suggest using it\r\n\r\n3. valetudo-helper-httpbridge\r\n\r\n A standalone self-contained utility webserver currently most useful for rooting dreames. The docs have been updated to suggest using it\r\n\r\n4. valetudo-helper-miio\r\n\r\n A standalone self-contained utility to send raw miio commands. Useful for development of valetudo or other software interacting via miio\r\n\r\n5. valetudo-helper-voicepacks\r\n\r\n A WIP tool to help with Voicepacks\r\n\r\nThese should make installation and usage of Valetudo even easier than before.\r\n\r\n## Other news\r\n\r\nWe're currently pretty busy figuring out how to root new robots and/or firmware versions.\r\nThese endeavors are partly funded by your donations. Thank you!\r\n\r\nIf you want to see Valetudo on more robots, you might want to consider donating:\r\n\r\nhttps://github.com/sponsors/Hypfer\r\n\r\nhttps://builder.dontvacuum.me/donations.txt\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Provide attachment state attributes autodiscovery for home assistant ([b7b6344](https://github.com/Hypfer/Valetudo/commit/b7b6344281183fa022d83f4635894af3beae7a97))\r\n* **ui:** Improve mobile controls for long screens ([f7f3f0d](https://github.com/Hypfer/Valetudo/commit/f7f3f0db6e155aff25344d293e9822b589e43d9a))\r\n* **ui:** Reduce live map obstructions caused by virtual restrictions ([ddec0b3](https://github.com/Hypfer/Valetudo/commit/ddec0b34b215cc9b81d5b2e86926c8b73e446ca5))\r\n* **ui:** Use JetBrains Mono ([5a7045c](https://github.com/Hypfer/Valetudo/commit/5a7045c1a03c97bf892738d40999824fb2ae6a81))\r\n* **vendor.dreame:** 1C PendingMapChangeHandling ([1b2f3bf](https://github.com/Hypfer/Valetudo/commit/1b2f3bf0055587faadaaa2bd841449e887de0a49))\r\n* **vendor.dreame:** Add support for the STYTJO6ZHM ([519c5b4](https://github.com/Hypfer/Valetudo/commit/519c5b4a437868e9d7de2e20448bbc6d1f1cfceb))\r\n* **vendor.viomi:** Fetch and display firmware version ([7f08743](https://github.com/Hypfer/Valetudo/commit/7f087438e08e66a5663ae6f52868249cb5348659))\r\n* **vendor.viomi:** Raise zone count limit to 10 ([8130e24](https://github.com/Hypfer/Valetudo/commit/8130e24dc31be40d76a4f417ca8ceb7f40751de5))\r\n* Provide list of attachments supported by the model of robot ([fe65df3](https://github.com/Hypfer/Valetudo/commit/fe65df3696d2a0af608db27c54f32b49bcb88635))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** MqttController default state should be disconnected ([137e630](https://github.com/Hypfer/Valetudo/commit/137e630147eadb06673d269920f29abed07c7dcf))\r\n* **networkadvertisement:** Disabling the Network advertisement multiple times in a row should not cause any issues ([789608f](https://github.com/Hypfer/Valetudo/commit/789608f8cc384692ad05c66223480a555843c729))\r\n* **ui:** Allow closing of ValetudoEvents even if there are a lot ([ec599b2](https://github.com/Hypfer/Valetudo/commit/ec599b2f7ed2b328f0ab801ac029902eec54e7fe))\r\n* **ui:** Fix auto empty dock control loading state ([7ec1e5d](https://github.com/Hypfer/Valetudo/commit/7ec1e5d62cd53c8829cb70bc46a0402b5a3306d6))\r\n* **ui:** Handle timers with invalid actions ([b467443](https://github.com/Hypfer/Valetudo/commit/b4674433c40a576cc4c51e97a7a6ea9aedfcf29a))\r\n* **ui:** use correct relative paths to allow hosting in a subdirectory ([6129ec5](https://github.com/Hypfer/Valetudo/commit/6129ec5f4282edf07de1a5173fcf3a88067fe151))\r\n* **vendor.dreame:** Fix 1C powersave state mapping ([fdb51e7](https://github.com/Hypfer/Valetudo/commit/fdb51e7945fd908dec498b8b0b90a272227daf47))\r\n* **vendor.roborock:** Don't update state for attachments that we don't have ([f27bbfd](https://github.com/Hypfer/Valetudo/commit/f27bbfd97f71fb5f4b0c6dea4c3be9cf8774d22d))\r\n* **vendor.roborock:** Fix manual control for roborock v1 ([abccee4](https://github.com/Hypfer/Valetudo/commit/abccee47dbdd8972431cad3873029c502a093928))\r\n* **vendor.roborock:** Fix obnoxious \"no error\" error event ([f3b4a54](https://github.com/Hypfer/Valetudo/commit/f3b4a548dffc3aa96c2ecdf37c063b73847b0d5e))\r\n* **vendor.roborock:** Remove confusing attachments that never get updated ([e4274d3](https://github.com/Hypfer/Valetudo/commit/e4274d3da8ba64d0bc31f9d7683a4f3fbf91c79a))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1483", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409/reactions", + "total_count": 7, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 7, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/60521593/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.03.1", + "id": 60521593, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4Dm3x5", + "tag_name": "2022.03.1", + "target_commitish": "master", + "name": "Valetudo 2022.03.1", + "draft": false, + "prerelease": false, + "created_at": "2022-02-25T23:40:23Z", + "published_at": "2022-02-25T23:43:51Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57948762", + "id": 57948762, + "node_id": "RA_kwDOCGKICM4DdDpa", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34122267, + "download_count": 794, + "created_at": "2022-02-25T23:51:05Z", + "updated_at": "2022-02-25T23:51:06Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949356", + "id": 57949356, + "node_id": "RA_kwDOCGKICM4DdDys", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13803443, + "download_count": 13, + "created_at": "2022-02-26T00:00:11Z", + "updated_at": "2022-02-26T00:00:12Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57948736", + "id": 57948736, + "node_id": "RA_kwDOCGKICM4DdDpA", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964239, + "download_count": 2172, + "created_at": "2022-02-25T23:51:02Z", + "updated_at": "2022-02-25T23:51:03Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57948749", + "id": 57948749, + "node_id": "RA_kwDOCGKICM4DdDpN", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964239, + "download_count": 569, + "created_at": "2022-02-25T23:51:04Z", + "updated_at": "2022-02-25T23:51:05Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949355", + "id": 57949355, + "node_id": "RA_kwDOCGKICM4DdDyr", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13218871, + "download_count": 20, + "created_at": "2022-02-26T00:00:10Z", + "updated_at": "2022-02-26T00:00:11Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949354", + "id": 57949354, + "node_id": "RA_kwDOCGKICM4DdDyq", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13218639, + "download_count": 23, + "created_at": "2022-02-26T00:00:09Z", + "updated_at": "2022-02-26T00:00:10Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949359", + "id": 57949359, + "node_id": "RA_kwDOCGKICM4DdDyv", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2894, + "created_at": "2022-02-26T00:00:13Z", + "updated_at": "2022-02-26T00:00:14Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.03.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.03.1", + "body": "
\r\n \"valetudo\"\r\n

2022.03.1

\r\n
\r\n\r\nOrdered segment cleanups via the UI, MQTT deduplication and a lot of internal refactoring\r\n\r\n## Ordered segment cleanup\r\n\r\nThe UI now tracks the order in which segments were selected, meaning that if your robots' firmware supports it, they will be cleaned in the order you've specified.\r\n\r\nIf supported, the order will be displayed as a roman numeral above the segment label triangle.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770812-180860d1-44f4-4531-a746-eff91e97e0cf.png)\r\n\r\n## MQTT\r\n\r\nThe MQTT connectivity feature now reports a state to the UI. Furthermore, it also collects some statistics.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770843-92204a3d-23e6-469f-b053-704ff2ec2347.png)\r\n\r\n\r\nBy watching those stats, you will notice that this release also causes less traffic, as most outgoing messages are deduplicated.\r\n\r\nInitially, I didn't want to do that as the solution proposed was to just store every payload in memory and then compare on each mqtt publish.\r\nThat would work, however it comes with a hefty ram overhead as you now have to constantly keep 300+ somewhat long string payloads in memory.\r\nWith each character taking up 2 byte, this approach isn't feasible with the ram budget we have (32 Mbyte or less).\r\n\r\nTo reduce the amount of ram required, we could use a hash function such as md5, however that would still be too much.\r\nAs they'd be saved as hex strings, that would mean 32 characters each with each character taking up 2 bytes, resulting in each pair of topic and payload using 128 byte or more.\r\n\r\nThus, instead we're now using 32-bit CRC32. With object keys being strings, I'd think that these pairs should use around 20 byte each.\r\nThe downside of CRC32 is that the risk of collisions is much higher. However, I highly doubt that that could actually happen in this application.\r\n\r\nTo save CPU time, which is also quite limited on our robots, the (in comparison) huge map data is not being deduplicated.\r\n\r\n## Misc\r\n\r\n- The system information page will now display the current robot firmware version if available\r\n- The UI will now prevent the user from configuring invalid MQTT topic names (containing spaces, # or +)\r\n- The UPnP/SSDP lib was dropped in favour of our own implementation, which should fix some unhandledRejections caused by the lib\r\n- The log viewer now doesn't scroll back down automatically if the user scrolled up\r\n- TotalStatistics should now also work for the Roborock S7\r\n- It is now possible to disable network advertisement (bonjour/mDNS and UPnP/SSDP) via the UI if you so desire\r\n- The nonsensical always-attached dustbin attachment has been removed\r\n- It is now possible to have 50% more virtual restrictions on roborock robots\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Allow setting the order of segments cleaned if support by the robot ([9eec3b6](https://github.com/Hypfer/Valetudo/commit/9eec3b6200dee08d4094fdac47e9200e9585961e))\r\n* NetworkAdvertisementManager UI control ([bd5fa9c](https://github.com/Hypfer/Valetudo/commit/bd5fa9c1d156cab2b499952acb7664ebee554623)), closes [#1168](https://github.com/Hypfer/Valetudo/issues/1168)\r\n* **core:** Remove outdated VirtualWallCapability and RestrictedZoneCapability ([5e24783](https://github.com/Hypfer/Valetudo/commit/5e247835e3772ed57d445c8be82849bcedba6db6))\r\n* **core:** Remove SensorCalibrationCapability ([5b081a7](https://github.com/Hypfer/Valetudo/commit/5b081a78a4dbccf54ad2fb547daaa622ce8c8c7f))\r\n* **mqtt:** Collect runtime metrics and provide them via REST ([dcc1db4](https://github.com/Hypfer/Valetudo/commit/dcc1db4f86265be47242d2f836ba3ffac521ed67))\r\n* **ui:** Display firmware version if available ([e78e9b4](https://github.com/Hypfer/Valetudo/commit/e78e9b4e1dc84b7ce2b60adb36ec35675664ded0))\r\n* **ui:** Display MQTTClient status ([c54ebc8](https://github.com/Hypfer/Valetudo/commit/c54ebc8c1eae6c14a35247e7e55ce2bb2e0d0ccd))\r\n* **vendor.roborock:** Support S7 total statistics ([d1926a9](https://github.com/Hypfer/Valetudo/commit/d1926a9b33dfdbdf53f8b3b53ef0ee695c53c867))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Fix free memory reporting on kernels >= 3.14 ([dceea16](https://github.com/Hypfer/Valetudo/commit/dceea16f5a3fbc7b69ea938dd3c112e12a874019))\r\n* **miio:** Don't throw plain objects on error responses ([e84fe8c](https://github.com/Hypfer/Valetudo/commit/e84fe8c066b3ad3b7576405ee7d8cd8f17fd3d85))\r\n* **miio:** Fix RetryWrapper never handshaking on stale stamp ([326cb4b](https://github.com/Hypfer/Valetudo/commit/326cb4bafda8b558e8eff2937aa034d3ae25306a))\r\n* **mqtt:** Deduplicate outgoing messages ([b835336](https://github.com/Hypfer/Valetudo/commit/b835336089aa02430cdeb7e877353869fd3e363d))\r\n* **networkadvertisement:** Replace ssdp lib with custom implementation ([f5e505a](https://github.com/Hypfer/Valetudo/commit/f5e505ae3c04313237a0648e5a35d04b6af59ef6))\r\n* **ui:** Disallow whitespaces, + and # for mqtt topic customization ([8148736](https://github.com/Hypfer/Valetudo/commit/81487363a0158c643ce55c7d555790d02d35d48a))\r\n* **ui:** Make the logviewer only auto-scroll if it is already scrolled down ([3c24eba](https://github.com/Hypfer/Valetudo/commit/3c24eba7794b01188f8e0446c4b6dc73c23af96c))\r\n* **vendor.dreame:** Mapping passes can only be done by lidar-based robots ([411fab5](https://github.com/Hypfer/Valetudo/commit/411fab5496c9c2eba9f488d7d97a742073ddf3de))\r\n* **vendor.dreame:** Re-enable custom order segment cleanups and hope for the best ([744a4bb](https://github.com/Hypfer/Valetudo/commit/744a4bb8558e2c938c3b163b3916a6408478b23b))\r\n* **vendor.roborock:** Fix roborock virtual restrictions counting vertices incorrectly ([cc5e37b](https://github.com/Hypfer/Valetudo/commit/cc5e37b6d4e81987005760f867f2487c40435073)), closes [#1423](https://github.com/Hypfer/Valetudo/issues/1423)\r\n* **vendor.roborock:** Properly parse and handle lab_status and map_status ([e158ac4](https://github.com/Hypfer/Valetudo/commit/e158ac4b7fc58ad9ee06bbf4bb296d054afb77d9)), closes [#1424](https://github.com/Hypfer/Valetudo/issues/1424)\r\n* Remove nonsensical always-attached dustbin attachment ([b9bd959](https://github.com/Hypfer/Valetudo/commit/b9bd9599c9931940cc7536eaccbbe2f11f25e066))\r\n* SegmentIds should be strings ([6325045](https://github.com/Hypfer/Valetudo/commit/63250452dfeeaae0e477dc66060be3136df5a7c2))\r\n* SegmentIds should be strings pt2 ([a8d314d](https://github.com/Hypfer/Valetudo/commit/a8d314d2e8878c58a16c2fd4f58f5e866b4fcf85))\r\n* **ui:** Fix customOrder flag for segmentActions ([07c5281](https://github.com/Hypfer/Valetudo/commit/07c5281ae7b52571f49e0e8d553339cf01b6f450))\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1430", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593/reactions", + "total_count": 8, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 8, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/54959037/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.12.1", + "id": 54959037, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DRpu9", + "tag_name": "2021.12.1", + "target_commitish": "master", + "name": "Valetudo 2021.12.1", + "draft": false, + "prerelease": false, + "created_at": "2021-12-09T13:05:00Z", + "published_at": "2021-12-09T13:08:53Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51390567", + "id": 51390567, + "node_id": "RA_kwDOCGKICM4DEChn", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34173424, + "download_count": 415, + "created_at": "2021-12-09T13:16:24Z", + "updated_at": "2021-12-09T13:16:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391087", + "id": 51391087, + "node_id": "RA_kwDOCGKICM4DECpv", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13854816, + "download_count": 7, + "created_at": "2021-12-09T13:25:45Z", + "updated_at": "2021-12-09T13:25:46Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51390565", + "id": 51390565, + "node_id": "RA_kwDOCGKICM4DEChl", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015396, + "download_count": 1099, + "created_at": "2021-12-09T13:16:20Z", + "updated_at": "2021-12-09T13:16:22Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51390566", + "id": 51390566, + "node_id": "RA_kwDOCGKICM4DEChm", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015396, + "download_count": 353, + "created_at": "2021-12-09T13:16:22Z", + "updated_at": "2021-12-09T13:16:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391086", + "id": 51391086, + "node_id": "RA_kwDOCGKICM4DECpu", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13270228, + "download_count": 12, + "created_at": "2021-12-09T13:25:44Z", + "updated_at": "2021-12-09T13:25:45Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391085", + "id": 51391085, + "node_id": "RA_kwDOCGKICM4DECpt", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13269756, + "download_count": 21, + "created_at": "2021-12-09T13:25:43Z", + "updated_at": "2021-12-09T13:25:44Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391091", + "id": 51391091, + "node_id": "RA_kwDOCGKICM4DECpz", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1420, + "created_at": "2021-12-09T13:25:48Z", + "updated_at": "2021-12-09T13:25:48Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.12.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.12.1", + "body": "
\r\n \"valetudo\"\r\n

2021.12.1

\r\n
\r\n\r\nMap data format changes, quality of life improvements and bugfixes.\r\n\r\n## Changes in 2021.12.1\r\n\r\nAs expected, something would go wrong with the map data format change.\r\nThis is a bugfix release, so 98% of the previous changelog still apply.\r\n\r\n\r\nIn 2021.12.0, if you have rooms that aren't rectangular, it might happen that the triangle to select it vanishes, leading to you being unable to trigger a segment cleanup using the UI.\r\nThis happened because in those cases, the UI calculates the median pixel coordinates to properly place the triangle.\r\nThis value isn't calculated by the backend, because it is an expensive operation, and we're both RAM and CPU-limited there.\r\n\r\nTo calculate the median, the UI needs the decompressed pixel coordinate format.\r\nThis works exactly once during the initial render, because of the MapLayerRenderer doing the pixel decompression on the map passed by reference to it.\r\n\r\nAs soon as the WebWorker is available however, this doesn't happen anymore, as the worker only receives a copy of the data.\r\nThis means that there are now 0 pixels as far as the SegmentLabel is concerned, leading it to be placed at coordinates `[NaN,NaN]`.\r\nSince testing is done locally without constant map updates, everything seemed fine during development.\r\n\r\n\r\nAnother thing discovered due to this bug was that the GithubValetudoUpdateProvider did not filter out pre-releases or drafts.\r\nNot a big issue though as it just requires you to update twice in a row.\r\n\r\nAnyways, on with the 2021.12.0 changelog:\r\n\r\n## Map data format changes\r\n\r\nThis release features the first version increment of the ValetudoMap data format.\r\nInitially, in version 1, pixel data such as walls or floor were stored as a huge array of coordinate pairs:\r\n`[x0, y0, x1, y1, ...]`. This was not a very efficient way of storing that data as most of it is redundant.\r\n\r\nThis resulted in map files that were over 1 MiB in size being pushed to your browser every 3 seconds.\r\n\r\nTo combat this, some thought was put into how the data is stored.\r\nIf you have a row of pixels, all of them will have the same y-coordinate, meaning that you only have to store that once.\r\nPeople already figured that out [in the 60s](https://en.wikipedia.org/wiki/Run-length_encoding).\r\n\r\nWith Map V2, pixels are stored as `[xStart0, y0, count0, xStart1, y1, count1, ...]` where `[xStart, y]` is the starting point and `count` represents additional pixels with the same y-coordinate to the right.\r\n\r\nThis resulted in V2 map files using between 5% and 15% of the size of the equivalent V1 map.\r\nThe huge testfile map for example was compressed from 847 kB to 75 kB.\r\n\r\n\r\nWhile this is a **breaking change**, the breakage actually isn't that big of a change as V2 can easily be converted back to V1.\r\nIn fact, running `JSON.parse()` on a V2 map and then converting it to a V1 one in memory is more than twice as fast as running `JSON.parse()` on a V1 map.\r\n\r\nSince this change drastically reduces the traffic caused by live maps, I expect to see general usability and reliability\r\nimprovements in situations where the Wi-Fi reception isn't that great.\r\n\r\n\r\n## LogViewer\r\n\r\nThe LogViewer has been greatly improved and now features a structured and color-coded view of your log.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744519-5ba963b9-6409-4e04-95d9-e73caf55021c.png)\r\n\r\nYou can use the text filter at the top to either filter for the loglevel or the message contents.\r\nJust start typing.\r\n\r\n## UI Help\r\n\r\nBoth consumables and timers now feature a help button, which shall explain how to use these features.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744625-d113d697-e4e1-4f77-a3a2-596ad88131a5.png)\r\n\r\n\r\n## Misc\r\n\r\n- Map reset on newer roborock models should now be fixed thanks to @supersmile2009\r\n- Zooming the map should now work much better if you zoom via a touchpad or trackpoint instead of a mousewheel\r\n- MQTT current statistics now have a unit_of_measurement in HA\r\n- Lowmem builds now have a reduced map poll rate to reduce memory pressure\r\n- Valetudo now manages its logfile size to prevent it from growing indefinitely\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Automatically clear the logfile when it gets too large ([c0698b4](https://github.com/Hypfer/Valetudo/commit/c0698b43dda5144d7d0c2c58d9336a1c0662cc65))\r\n* Reduce map polling interval for lowmem hosts ([fcf94ce](https://github.com/Hypfer/Valetudo/commit/fcf94ceeb60f9b46e25bfa04d2e4e88ac2a25926))\r\n* **ntpClient:** Improve log messages ([8880bbf](https://github.com/Hypfer/Valetudo/commit/8880bbfc7ed79969a61c6d6e51f7023c23d7561e))\r\n* **ui:** Add help button + modal to consumables view ([d1388f1](https://github.com/Hypfer/Valetudo/commit/d1388f124dae0046d2bee49345d0513441926f21))\r\n* **ui:** Add timers help ([c864170](https://github.com/Hypfer/Valetudo/commit/c864170d44c2b686394bb6d770cff937e8a9de43))\r\n* **ui:** Implement LogViewer component ([1b96ae0](https://github.com/Hypfer/Valetudo/commit/1b96ae06c8a74acbc9a6fa03cf941736520e30d0))\r\n* **ui:** Remove obsolete about > github release info ([253d9f9](https://github.com/Hypfer/Valetudo/commit/253d9f99b0965859705c52ffae9483c381d49ad7))\r\n* **ui:** Swap Manual control cw & ccw rotation button ([44eab06](https://github.com/Hypfer/Valetudo/commit/44eab06eadcd57c8c9b3784bc6f4c7a6dbea58e8))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Automatically refresh the updater state ([596dc06](https://github.com/Hypfer/Valetudo/commit/596dc067a6e77d908e3dc11b3e60aeab1e72bd07))\r\n* **ui:** Transparently decompress the v2 map data in the api client ([0bcb974](https://github.com/Hypfer/Valetudo/commit/0bcb974fd9c1ffa8c164b494899ef9c9e1735091)), closes [#1262](https://github.com/Hypfer/Valetudo/issues/1262)\r\n* **updater:** Ignore github release drafts and prereleases ([ad97a14](https://github.com/Hypfer/Valetudo/commit/ad97a146b0989f7caf21c3b834849aca75b9bdc3))\r\n* **ui:** Try avoiding bright flashes on initial loading ([f84a51d](https://github.com/Hypfer/Valetudo/commit/f84a51dc7c09ec4a7cb19e40e3889544375af58a))\r\n* Fix log sse endpoint ([fd6f0e2](https://github.com/Hypfer/Valetudo/commit/fd6f0e2d34ebc2f9de4aa5b23da2fa8ec2e4d630)), closes [#1256](https://github.com/Hypfer/Valetudo/issues/1256)\r\n* **mqtt:** Fix unit_of_measurement for current statistics and consumables ([7f052dc](https://github.com/Hypfer/Valetudo/commit/7f052dc3f64905afd69e35de217cd390377e6ce2))\r\n* **ntpClient:** Delay initial ntp sync to wait for valetudo to start up properly ([727af04](https://github.com/Hypfer/Valetudo/commit/727af04ab54d007c21a3c6ac270036611280e112))\r\n* **ui:** AppBar and menu should not be user-selectable ([69754b7](https://github.com/Hypfer/Valetudo/commit/69754b7204efe81ba147539a04630d644d0e07f4))\r\n* **ui:** Cleanup unused code ([c050940](https://github.com/Hypfer/Valetudo/commit/c05094011540c46737e7829532a319756255b2f3))\r\n* **ui:** Fix map zoom behavior for trackpoint and trackpad scroll zoom ([ca94600](https://github.com/Hypfer/Valetudo/commit/ca9460095eb6e4946f7653328667e8df60c678dc))\r\n* **ui:** Updater changelog should stay in its constraints ([5d815bf](https://github.com/Hypfer/Valetudo/commit/5d815bf98f334b9f40faecaf00f918bb6fecaacb))\r\n* **updater:** Ensure that there is enough space besides process.argv0 to store the new binary ([c298e98](https://github.com/Hypfer/Valetudo/commit/c298e9833cc6dcb2457a52b986daa8f2e81a8850))\r\n* **vendor.dreame:** Fix wrong segment iteration count ([9fd9c17](https://github.com/Hypfer/Valetudo/commit/9fd9c1723e0329b76b89e84cca108cc117a2a736))\r\n* **vendor.dreame:** There are actually no firmware limits for virtual restrictions ([8a8b536](https://github.com/Hypfer/Valetudo/commit/8a8b536b2eb126b9604b58e58cf196824da63be1))\r\n* **vendor.roborock:** Fix resetting incomplete map on Roborock. Detect and reset current map slot. ([#1252](https://github.com/Hypfer/Valetudo/issues/1252)) ([ba86057](https://github.com/Hypfer/Valetudo/commit/ba86057ba7946ee90c6ee7408ca446de56d23136))\r\n* Fix CurrentStatistics UI refresh ([93249ad](https://github.com/Hypfer/Valetudo/commit/93249ad142d4879ea967898f26905645af1c4f2b))\r\n* **ui:** Fix LogViewer overflow-wrap ([4799027](https://github.com/Hypfer/Valetudo/commit/4799027a42e6f5216cb748c75b88b1291a863335))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1267", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037/reactions", + "total_count": 5, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 4, + "rocket": 1, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54654293", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54654293/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/54654293/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.12.0", + "id": 54654293, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DQfVV", + "tag_name": "2021.12.0", + "target_commitish": "master", + "name": "Valetudo 2021.12.0", + "draft": false, + "prerelease": true, + "created_at": "2021-12-05T11:20:47Z", + "published_at": "2021-12-05T11:33:26Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51048888", + "id": 51048888, + "node_id": "RA_kwDOCGKICM4DCvG4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34173355, + "download_count": 311, + "created_at": "2021-12-05T11:39:58Z", + "updated_at": "2021-12-05T11:39:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049177", + "id": 51049177, + "node_id": "RA_kwDOCGKICM4DCvLZ", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13854315, + "download_count": 5, + "created_at": "2021-12-05T11:47:57Z", + "updated_at": "2021-12-05T11:47:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51048882", + "id": 51048882, + "node_id": "RA_kwDOCGKICM4DCvGy", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015327, + "download_count": 1286, + "created_at": "2021-12-05T11:39:55Z", + "updated_at": "2021-12-05T11:39:56Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51048887", + "id": 51048887, + "node_id": "RA_kwDOCGKICM4DCvG3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015327, + "download_count": 290, + "created_at": "2021-12-05T11:39:57Z", + "updated_at": "2021-12-05T11:39:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049176", + "id": 51049176, + "node_id": "RA_kwDOCGKICM4DCvLY", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13270047, + "download_count": 15, + "created_at": "2021-12-05T11:47:56Z", + "updated_at": "2021-12-05T11:47:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049175", + "id": 51049175, + "node_id": "RA_kwDOCGKICM4DCvLX", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13269623, + "download_count": 18, + "created_at": "2021-12-05T11:47:55Z", + "updated_at": "2021-12-05T11:47:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049178", + "id": 51049178, + "node_id": "RA_kwDOCGKICM4DCvLa", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1802, + "created_at": "2021-12-05T11:47:59Z", + "updated_at": "2021-12-05T11:47:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.12.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.12.0", + "body": "
\r\n \"valetudo\"\r\n

2021.12.0

\r\n
\r\n\r\nMap data format changes, quality of life improvements and bugfixes.\r\n\r\n## Map data format changes\r\n\r\nThis release features the first version increment of the ValetudoMap data format.\r\nInitially, in version 1, pixel data such as walls or floor were stored as a huge array of coordinate pairs: \r\n`[x0, y0, x1, y1, ...]`. This was not a very efficient way of storing that data as most of it is redundant.\r\n\r\nThis resulted in map files that were over 1 MiB in size being pushed to your browser every 3 seconds.\r\n\r\nTo combat this, some thought was put into how the data is stored.\r\nIf you have a row of pixels, all of them will have the same y-coordinate, meaning that you only have to store that once.\r\nPeople already figured that out [in the 60s](https://en.wikipedia.org/wiki/Run-length_encoding).\r\n\r\nWith Map V2, pixels are stored as `[xStart0, y0, count0, xStart1, y1, count1, ...]` where `[xStart, y]` is the starting point and `count` represents additional pixels with the same y-coordinate to the right.\r\n\r\nThis resulted in V2 map files using between 5% and 15% of the size of the equivalent V1 map.\r\nThe huge testfile map for example was compressed from 847 kB to 75 kB.\r\n\r\n\r\nWhile this is a **breaking change**, the breakage actually isn't that big of a change as V2 can easily be converted back to V1.\r\nIn fact, running `JSON.parse()` on a V2 map and then converting it to a V1 one in memory is more than twice as fast as running `JSON.parse()` on a V1 map.\r\n\r\nSince this change drastically reduces the traffic caused by live maps, I expect to see general usability and reliability\r\nimprovements in situations where the Wi-Fi reception isn't that great.\r\n\r\n\r\n## LogViewer\r\n\r\nThe LogViewer has been greatly improved and now features a structured and color-coded view of your log.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744519-5ba963b9-6409-4e04-95d9-e73caf55021c.png)\r\n\r\nYou can use the text filter at the top to either filter for the loglevel or the message contents.\r\nJust start typing.\r\n\r\n## UI Help\r\n\r\nBoth consumables and timers now feature a help button, which shall explain how to use these features.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744625-d113d697-e4e1-4f77-a3a2-596ad88131a5.png)\r\n\r\n\r\n## Misc\r\n\r\n- Map reset on newer roborock models should now be fixed thanks to @supersmile2009\r\n- Zooming the map should now work much better if you zoom via a touchpad or trackpoint instead of a mousewheel\r\n- MQTT current statistics now have a unit_of_measurement in HA\r\n- Lowmem builds now have a reduced map poll rate to reduce memory pressure\r\n- Valetudo now manages its logfile size to prevent it from growing indefinitely\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Automatically clear the logfile when it gets too large ([c0698b4](https://github.com/Hypfer/Valetudo/commit/c0698b43dda5144d7d0c2c58d9336a1c0662cc65))\r\n* Reduce map polling interval for lowmem hosts ([fcf94ce](https://github.com/Hypfer/Valetudo/commit/fcf94ceeb60f9b46e25bfa04d2e4e88ac2a25926))\r\n* **ntpClient:** Improve log messages ([8880bbf](https://github.com/Hypfer/Valetudo/commit/8880bbfc7ed79969a61c6d6e51f7023c23d7561e))\r\n* **ui:** Add help button + modal to consumables view ([d1388f1](https://github.com/Hypfer/Valetudo/commit/d1388f124dae0046d2bee49345d0513441926f21))\r\n* **ui:** Add timers help ([c864170](https://github.com/Hypfer/Valetudo/commit/c864170d44c2b686394bb6d770cff937e8a9de43))\r\n* **ui:** Implement LogViewer component ([1b96ae0](https://github.com/Hypfer/Valetudo/commit/1b96ae06c8a74acbc9a6fa03cf941736520e30d0))\r\n* **ui:** Remove obsolete about > github release info ([253d9f9](https://github.com/Hypfer/Valetudo/commit/253d9f99b0965859705c52ffae9483c381d49ad7))\r\n* **ui:** Swap Manual control cw & ccw rotation button ([44eab06](https://github.com/Hypfer/Valetudo/commit/44eab06eadcd57c8c9b3784bc6f4c7a6dbea58e8))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Try avoiding bright flashes on initial loading ([f84a51d](https://github.com/Hypfer/Valetudo/commit/f84a51dc7c09ec4a7cb19e40e3889544375af58a))\r\n* Fix log sse endpoint ([fd6f0e2](https://github.com/Hypfer/Valetudo/commit/fd6f0e2d34ebc2f9de4aa5b23da2fa8ec2e4d630)), closes [#1256](https://github.com/Hypfer/Valetudo/issues/1256)\r\n* **mqtt:** Fix unit_of_measurement for current statistics and consumables ([7f052dc](https://github.com/Hypfer/Valetudo/commit/7f052dc3f64905afd69e35de217cd390377e6ce2))\r\n* **ntpClient:** Delay initial ntp sync to wait for valetudo to start up properly ([727af04](https://github.com/Hypfer/Valetudo/commit/727af04ab54d007c21a3c6ac270036611280e112))\r\n* **ui:** AppBar and menu should not be user-selectable ([69754b7](https://github.com/Hypfer/Valetudo/commit/69754b7204efe81ba147539a04630d644d0e07f4))\r\n* **ui:** Cleanup unused code ([c050940](https://github.com/Hypfer/Valetudo/commit/c05094011540c46737e7829532a319756255b2f3))\r\n* **ui:** Fix map zoom behavior for trackpoint and trackpad scroll zoom ([ca94600](https://github.com/Hypfer/Valetudo/commit/ca9460095eb6e4946f7653328667e8df60c678dc))\r\n* **ui:** Updater changelog should stay in its constraints ([5d815bf](https://github.com/Hypfer/Valetudo/commit/5d815bf98f334b9f40faecaf00f918bb6fecaacb))\r\n* **updater:** Ensure that there is enough space besides process.argv0 to store the new binary ([c298e98](https://github.com/Hypfer/Valetudo/commit/c298e9833cc6dcb2457a52b986daa8f2e81a8850))\r\n* **vendor.dreame:** Fix wrong segment iteration count ([9fd9c17](https://github.com/Hypfer/Valetudo/commit/9fd9c1723e0329b76b89e84cca108cc117a2a736))\r\n* **vendor.dreame:** There are actually no firmware limits for virtual restrictions ([8a8b536](https://github.com/Hypfer/Valetudo/commit/8a8b536b2eb126b9604b58e58cf196824da63be1))\r\n* **vendor.roborock:** Fix resetting incomplete map on Roborock. Detect and reset current map slot. ([#1252](https://github.com/Hypfer/Valetudo/issues/1252)) ([ba86057](https://github.com/Hypfer/Valetudo/commit/ba86057ba7946ee90c6ee7408ca446de56d23136))\r\n* Fix CurrentStatistics UI refresh ([93249ad](https://github.com/Hypfer/Valetudo/commit/93249ad142d4879ea967898f26905645af1c4f2b))\r\n* **ui:** Fix LogViewer overflow-wrap ([4799027](https://github.com/Hypfer/Valetudo/commit/4799027a42e6f5216cb748c75b88b1291a863335))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1259", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54654293/reactions", + "total_count": 7, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 7, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/53791376/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.11.1", + "id": 53791376, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DNMqQ", + "tag_name": "2021.11.1", + "target_commitish": "master", + "name": "Valetudo 2021.11.1", + "draft": false, + "prerelease": false, + "created_at": "2021-11-21T11:30:14Z", + "published_at": "2021-11-21T11:43:51Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49967993", + "id": 49967993, + "node_id": "RA_kwDOCGKICM4C-nN5", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34299417, + "download_count": 284, + "created_at": "2021-11-21T11:50:24Z", + "updated_at": "2021-11-21T11:50:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968319", + "id": 49968319, + "node_id": "RA_kwDOCGKICM4C-nS_", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13979369, + "download_count": 8, + "created_at": "2021-11-21T11:58:19Z", + "updated_at": "2021-11-21T11:58:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49967989", + "id": 49967989, + "node_id": "RA_kwDOCGKICM4C-nN1", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32141389, + "download_count": 1274, + "created_at": "2021-11-21T11:50:18Z", + "updated_at": "2021-11-21T11:50:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49967991", + "id": 49967991, + "node_id": "RA_kwDOCGKICM4C-nN3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32141389, + "download_count": 322, + "created_at": "2021-11-21T11:50:20Z", + "updated_at": "2021-11-21T11:50:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968318", + "id": 49968318, + "node_id": "RA_kwDOCGKICM4C-nS-", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13396701, + "download_count": 15, + "created_at": "2021-11-21T11:58:18Z", + "updated_at": "2021-11-21T11:58:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968317", + "id": 49968317, + "node_id": "RA_kwDOCGKICM4C-nS9", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13396869, + "download_count": 14, + "created_at": "2021-11-21T11:58:17Z", + "updated_at": "2021-11-21T11:58:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968320", + "id": 49968320, + "node_id": "RA_kwDOCGKICM4C-nTA", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1654, + "created_at": "2021-11-21T11:58:21Z", + "updated_at": "2021-11-21T11:58:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.11.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.11.1", + "body": "
\r\n \"valetudo\"\r\n

2021.11.1

\r\n
\r\n\r\nBugfixes, polishing, two minor breaking changes and new features.\r\nDon't forget: If you're running Valetudo 2021.11.0, you can now use the integrated updater :)\r\n\r\n## UI\r\n\r\n### Polishing\r\n\r\n- Controls in the UI were slightly rearranged/reworked.\r\n- The mobile controls drawer now works slightly different and more importantly more reliably with better performance (+ 50kb less bundle size).\r\n- There's a neat loading splashscreen, which you should only see for longer than a second if your Wi-Fi sucks\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760316-4af4fd83-79dd-4c42-857f-fa71ef2d2bc2.png) ![image](https://user-images.githubusercontent.com/974410/142760318-2b74c894-0572-4a55-8c71-6a655660f081.png)\r\n\r\n\r\n### Provisioning\r\n\r\nThe UI now checks if the robot is connected to a Wi-Fi network and if not opens a special provisioning page.\r\nIt's pretty neat and also fixes the issue of Dreames not being provisionable with the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760331-ee5a4031-c692-49be-9ad8-4144f35bb5e0.png)\r\n\r\n\r\n## Backend\r\n\r\n### CurrentStatisticsCapability\r\n\r\nStatistics related to the current (or most recent) operation of the robot are now back.\r\nYes, they are also being published to MQTT. Stop asking.\r\n\r\nData is published to MQTT as machine-readable (seconds for runtime, cm² for the area) as it is meant to build automations with it.\r\nUsing cm² instead of m² saves us from having to deal with floats.\r\n\r\n### TotalStatisticsCapability\r\n\r\nMore importantly, you can now get total statistics from your robot. \r\n\r\nDepending on your model those can be\r\n\r\n- Total operation count\r\n- Total runtime\r\n- Total area\r\n\r\nThis isn't available via the UI yet as it is yet TBD how to do that.\r\nMaybe have like badges, achievements or a rank system?\r\nMaybe have random trivia related to the numbers? (e.g. having cleaned 0.0001% of the Saarland)\r\n\r\nFeel free to leave your input in the comments. ~~Like, subscribe and click the bell icon~~\r\nIf you're good with graphics design, something like e.g. a Corporal IV vacuum robot badge would be a great contribution.\r\n\r\n## Zeroconf hostname changes\r\n\r\nBy actually reading the relevant RFCs, we've discovered that `valetudo_something.local` is not a valid bonjour hostname as the `_` is illegal.\r\nWhile it does seem to work in most setups, it might cause problems in some, which is why starting with this release, Valetudo will use an RFC-compliant hostname: `valetudo-something.local`.\r\n\r\nPlease **update your bookmarks** if you were using any.\r\n\r\n\r\n## MQTT\r\n\r\n### Home Assistant 2021.11 MQTT Changes\r\n\r\nValetudo 2021.11.1 makes use of new features introduced in Home Assistant 2021.11 (namely `configuration_url` and `entity_category`).\r\nThis means that **Home Assistant >= 2021.11 is now required** if you want to use it with Valetudo.\r\n\r\nYou might also have to delete your Valetudo device in HA and let it get rediscovered so that the changes are applied properly.\r\n\r\nIt now looks like this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760339-aa5b2314-692d-4167-9689-cec21f718924.png)\r\n\r\n\r\n### Possible MQTT OOM fixes\r\n\r\nWe have received unconfirmed, unsubstantiated and possibly falsified reports of Valetudo going OOM related to Wi-Fi connectivity issues and the MQTT interface.\r\n\r\nTo combat this, Valetudo now drops any outgoing MQTT message if there are more than 1 MiB of outgoing messages buffered. This may or may not ever happen.\r\nIf you see a warning in your log related to this, please report back. I have not been able to reproduce this.\r\n\r\n### Homie Consumables\r\n\r\nHome consumable durations are now reported as an int. This should fix issues with OpenHab.\r\n\r\n## Bugfixes\r\n\r\n### Dreame paths\r\n\r\nDreame paths now parse to multiple path map entities instead of a single one, which fixes the visual with lines going straight across the map connecting the previous path to the next one.\r\nConsumers of the Valetudo map data might have to be updated to properly display multiple path entities.\r\n\r\n### 1C-related fixes\r\n\r\nI've bought a Dreame 1C to do some QA, which led to a few fixes.\r\nI'm now quite happy with the current state of its implementation in Valetudo.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** CurrentStatisticsCapability ([8e4e183](https://github.com/Hypfer/Valetudo/commit/8e4e1839c217cc081f3172f227e935c2dc616bf1))\r\n* **core:** CurrentStatisticsCapability & TotalStatisticsCapability properties ([4fc9df2](https://github.com/Hypfer/Valetudo/commit/4fc9df271af4dbb9a9c1841d5f23a292d8cd0af3))\r\n* **core:** Introduce ConsumableMonitoringCapability properties and remove mqtt consumables hack ([a998ee1](https://github.com/Hypfer/Valetudo/commit/a998ee1eeeba2fd808c797bed719933d85922252))\r\n* **core:** TotalStatisticsCapability ([55b6696](https://github.com/Hypfer/Valetudo/commit/55b6696ecfb7f6d86b34da2e9e37b07287f8ef68))\r\n* **MockRobot:** Add MockCurrentStatisticsCapability + fix MockConsumableMonitoringCapability ([bda0b1a](https://github.com/Hypfer/Valetudo/commit/bda0b1adc54c8b651a3d23db8a4dc4638b460e48))\r\n* **mqtt:** Homie consumables should always be int ([c39ad93](https://github.com/Hypfer/Valetudo/commit/c39ad9380fc1d4cf752a3d95f0f57512e608c64f))\r\n* **mqtt:** Limit outgoing message buffer size to prevent OOM situations ([1a74f91](https://github.com/Hypfer/Valetudo/commit/1a74f9114de877f01b728e281b843e8459100b0f))\r\n* **mqtt:** Publish current statistics to mqtt ([102a078](https://github.com/Hypfer/Valetudo/commit/102a07890fe0a13efbda8b568b177fa4940478be))\r\n* **ui:** Add Valetudo loading splash ([a7ca33c](https://github.com/Hypfer/Valetudo/commit/a7ca33c845fa1e32d1a217115e48cd534c38b7bb))\r\n* **ui:** Collapse preset selection controls ([4f8aaec](https://github.com/Hypfer/Valetudo/commit/4f8aaec2f43b9e1a3bb21df88083b80509652fde))\r\n* **ui:** Display current statistics ([0fbc182](https://github.com/Hypfer/Valetudo/commit/0fbc182b0998cf1b3804b52ef24ee5d2d14c1b21))\r\n* **ui:** Slightly decrease required zoom level for segment label text ([08209a3](https://github.com/Hypfer/Valetudo/commit/08209a3164156db6e5e3ba340342bfbbf75bd7e3))\r\n* **vendor.dreame:** Total and current statistics for the 1C ([c1a51e9](https://github.com/Hypfer/Valetudo/commit/c1a51e916a9d123fcd6f9621eff02b645f79d702))\r\n* Provision Wizard thingy ([a6f6ded](https://github.com/Hypfer/Valetudo/commit/a6f6dedc851d6852e7b25ba1dc5222f3130ef210))\r\n* **ui:** Reorder state display ([828e54d](https://github.com/Hypfer/Valetudo/commit/828e54da624d2e00f500499e3497867fdb2ad6eb))\r\n* **ui:** Replace bottom sheet with simpler mobile controls ([17ff7ec](https://github.com/Hypfer/Valetudo/commit/17ff7ecb1105d9904f382a15b92dd5a6b988dd1f))\r\n* **vendor.dreame:** DreameCurrentStatisticsCapability ([656a19e](https://github.com/Hypfer/Valetudo/commit/656a19ee39f1411bb962e61077486d9336dd79b5))\r\n* **vendor.dreame:** DreameTotalStatisticsCapability ([4bb9342](https://github.com/Hypfer/Valetudo/commit/4bb934208ff52ad7fc1f42b82e5046362353ab6a))\r\n* **vendor.roborock:** RoborockCurrentStatisticsCapability ([93aa77b](https://github.com/Hypfer/Valetudo/commit/93aa77b09b7924baf5fce594d6455f4a5f51837e))\r\n* **vendor.roborock:** RoborockKeyLockCapability ([#1222](https://github.com/Hypfer/Valetudo/issues/1222)) ([02e155c](https://github.com/Hypfer/Valetudo/commit/02e155cec954cc75e41c5fcbf8ebe37acffb4c37))\r\n* **vendor.roborock:** RoborockTotalStatisticsCapability ([e0cbbff](https://github.com/Hypfer/Valetudo/commit/e0cbbff7470426119dd1eff6bde064a9387209b5))\r\n* **vendor.viomi:** ViomiCurrentStatisticsCapability ([9dd1091](https://github.com/Hypfer/Valetudo/commit/9dd1091cbc7a63ac7c0f61b40bc73abd026572bc))\r\n* **webserver:** Add 404 page ([8f5095c](https://github.com/Hypfer/Valetudo/commit/8f5095cac124c0ee0a6b8cdece07223c3374c51f))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Attempt to mitigate problems related to connectivity issues ([cf0f2d6](https://github.com/Hypfer/Valetudo/commit/cf0f2d691017ac69635d17f04062c260ebf62091))\r\n* **mqtt:** homie.durationsAsInteger should not be a breaking change ([bbd918a](https://github.com/Hypfer/Valetudo/commit/bbd918ac35530c0a7a8e8b684ebbe05967506bfc))\r\n* **ui:** Align preset selection labels with icons ([c6803f6](https://github.com/Hypfer/Valetudo/commit/c6803f6e2d5a60172d945bd62ab47badd679d234))\r\n* **ui:** Attachment buttons should be disabled ([922572a](https://github.com/Hypfer/Valetudo/commit/922572a779e0e1402ca53bb3e9b8a1c82605ea70))\r\n* **ui:** Fix CurrentStatistics trying to map something that isn't an array ([4d6f3d8](https://github.com/Hypfer/Valetudo/commit/4d6f3d869202288fb48bc50ee38d124c611fac78))\r\n* **ui:** Fix mobile control scrolling ([6264400](https://github.com/Hypfer/Valetudo/commit/6264400a473b36aff9f5409a5e157de536389e6d))\r\n* **ui:** Only check for provisioning once ([6bd0480](https://github.com/Hypfer/Valetudo/commit/6bd0480d8d40600aa5f438d060a21b2ba775925a))\r\n* **ui:** Only regular mouse clicks should interact with the map ([d452d88](https://github.com/Hypfer/Valetudo/commit/d452d88206afafbf4017138fa8b52edd38f1f70d))\r\n* **ui:** Preset selection labels should not be user selectable ([965a061](https://github.com/Hypfer/Valetudo/commit/965a0610c2dd73e028f944ed3a49a5e3c507d7e6))\r\n* **ui:** Swap presetSelection open/close icons ([380109b](https://github.com/Hypfer/Valetudo/commit/380109baa7bc6abfb06169eaeac036a7235af005))\r\n* **ui:** The whole controls body should not be user-selectable ([861f15f](https://github.com/Hypfer/Valetudo/commit/861f15f6da3633c266f0fbca8471193642b8ae57))\r\n* **vendor.dreame:** 1C shall ignore persistent map property updates ([5744346](https://github.com/Hypfer/Valetudo/commit/5744346272bf443ca734da77c5af938a559d314b))\r\n* **vendor.dreame:** Assume that we're in the docked state if we're charging on the 1C ([c73e062](https://github.com/Hypfer/Valetudo/commit/c73e06207c098deae3e596de135c5e2cbf50f4da))\r\n* **vendor.dreame:** Fine-tune 1C manual control ([72614e2](https://github.com/Hypfer/Valetudo/commit/72614e29977297078cf37425be361ad5310aad07))\r\n* **vendor.dreame:** Fine-tune manual control ([cc267c7](https://github.com/Hypfer/Valetudo/commit/cc267c75fe02178343cbddd43099ff59cfe8b16f))\r\n* **vendor.dreame:** Fix Dreame1CManualControlCapability ([9c85ca5](https://github.com/Hypfer/Valetudo/commit/9c85ca5f8c09dc5e1371f4b805767a6bec54175c))\r\n* **vendor.dreame:** Properly parse path data to multiple paths ([e083af2](https://github.com/Hypfer/Valetudo/commit/e083af2759f37706cda1e45a0b083b0782112f3b))\r\n* **vendor.dreame:** Remove capabilities for models that don't support them ([0d6d6ad](https://github.com/Hypfer/Valetudo/commit/0d6d6ad3ad44bdadb9ceea830652e8e742487776))\r\n* **vendor.dreame:** The 1C does not support multiple iterations for segment cleanups ([2d35bd9](https://github.com/Hypfer/Valetudo/commit/2d35bd9a0f00f52f9e0a67dae5f31d50e7a87cb3))\r\n* **vendor.viomi:** Fix ViomiPersistentMapControlCapability ([#1218](https://github.com/Hypfer/Valetudo/issues/1218)) ([80d7bb2](https://github.com/Hypfer/Valetudo/commit/80d7bb2bd91377d1c06a0c6afa4a262d0b7511e7))\r\n* Fix LinuxWifiConfigurationCapability not_connected state reporting ([25271f2](https://github.com/Hypfer/Valetudo/commit/25271f24c95976bae9b201ff1a6d2625c3e643a1))\r\n* **vendor.roborock:** RoborockSpeakerVolumeControlCapability.getVolume() should return a number ([32898d1](https://github.com/Hypfer/Valetudo/commit/32898d1cd27b3498f00e6dd4d67c2de09d0ec1ed))\r\n* **vendor.viomi:** Fix volume control ([0269182](https://github.com/Hypfer/Valetudo/commit/0269182f5e94d055d908b9c16e1524ef5a9f949d))\r\n* **webserver:** try/catch for SpeakerVolumeControlCapabilityRouter ([5cb7c5a](https://github.com/Hypfer/Valetudo/commit/5cb7c5ac3c09c9138ac11316aff3c7dcfa22fde1))\r\n* Nested assign configuration defaults + don't persist if there are no changes to persist ([b12c452](https://github.com/Hypfer/Valetudo/commit/b12c452b4d693326d0ebec81bf6b1145c8ca9de5))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1223", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376/reactions", + "total_count": 11, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 10, + "confused": 0, + "heart": 1, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/51929111/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.11.0", + "id": 51929111, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DGGAX", + "tag_name": "2021.11.0", + "target_commitish": "master", + "name": "Valetudo 2021.11.0", + "draft": false, + "prerelease": false, + "created_at": "2021-10-24T11:34:45Z", + "published_at": "2021-10-24T11:41:55Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47746670", + "id": 47746670, + "node_id": "RA_kwDOCGKICM4C2I5u", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34461299, + "download_count": 254, + "created_at": "2021-10-24T11:48:38Z", + "updated_at": "2021-10-24T11:48:38Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747076", + "id": 47747076, + "node_id": "RA_kwDOCGKICM4C2JAE", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14141395, + "download_count": 12, + "created_at": "2021-10-24T11:56:41Z", + "updated_at": "2021-10-24T11:56:41Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47746666", + "id": 47746666, + "node_id": "RA_kwDOCGKICM4C2I5q", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32303271, + "download_count": 578, + "created_at": "2021-10-24T11:48:35Z", + "updated_at": "2021-10-24T11:48:36Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47746669", + "id": 47746669, + "node_id": "RA_kwDOCGKICM4C2I5t", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32303271, + "download_count": 346, + "created_at": "2021-10-24T11:48:36Z", + "updated_at": "2021-10-24T11:48:37Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747075", + "id": 47747075, + "node_id": "RA_kwDOCGKICM4C2JAD", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13557831, + "download_count": 19, + "created_at": "2021-10-24T11:56:40Z", + "updated_at": "2021-10-24T11:56:40Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747073", + "id": 47747073, + "node_id": "RA_kwDOCGKICM4C2JAB", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13558111, + "download_count": 17, + "created_at": "2021-10-24T11:56:39Z", + "updated_at": "2021-10-24T11:56:39Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747077", + "id": 47747077, + "node_id": "RA_kwDOCGKICM4C2JAF", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 46, + "created_at": "2021-10-24T11:56:43Z", + "updated_at": "2021-10-24T11:56:43Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.11.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.11.0", + "body": "
\r\n \"valetudo\"\r\n

2021.11.0

\r\n
\r\n\r\nLikely the most important release of the year.\r\n\r\n## Recap 0.6.1 to 2021.11.0\r\nApparently, Valetudo 0.6.1 was released only a bit more than a year ago, but tbh it feels like an eternity.\r\nSo much has changed since then. The iteration speed of the project has been insane in the last months.\r\nAs we've now finished most if not all of the huge tasks, I expect things to slow down a little.\r\n\r\nHere's a quick recap of what happened since 0.6.1:\r\n\r\n- Complete core rewrite to easily support multiple vendors and different robots\r\n- A proper REST-API documented with Swagger UI\r\n- Complete MQTT rewrite to support Home Assistant as well as Homie\r\n- Easy map display in Home Assistant via MQTT and the custom lovelace valetudo map card\r\n- Complete UI rewrite based on a proper UI framework\r\n- Support for all relevant features of the robots\r\n- Support for autodiscovery of Valetudo-enabled robots via mDNS and SSDP\r\n- Support for Dreame-made robots\r\n- An [android companion app](https://valetudo.cloud/pages/companion_apps/valetudo_companion.html) that makes use of said autodiscovery feature\r\n- [Valeronoi](https://valetudo.cloud/pages/companion_apps/valeronoi.html): A companion app that generates Wi-Fi signal strength maps using Valetudo\r\n- An updater functionality\r\n- [Proper docs](https://valetudo.cloud/)\r\n- General polishing. A lot of it\r\n\r\n\r\n## Default new UI\r\n\r\nStarting with this release, the new react-based UI introduced by @jomik with large contributions by @ccoors is now the default.\r\n\r\nThe existing map renderer was ported to react with a few quality of life improvements:\r\n\r\n- You can now specify an iteration count when cleaning segments or zones\r\n- Layers are now sorted, meaning that walls will always be on top. This solves some visual issues of vSlam-based devices\r\n- Adding a new zone/virtual wall/etc. will now spawn it in the middle of your viewport \r\n- Map segment labels now attempt to actually be inside the segment they're for. This fixes issues with cornered hallways. No more stray triangles\r\n- Editing the map will now refresh your current view instead of navigating back\r\n- Rendering has been partly moved to a webworker for improved performance\r\n\r\nSpeaking of navigating back: Given that the new UI is based on a frontend framework including proper routing,\r\nwe now have a working back button. Amazing!\r\n\r\nThe only thing not yet available in the new UI is management of Zone and GoTo presets. This will be added later.\r\nFor now, please navigate to the old UI via the menu and use that.\r\n\r\n\r\n### Screenshots\r\n\r\n#### Phone/Mobile\r\n![image](https://user-images.githubusercontent.com/974410/138561830-e0a3edf7-1974-49cf-90a8-31e677b482d2.png) ![image](https://user-images.githubusercontent.com/974410/138561931-41b68344-f260-4343-9c79-ef85e56d9786.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138561874-f5e5fee9-81dd-43fb-9de0-75263169a0e6.png) ![image](https://user-images.githubusercontent.com/974410/138561884-9633600b-3362-454b-b95d-90f8e5951971.png)\r\n\r\n\r\n#### Tablet/Desktop\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138562037-05bc5140-d7af-488b-8734-72e66b820192.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138561911-77aa8d10-3918-4eb7-96ff-8a6d0440dfce.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138562111-3cbfe03c-7a19-4e57-9bfb-6b872239f432.png)\r\n\r\n\r\n## Updater\r\n\r\nStarting with this release, Valetudo will be capable of updating itself with the press of a button.\r\n\r\nThis has been a long-requested feature and considering how mature this whole project has become, I decided that\r\nit was finally time to actually implement that.\r\nAs it is implemented now, it uses the GitHub API by default, meaning that I am not able to track you.\r\n\r\nThere's also no automatic update check, because periodical pings to some cloud service are obviously problematic.
\r\nYou will decide when to press the \"Check for Updates\" button and also when to update.\r\n\r\n## More stickers\r\n\r\nI've decided to get a few more stickers printed because merch\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138592502-4c6d150e-ecde-46ea-9ce4-7da8fdb77431.png)\r\n\r\n## Misc\r\n\r\nI'm currently looking for a job that isn't a corporate hellhole with nice people doing interesting stuff.\r\nIf you're a likeminded hacker looking for a new colleague or know someone who does feel free to ping me\r\n\r\nThanks :)\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Add Valetudo logo to bottom sheet ([76eeaff](https://github.com/Hypfer/Valetudo/commit/76eeaffd4aa273e351d9306d4660df196380b275))\r\n* **ui:** Bring back the old map renderer ([7aa6822](https://github.com/Hypfer/Valetudo/commit/7aa6822e20ef026a73bcfebcf76c9bbd49ce2a94))\r\n* **ui:** Change map colors according to theme in use ([b17745e](https://github.com/Hypfer/Valetudo/commit/b17745e2ca70a9b24982f70cfc2272130cd1e9a4))\r\n* **ui:** Fan speed icon and battery level bar improvements ([d0a0671](https://github.com/Hypfer/Valetudo/commit/d0a06712315f0dc7b93fc35ee9f9270a9204df7e))\r\n* **ui:** Improve controls ([b678cda](https://github.com/Hypfer/Valetudo/commit/b678cdac0f2a15e1a3191f2125fbbaabbc7af833))\r\n* **ui:** Map Editing ([35feb65](https://github.com/Hypfer/Valetudo/commit/35feb654e76599d0c267ed118453f3c25e4b8fbd))\r\n* **ui:** Move locate to the map view ([32de2b8](https://github.com/Hypfer/Valetudo/commit/32de2b83daf1e03fa16b1115713a9290abc05029))\r\n* **ui:** Place new client structures in the middle of the viewport ([d9d2a64](https://github.com/Hypfer/Valetudo/commit/d9d2a6436bd6ea24dd431b24776c93587114cfba))\r\n* **ui:** Remove map transparency ([ace000b](https://github.com/Hypfer/Valetudo/commit/ace000b922a426076db49aaa25e1cbf4207b0ad8))\r\n* **ui:** Remove obsolete segment controls ([9912cf5](https://github.com/Hypfer/Valetudo/commit/9912cf58f60a6ca88517786bb9fc6afccf9a5cf0))\r\n* **updater:** Introduce ValetudoUpdaterNoUpdateRequiredState ([354028e](https://github.com/Hypfer/Valetudo/commit/354028e6f4f23e8c61a9f2e302edcaecf7807fe6))\r\n* Updater ([5db2c55](https://github.com/Hypfer/Valetudo/commit/5db2c554dc9905352c310f4be7d6130a26f7730c))\r\n* **ui:** Remove Accordion from interface settings ([c4c31bb](https://github.com/Hypfer/Valetudo/commit/c4c31bb5a68757a6ec687c3dde436f26374a2fdc))\r\n* **ui:** Set the new UI as the default ([c0f90fb](https://github.com/Hypfer/Valetudo/commit/c0f90fb90f44d7020db016cfe9129d80f8df7d56))\r\n* **ui:** Use a WebWorker for rendering the map layers when possible ([3eafded](https://github.com/Hypfer/Valetudo/commit/3eafded6c62a420795f6f910ca5b933f29a7e5f6))\r\n* **ui:** Use real swagger icon in sidebar ([#1160](https://github.com/Hypfer/Valetudo/issues/1160)) ([f4c0093](https://github.com/Hypfer/Valetudo/commit/f4c0093527be1ae3ce6fa298bd878b3cc5b1283c))\r\n* **ValetudoEvents:** Add Mop Attachment Reminder event ([ac268d7](https://github.com/Hypfer/Valetudo/commit/ac268d765f93c33aba14ad7ffd8602d00a02985e))\r\n* Add nonce to every instance of a Valetudo map ([f0489f1](https://github.com/Hypfer/Valetudo/commit/f0489f15260f8eb368bc6b759029a022781bebf9))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* Fix MopAttachmentReminderValetudoEvent not being a DismissibleValetudoEvent ([302f6ce](https://github.com/Hypfer/Valetudo/commit/302f6cefc3f155d45589ea1cf50ed39fc983b5d3))\r\n* **mqtt:** Fix consumable state attribute data being published multiple times ([894bba9](https://github.com/Hypfer/Valetudo/commit/894bba9c9b99a5b67f584dbaa9e1571ffa18812c))\r\n* **mqtt:** Fix zone cleanup ([#1130](https://github.com/Hypfer/Valetudo/issues/1130)) ([bb951b2](https://github.com/Hypfer/Valetudo/commit/bb951b2fcddb6435bfe6b838044cc2af7b0c235f))\r\n* **mqtt:** Hopefully avoid a deadlock ([c3313ea](https://github.com/Hypfer/Valetudo/commit/c3313eac738cf8d5dc1a05f3c60308e4b002dd3a))\r\n* **ui:** Allow more states for zone/segment cleanup and goto ([c738938](https://github.com/Hypfer/Valetudo/commit/c738938cc0d8140ce91011db8420df7a6768c893))\r\n* **ui:** Better placement of segment labels ([ba788a0](https://github.com/Hypfer/Valetudo/commit/ba788a0da1042106cac698e5de9f20d6e7bb89f5))\r\n* **ui:** Combinations of scrolling and touch events also should not cause any jank ([e36c40f](https://github.com/Hypfer/Valetudo/commit/e36c40f2a66a67baebd75da13ed8bb84cd26d371))\r\n* **ui:** Fix controls jumping around when there is a status flag ([c641fb1](https://github.com/Hypfer/Valetudo/commit/c641fb10e3bc2a7e56a9e6a388be1d479fb6c91b))\r\n* **ui:** Fix draw order for ControlsBottomSheet ([c46ef10](https://github.com/Hypfer/Valetudo/commit/c46ef10981298570bc14a7e9094698b70dd30e94))\r\n* **ui:** Fix SSE not reconnecting after having closed the connection once ([6feaaf8](https://github.com/Hypfer/Valetudo/commit/6feaaf807065f3e5d585c9f723e8b48f9aa32621))\r\n* **ui:** Further improve segment label placement using the median ([6545cc7](https://github.com/Hypfer/Valetudo/commit/6545cc7fb4077247b08675f8ea10895062996401))\r\n* **ui:** Ignore map updates if the tab is invisible ([370753d](https://github.com/Hypfer/Valetudo/commit/370753dcd5bb2dd1803d8dac67d3b96759dd94c3))\r\n* **ui:** MQTT port is an integer ([#1159](https://github.com/Hypfer/Valetudo/issues/1159)) ([5b91c96](https://github.com/Hypfer/Valetudo/commit/5b91c96eb8e2928be48b4ef63abbb7c043b34aa9))\r\n* **ui:** Postpone map data updates during pan/zoom to prevent jank ([92a9147](https://github.com/Hypfer/Valetudo/commit/92a9147191981b15d48e4817f7200875470a13fe))\r\n* **ui:** Postpone map data updates during scroll to prevent jank ([adcd117](https://github.com/Hypfer/Valetudo/commit/adcd1174a50b4bce4805da5a36bcf80646eb9979))\r\n* **ui:** Prevent issues with zooming on mobile ([a5057fd](https://github.com/Hypfer/Valetudo/commit/a5057fd7f4dd58b38628f5bbdd4ade951ca6b6fc))\r\n* **ui:** Use the correct canvas size for the map layer renderer ([b55ffa6](https://github.com/Hypfer/Valetudo/commit/b55ffa6cc56d7c7d6bb0c8459ccd1d35252c3b63))\r\n* **ui:** Zone dimensions should be based on the pixelSize ([b317c85](https://github.com/Hypfer/Valetudo/commit/b317c856dbdfe95ab45ea639223d23fca093c464))\r\n* **updater:** Fix fallback download location for roborock ([d515f04](https://github.com/Hypfer/Valetudo/commit/d515f04e5f6695b71567f6818ba2734553c75d03))\r\n* **vendor.dreame:** Fix virtual restriction coordinates being not sorted properly ([17cc303](https://github.com/Hypfer/Valetudo/commit/17cc303cf4726cf4bcbb9597c268273896b52c78))\r\n* **vendor.dreame:** Ignore error 68 ([dd44320](https://github.com/Hypfer/Valetudo/commit/dd44320a390c42f6e36a301931e5006e103a4684))\r\n* **webserver:** Allow unsetting names of segments ([f992e5a](https://github.com/Hypfer/Valetudo/commit/f992e5adce4c4fd997ff4a6c868f95d32a5e214b))\r\n* Use shorter model names ([d268013](https://github.com/Hypfer/Valetudo/commit/d268013b9c93b4dc610cb8374a3316d9e2a842a9))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1175", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111/reactions", + "total_count": 47, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 29, + "confused": 0, + "heart": 18, + "rocket": 0, + "eyes": 0 + }, + "mentions_count": 2 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/50662403/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.10.0", + "id": 50662403, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DBQwD", + "tag_name": "2021.10.0", + "target_commitish": "master", + "name": "Valetudo 2021.10.0", + "draft": false, + "prerelease": false, + "created_at": "2021-10-01T21:19:25Z", + "published_at": "2021-10-01T21:25:10Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46053587", + "id": 46053587, + "node_id": "RA_kwDOCGKICM4CvrjT", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34522555, + "download_count": 269, + "created_at": "2021-10-01T21:33:32Z", + "updated_at": "2021-10-01T21:33:34Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46054033", + "id": 46054033, + "node_id": "RA_kwDOCGKICM4CvrqR", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14203219, + "download_count": 12, + "created_at": "2021-10-01T21:42:35Z", + "updated_at": "2021-10-01T21:42:37Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46053583", + "id": 46053583, + "node_id": "RA_kwDOCGKICM4CvrjP", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32364527, + "download_count": 420, + "created_at": "2021-10-01T21:33:27Z", + "updated_at": "2021-10-01T21:33:29Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46053586", + "id": 46053586, + "node_id": "RA_kwDOCGKICM4CvrjS", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32364527, + "download_count": 278, + "created_at": "2021-10-01T21:33:30Z", + "updated_at": "2021-10-01T21:33:31Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46054032", + "id": 46054032, + "node_id": "RA_kwDOCGKICM4CvrqQ", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13619079, + "download_count": 23, + "created_at": "2021-10-01T21:42:34Z", + "updated_at": "2021-10-01T21:42:35Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46054031", + "id": 46054031, + "node_id": "RA_kwDOCGKICM4CvrqP", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13619623, + "download_count": 20, + "created_at": "2021-10-01T21:42:32Z", + "updated_at": "2021-10-01T21:42:33Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47462841", + "id": 47462841, + "node_id": "RA_kwDOCGKICM4C1Dm5", + "name": "valetudo_release_manifest.json", + "label": null, + "uploader": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 559, + "download_count": 14, + "created_at": "2021-10-20T17:57:24Z", + "updated_at": "2021-10-20T17:57:32Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.10.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.10.0", + "body": "
\r\n \"valetudo\"\r\n

2021.10.0

\r\n
\r\n\r\nAnother release with a lot of UI changes by @ccoors. Also, there's an Android companion App now.\r\n\r\n## Android Companion App\r\n\r\nThanks to the help of @TheLastProject who had built the first prototype in less than 18h after initially mentioning the idea on the telegram group, there's now an Android Companion App for Valetudo.\r\n\r\nDon't worry, it is completely optional. All it does and aims to do is to find Valetudo instances on your network via Bonjour and help you with the provisioning (configuring Wi-Fi) process of new robots with Valetudo installed.\r\nThis can be helpful for example if you were to give your non-linux-skilled parents a rooted robot for Christmas or whatever.\r\n\r\nIt's available on F-Droid and Google Play and of course open source.\r\n\r\nFor more information, please check out [the docs](https://valetudo.cloud/pages/companion_apps/valetudo_companion.html).\r\n\r\n[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-02.png)[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-03.png)[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png)\r\n\r\n\r\n## UI Changes\r\n\r\n@ccoors provided very nice previews displaying their changes in each PR, which is why I will just copy-paste them here for your convenience.\r\nAlso, I'm lazy\r\n\r\n\"wifi\r\n\r\n\"voice\"manual\r\n\r\n\"more\r\n\r\n\r\n## Logo Cleanup\r\n\r\nAs you might've noticed, the logo slightly changed.\r\nThis avoids the bug in some people, which made them read it as *aletudo* when looking at it.\r\n\r\n## Valetudog\r\n\r\nThe thing from the telegram group finally got a name: Valetudog\r\nIt's now some kind of mascot I guess.\r\n\r\n\"valetudog\"\r\n\r\nI also bought a lot of stickers of it\r\n\r\n![image](https://user-images.githubusercontent.com/974410/135687512-e49f8bae-97ab-4d5c-bb8b-ba989eea1518.png)\r\n\r\nUnfortunately, I have no idea what to do with them.\r\nThey did turn out quite nice though.\r\n\r\n## Zoned Cleanup MQTT changes\r\n\r\nStarting with this release, it's no longer possible to clean multiple zone presets at once via MQTT.\r\nThat should've never been possible in the first place since it's conceptually wrong as you can only call a single preset at a time. Sorry about that.\r\n\r\nNote that this is a **breaking change** and will require updating of e.g. your Home Assistant automations.\r\nInstead of an array, you now have to send just the preset ID as a string.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Consumables bottom view sensors ([#1104](https://github.com/Hypfer/Valetudo/issues/1104)) ([2f83d8e](https://github.com/Hypfer/Valetudo/commit/2f83d8ea02aaefde8f132909071ca9bf7367de74))\r\n* **ui:** DoNotDisturb configuration & Masonry on large screens ([#1112](https://github.com/Hypfer/Valetudo/issues/1112)) ([935f903](https://github.com/Hypfer/Valetudo/commit/935f903981ad5f98e9224cae143396b353a195db))\r\n* **ui:** HTTP Basic Auth and NTP client config ([#1118](https://github.com/Hypfer/Valetudo/issues/1118)) ([2371878](https://github.com/Hypfer/Valetudo/commit/2371878cd48e19b57fce61b4200d76a1cc30257b))\r\n* **ui:** Manage voice packs ([#1108](https://github.com/Hypfer/Valetudo/issues/1108)) ([0d02c27](https://github.com/Hypfer/Valetudo/commit/0d02c278edaf1ea60810990455b33175b957acc7))\r\n* **ui:** Manual control ([#1114](https://github.com/Hypfer/Valetudo/issues/1114)) ([7e9ef04](https://github.com/Hypfer/Valetudo/commit/7e9ef04b2fa5d8fb4d5f7e8d3fa88366592873ea))\r\n* **ui:** Robot settings ([#1097](https://github.com/Hypfer/Valetudo/issues/1097)) ([4b43b37](https://github.com/Hypfer/Valetudo/commit/4b43b370663ca44f03d82ba828026169075d670c))\r\n* **ui:** Wifi configuration ([#1116](https://github.com/Hypfer/Valetudo/issues/1116)) ([3e71184](https://github.com/Hypfer/Valetudo/commit/3e7118414b6b190750e3f606c93e1b052d78b898))\r\n* **vendor.dreame:** Add Dreame D9 Pro ([cc50a8c](https://github.com/Hypfer/Valetudo/commit/cc50a8c6e4cab7a04c68ca61d21e59e15a3a59cb))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix MQTT Zone cleanup ([fdabcc5](https://github.com/Hypfer/Valetudo/commit/fdabcc52be3553f01648997ec714133e27a6e7cc))\r\n* **ui:** Allow start and home basic commands on error state ([5fd0354](https://github.com/Hypfer/Valetudo/commit/5fd0354eabd91aa50cc42120bdabdf6947aaf604))\r\n* **ui:** Blue line between buttons in PendingMapChangeEventControl ([196a29e](https://github.com/Hypfer/Valetudo/commit/196a29e1549ffd46fddcd78c7c8bee9b2d1e8c21))\r\n* **ui:** Fix mobile Icons in new frontend ([#1113](https://github.com/Hypfer/Valetudo/issues/1113)) ([313caa1](https://github.com/Hypfer/Valetudo/commit/313caa10ea0a246ea05dd4ba3fca83e374e75cdc))\r\n* **ui:** Import ToggleButton from core ([da0cce5](https://github.com/Hypfer/Valetudo/commit/da0cce588eee9c6065bb2ad4f2890b19cd8c5e59))\r\n* **ui:** RatioBar background color ([c00d174](https://github.com/Hypfer/Valetudo/commit/c00d1749c26bec217a60a529166c5f8bf6de3dba))\r\n* **ui:** Remove persistent data hint ([6777f3a](https://github.com/Hypfer/Valetudo/commit/6777f3aa7bbf4ef5afea5a3ba8fdecd2aa8f150e))\r\n* **ui:** repair light mode ([#1103](https://github.com/Hypfer/Valetudo/issues/1103)) ([842aea1](https://github.com/Hypfer/Valetudo/commit/842aea125b97a33adbf28c3b0c9d1cf84c069943))\r\n* **ui:** Root grid height ([957463a](https://github.com/Hypfer/Valetudo/commit/957463a9de34e4e7c3fafe5d94fdd6360b4a2f88))\r\n* **ui:** Root grid height ([1d9a244](https://github.com/Hypfer/Valetudo/commit/1d9a244412b235ed2da71d594cb77d00fd9eae45))\r\n* **ui:** Stop events badge flashing when it reloads ([#1115](https://github.com/Hypfer/Valetudo/issues/1115)) ([007926b](https://github.com/Hypfer/Valetudo/commit/007926b90881664e9b0c718e7c3ef21ad306e233))\r\n* **webserver:** Fix reflected xss vulnerability ([36a3bae](https://github.com/Hypfer/Valetudo/commit/36a3bae630dfc84c6a2e610ef35e93a002470857))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1119", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403/reactions", + "total_count": 16, + "+1": 0, + "-1": 0, + "laugh": 5, + "hooray": 2, + "confused": 0, + "heart": 0, + "rocket": 9, + "eyes": 0 + }, + "mentions_count": 2 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/47830402/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.08.0", + "id": 47830402, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ3ODMwNDAy", + "tag_name": "2021.08.0", + "target_commitish": "master", + "name": "Valetudo 2021.08.0", + "draft": false, + "prerelease": false, + "created_at": "2021-08-13T18:50:06Z", + "published_at": "2021-08-13T19:05:50Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42390793", + "id": 42390793, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkwNzkz", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32535472, + "download_count": 124, + "created_at": "2021-08-13T19:08:59Z", + "updated_at": "2021-08-13T19:09:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42391177", + "id": 42391177, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkxMTc3", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12011600, + "download_count": 7, + "created_at": "2021-08-13T19:17:59Z", + "updated_at": "2021-08-13T19:18:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42390791", + "id": 42390791, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkwNzkx", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30287988, + "download_count": 300, + "created_at": "2021-08-13T19:08:57Z", + "updated_at": "2021-08-13T19:08:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42390792", + "id": 42390792, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkwNzky", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30287988, + "download_count": 218, + "created_at": "2021-08-13T19:08:58Z", + "updated_at": "2021-08-13T19:08:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42391176", + "id": 42391176, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkxMTc2", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11385424, + "download_count": 15, + "created_at": "2021-08-13T19:17:58Z", + "updated_at": "2021-08-13T19:17:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42391175", + "id": 42391175, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkxMTc1", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11385592, + "download_count": 9, + "created_at": "2021-08-13T19:17:57Z", + "updated_at": "2021-08-13T19:17:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.08.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.08.0", + "body": "
\r\n \"valetudo\"\r\n

2021.08.0

\r\n
\r\n\r\nThis release contains mostly bugfixes and code cleanup.\r\nAlso, ordered cleanup and iterations for MQTT segment cleaning.\r\n\r\n## Dreame root public release\r\n\r\nRooting Dreame robots has been made publicly available with Dennis' DEF CON 29 Talk\r\n[Robots with lasers and cameras but no security Liberating your vacuum](https://youtu.be/EWqFxQpRbv8?t=1525).\r\n\r\nFor more information, consider joining the [Dreame Robot Vacuum Telegram Usergroup](https://t.me/joinchat/zgRioVBpWHliNGZi).\r\n\r\n## MQTT Segment Cleaning options\r\n\r\nThis release allows you to specify an iteration count when calling Segment Cleanups via MQTT.\r\nFurthermore, you can also request it to respect the order you've provided. e.g. Kitchen then Living Room then Bathroom.\r\n\r\nThis requires firmware support and is also a **breaking change.**\r\nYou'll have to update your MQTT scripts/automations/whatever.\r\n\r\n[The docs](https://valetudo.cloud/pages/integrations/home-assistant-integration.html) contain an example payload.\r\n\r\n## KeyLockCapability\r\n\r\nIf you have children, cats or drunk roommates who like to mess with your robot vacuum, you can now lock the buttons via Valetudo.\r\nThis of course needs firmware support. Something that seems to be available on most Dreame-made robots.\r\n\r\nPlease note that there's no UI toggle for it yet, meaning that you'll have to use the Swagger UI (http://ROBOT_IP/swagger/) to enable it.\r\n\r\n## _valetudo._tcp bonjour service\r\n\r\nValetudo 2021.08.0 and up will publish a bonjour service, which should make it easy to auto-discover a Valetudo instance.\r\nThis will likely be useful in the future.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** KeyLockCapability ([4e2b97b](https://github.com/Hypfer/Valetudo/commit/4e2b97b3f214d239af3ef4d032c9a123fad1a816))\r\n* **networkadvertisement:** Publish _valetudo._tcp service ([cb1c34f](https://github.com/Hypfer/Valetudo/commit/cb1c34fc3c0083d5405c2c638120e498a0ef5151))\r\n* **vendor.dreame:** 1C Manual Control ([afded40](https://github.com/Hypfer/Valetudo/commit/afded402a5f26c5bcdf409b41f22d3f6d8b7272b))\r\n* **vendor.dreame:** DreameKeyLockCapability ([36e3598](https://github.com/Hypfer/Valetudo/commit/36e3598d50efc04515809f909a1600aa8575a5ac))\r\n* **vendor.dreame:** Manual Control ([4cfddd4](https://github.com/Hypfer/Valetudo/commit/4cfddd4ca17e40187d2e6f2e4557e122349978ac))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Improve unhandledRejection event handler ([a8720b9](https://github.com/Hypfer/Valetudo/commit/a8720b931a4a89b4748470786a0fe0b9b4fd64c4))\r\n* **mqtt:** Catch exceptions when handling MQTT commands ([33b9dc3](https://github.com/Hypfer/Valetudo/commit/33b9dc3cfcd6f66d3805c662766c36c494bbad69))\r\n* **mqtt:** Fix weirdness on disconnect ([be033b6](https://github.com/Hypfer/Valetudo/commit/be033b6efe1806b382a47609802e28a2004130fb))\r\n* **mqtt:** Only try to publish state when connected ([e61cf98](https://github.com/Hypfer/Valetudo/commit/e61cf9840d73a08edd44e1368339afb3d4fecef5))\r\n* **mqtt:** Publish named as well as unnamed segments ([b5ff0b4](https://github.com/Hypfer/Valetudo/commit/b5ff0b47061d997ce2439292e6f11ceea8405de0))\r\n* **vendor.dreame:** Add error code 64 for Dreame robots ([#1017](https://github.com/Hypfer/Valetudo/issues/1017)) ([4ed64d2](https://github.com/Hypfer/Valetudo/commit/4ed64d2f2ccf66994c71091b06d9531f8b603244))\r\n* **vendor.dreame:** Error 11 Mapping for CombinedVirtualRestrictions ([491ed4b](https://github.com/Hypfer/Valetudo/commit/491ed4b4f6f670f1f148383084de0f7b2528a816))\r\n* **vendor.dreame:** Fix cleaning order of segments ([d7cfd07](https://github.com/Hypfer/Valetudo/commit/d7cfd07b681e9e8c76efcaf0257b31f0c54dfcd4))\r\n* **vendor.dreame:** Handle more segment-related error codes ([57fe90a](https://github.com/Hypfer/Valetudo/commit/57fe90afebebf93519eabd7a80bf74390e0ca4da))\r\n* **vendor.dreame:** Ignore some FDS uploads ([f1930b3](https://github.com/Hypfer/Valetudo/commit/f1930b30228e34f9c123031f0e559fcd3704a532))\r\n* **vendor.dreame:** Update error code mapping ([d1699b2](https://github.com/Hypfer/Valetudo/commit/d1699b24d9631e22e4fd189c1f054a10949e4a36))\r\n* Fix invalid use of .finally() ([770f977](https://github.com/Hypfer/Valetudo/commit/770f977a1e4c76f056e1a83c9aeca76cb45b57ab))\r\n* **vendor.dreame:** Remove logging of raw data on failed parse ([11fec98](https://github.com/Hypfer/Valetudo/commit/11fec98920afae8b7d99914158706bad38f5f082))\r\n* **vendor.roborock:** Fix unhandled rejection in virtual restrictions ([4a76029](https://github.com/Hypfer/Valetudo/commit/4a760293473e57cf49217e9b901f013e2637370b))\r\n* **vendor.viomi:** Fix unhandled rejection in virtual restrictions ([af4704f](https://github.com/Hypfer/Valetudo/commit/af4704f8846cb95630debdabd1753e61a7c76ab5))\r\n* Fix more various minor issues found by deepscan ([c6c1a7f](https://github.com/Hypfer/Valetudo/commit/c6c1a7f0dd89656b3d2385ffee648e03a5956511))\r\n* Fix various minor issues found by deepscan ([37cc55f](https://github.com/Hypfer/Valetudo/commit/37cc55f4431eb01d1b2036ddc9cf1bf458368487))", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1018", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402/reactions", + "total_count": 13, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 13, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/46995769/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.07.1", + "id": 46995769, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ2OTk1NzY5", + "tag_name": "2021.07.1", + "target_commitish": "master", + "name": "Valetudo 2021.07.1", + "draft": false, + "prerelease": false, + "created_at": "2021-07-29T17:43:36Z", + "published_at": "2021-07-29T17:46:33Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286385", + "id": 41286385, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2Mzg1", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32532575, + "download_count": 105, + "created_at": "2021-07-29T17:49:30Z", + "updated_at": "2021-07-29T17:49:31Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286768", + "id": 41286768, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2NzY4", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12009119, + "download_count": 4, + "created_at": "2021-07-29T17:57:37Z", + "updated_at": "2021-07-29T17:57:38Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286376", + "id": 41286376, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2Mzc2", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30285091, + "download_count": 229, + "created_at": "2021-07-29T17:49:28Z", + "updated_at": "2021-07-29T17:49:29Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286383", + "id": 41286383, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2Mzgz", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30285091, + "download_count": 116, + "created_at": "2021-07-29T17:49:29Z", + "updated_at": "2021-07-29T17:49:30Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286767", + "id": 41286767, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2NzY3", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11382527, + "download_count": 9, + "created_at": "2021-07-29T17:57:36Z", + "updated_at": "2021-07-29T17:57:37Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286766", + "id": 41286766, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2NzY2", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11382695, + "download_count": 9, + "created_at": "2021-07-29T17:57:36Z", + "updated_at": "2021-07-29T17:57:36Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.07.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.07.1", + "body": "
\r\n \"valetudo\"\r\n

2021.07.1

\r\n
\r\n\r\nThis release includes, SSDP and Zeroconf advertisement, an Event/Notification feature some bugfixes and lowmem optimizations.\r\nFurthermore, 2021.07.1 fixes a race condition which was present in 2021.07.0 causing crashes on reboot.\r\n\r\n## Network advertisement\r\n\r\nTo make using Valetudo a bit easier and more straight-forward, advertisement of the Service via both SSDP/UPnP as well as Zeroconf was added.\r\n\r\nIf you're on Windows, opening \"Network\" in the File Explorer should look similar to this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/127387044-da7e8c18-390f-40bc-88b1-3ff316e4e6cf.png)\r\n\r\n\r\nIf you're on a Mac, I'm sure that there's also something.\r\nFurthermore, Valetudo will log the `.local` domain it's using, which might be useful in some setups.\r\n\r\n## ValetudoEvents\r\n\r\nStarting with this release, we now have something that will deal with everything that would've been a push notification\r\nwhen using the regular app. Utilizing this, the \"Bin Full\" notification on roborock vacuum robots may finally happen.\r\n\r\nThere's no UI for it just yet, however it will be implemented eventually.\r\n\r\n## Runtime Reuse\r\n\r\nAs storage space can be quite limited on these devices, it is now possible to use the NodeJS runtime bundled with\r\nValetudo for other things as well.\r\n\r\nThis can be helpful if one would e.g. want to implement a Microservice, which also runs on the Robot, talks to Valetudo\r\nand provides Telegram connectivity.\r\n\r\nJust add the `--ignore-payload` flag plus another JS file:\r\n`./valetudo --ignore-payload repl.js`\r\n\r\nThe baked-in v8 options will still apply when reusing the runtime.\r\nThat however shouldn't be an issue for most use-cases.\r\n\r\n## S5 Max Map issues\r\n\r\nApparently, the Map Reset on the S5 Max never worked. That might explain some issues users of this Robot were seeing.\r\nIt should be fixed now.\r\n\r\n## Memory-related changes\r\n\r\nDuring the development of 2021.07.0, a lot of time was spent optimizing Valetudo for use in lowmem environments\r\nsuch as the Roborock S5 Max or Dreame D9.\r\n\r\nIt was discovered that there were issues with the SSE Map update feature, which lead to Valetudo being killed by the\r\nKernel OOM killer. This was the cause of the confusing \"Hey my Valetudo is just.. gone\" reports.\r\n\r\nWhile this was fixed by introducing limits there, Valetudo was also extended to watch its own Memory usage\r\nand shut down if it exceeds 1/3 of system memory. This should provide an additional failsafe.\r\n\r\nFurthermore, Valetudo will also set its OOM score to a rather high value by itself, so that the Kernel OOM killer\r\nwill always kill Valetudo and nothing else.\r\n\r\nStill, if you can, please buy a 512mb or more RAM robot.\r\n\r\n## Misc\r\n\r\n- To help with debugging, you can now enable an option in the config file to store all uploaded maps in the filesystem.\r\n- Resetting the Map will now also invalidate the map cached by Valetudo to reduce confusion.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Network Announcement via SSDP/UPnP and mDNS/Zeroconf/Bonjour ([c158d77](https://github.com/Hypfer/Valetudo/commit/c158d7718c33d4b14b8710e636a25616c8e1acad))\r\n* **core:** MappingPassCapability ([1b09cde](https://github.com/Hypfer/Valetudo/commit/1b09cdec4ab4d3605ae2572f1f3eb187dfd2e1d5))\r\n* **core:** PendingMapChangeHandlingCapability ([ed0455d](https://github.com/Hypfer/Valetudo/commit/ed0455d66a46b7adc16e91d34daff2da3e784417))\r\n* **miio:** Add easy way to store uploaded maps for debugging purposes ([547f8c1](https://github.com/Hypfer/Valetudo/commit/547f8c13271f684d3285490b2365f161415b357d))\r\n* **vendor.dreame:** Add Support for the L10 Pro ([2f618c0](https://github.com/Hypfer/Valetudo/commit/2f618c030edf2bd27d254992940ac7514dd4b3c3))\r\n* **vendor.dreame:** DreamePendingMapChangeHandlingCapability ([d972121](https://github.com/Hypfer/Valetudo/commit/d972121d93f6cd552d868ae0935d698efba28d6b))\r\n* **vendor.dreame:** Handle more properties ([421e7de](https://github.com/Hypfer/Valetudo/commit/421e7dea340c8e364e82bb35770958b0c7b0792f))\r\n* **vendor.dreame:** MappingPassCapability ([7f9322b](https://github.com/Hypfer/Valetudo/commit/7f9322b060d354df13d3238328d99cb29ce2df43))\r\n* Set OOM Score Adj when embedded ([6de2f06](https://github.com/Hypfer/Valetudo/commit/6de2f06ba87f1884e74acab32976437cf34cf2c2))\r\n* ValetudoEvents ([aa15238](https://github.com/Hypfer/Valetudo/commit/aa152381d1c4b73e594b1dd36c04ccfc32de3f87))\r\n* **vendor.dreame:** Map fast mapping status ([021213e](https://github.com/Hypfer/Valetudo/commit/021213e8cd3b932685b590d896dcf640c311a2fc))\r\n* **vendor.dreame:** Sensor consumable ([4c1e319](https://github.com/Hypfer/Valetudo/commit/4c1e31980af77492f634fbaad375cd20d1fb8a2d))\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Catch uncaught exceptions for an orderly shutdown ([5cf19c4](https://github.com/Hypfer/Valetudo/commit/5cf19c426734acb08f38b86a88a7743c7db770db))\r\n* **core:** Reverse event order ([a829ba5](https://github.com/Hypfer/Valetudo/commit/a829ba54ab95ea0e00c9e855467d715a98ba4055))\r\n* **networkadvertisement:** Don't crash on reboots + human-friendly URL ([3cb1cb8](https://github.com/Hypfer/Valetudo/commit/3cb1cb8dae25b472ab6b79653ea2c8ba59e2c0df))\r\n* **vendor.dreame:** Fix segment cleanup via mqtt ([5dbb9d0](https://github.com/Hypfer/Valetudo/commit/5dbb9d0474b441a3285cae22140d82ecd71fb3d6))\r\n* **vendor.dreame:** Fix status mapping and ignore irrelevant property change ([68c1c0c](https://github.com/Hypfer/Valetudo/commit/68c1c0ceb0e13609b32b9637ee07addc67330c45)), closes [#969](https://github.com/Hypfer/Valetudo/issues/969)\r\n* **vendor.dreame:** Handle more properties ([6a834c8](https://github.com/Hypfer/Valetudo/commit/6a834c8ff888ab2c24516048c899f3bf42ec0290))\r\n* **vendor.dreame:** Handle sensor consumable push ([cc8b7a5](https://github.com/Hypfer/Valetudo/commit/cc8b7a5bc86014f61a6e792c69826e7ebed653db))\r\n* **vendor.dreame:** Handle sensor consumable push ([4276c36](https://github.com/Hypfer/Valetudo/commit/4276c3648e06a6951df9ee4f576db7cb1e5821bc))\r\n* **vendor.dreame:** Handle uploaded multi-map jsons ([01486b8](https://github.com/Hypfer/Valetudo/commit/01486b80292ddbafb9cae61f43ac19a0520e0a78))\r\n* **vendor.dreame:** Revert Fix status mapping ([8db8b6f](https://github.com/Hypfer/Valetudo/commit/8db8b6fd0dc22fc1b0cb23ec1052e1fa2e2ceae1))\r\n* **vendor.dreame:** Segments from rism might not apply in some situations ([e1161cf](https://github.com/Hypfer/Valetudo/commit/e1161cf6816db67306eff7ecf4935d36b2497347))\r\n* **vendor.dreame:** There actually is a difference between pause and stop ([6da5dc4](https://github.com/Hypfer/Valetudo/commit/6da5dc46a24b622b093af15024b729252b3c2e1d))\r\n* **vendor.roborock:** Add filename to map upload url ([90b7346](https://github.com/Hypfer/Valetudo/commit/90b73465159e65f89d94fce1096cf915b4903985))\r\n* **vendor.roborock:** Enable S7 Water Pump Control + No-Mop-Zones ([f699a55](https://github.com/Hypfer/Valetudo/commit/f699a558d49523f2683c08027538466c01b61ecc))\r\n* **vendor.roborock:** MapSnapshots are only available on Gen2 robots ([0752de2](https://github.com/Hypfer/Valetudo/commit/0752de2b862f697943171b4b56ba67ea0db3f203))\r\n* **vendor.roborock:** MapSnapshots IDs are strings in valetudo but numbers for roborock ([361dffa](https://github.com/Hypfer/Valetudo/commit/361dffacea59b76726ac93eb7a3296bb6905c763))\r\n* **vendor.roborock:** Multi-Map capable roborock robots use a different command for map resets ([2bbd86f](https://github.com/Hypfer/Valetudo/commit/2bbd86f9df27baeccb46580e3a24b08b02e28ab6))\r\n* **webserver:** Remove unused parameter ([d27e3b1](https://github.com/Hypfer/Valetudo/commit/d27e3b1f626e935dcc1e279d300abc4517f45517))\r\n* Fix missing git commit id ([40ca9cb](https://github.com/Hypfer/Valetudo/commit/40ca9cb55884153c4ad582fd377cff863666d9f2))\r\n* Fix OOM-issues caused by SSE connections ([a0371f4](https://github.com/Hypfer/Valetudo/commit/a0371f4909b58403bf88fabecf2969d400c5487c))\r\n* Further tweak forced garbage collection ([c70393a](https://github.com/Hypfer/Valetudo/commit/c70393a4f19e296642ab1dd4540a3f4a64f931b4))\r\n* Further tweak SSE settings ([8eae178](https://github.com/Hypfer/Valetudo/commit/8eae1786c9d85a10c3222144e1a9561141c10746))\r\n* Further tweak SSE settings ([40d16f5](https://github.com/Hypfer/Valetudo/commit/40d16f5332f746f0d589ac530007c170eaa5a024))\r\n* Further tweak SSE settings ([cb8e01e](https://github.com/Hypfer/Valetudo/commit/cb8e01e20b195146b901f405fd87b3e45b3d69b6))\r\n* Resetting the map should also clear the Map cached by Valetudo ([e70041f](https://github.com/Hypfer/Valetudo/commit/e70041fd0318b4f8389db7b78bb4dc6bb6a75a05))\r\n* **vendor.viomi:** Set correct env variables ([#979](https://github.com/Hypfer/Valetudo/issues/979)) ([5fd4a6a](https://github.com/Hypfer/Valetudo/commit/5fd4a6a618d6ea9b93991618a3f586ca4df76903))\r\n* **vendor.viomi:** Set correct ssh key location ([b15c707](https://github.com/Hypfer/Valetudo/commit/b15c707a8a7d9b344ba314a2109bc52531f0b395))\r\n* Try logging everything we can get about process memory before committing sudoku ([6578a99](https://github.com/Hypfer/Valetudo/commit/6578a99344a6d087450a0e4b45a630398fb3a544))\r\n* Tweak forced garbage collection ([d905864](https://github.com/Hypfer/Valetudo/commit/d905864f5e2b07579a0bcf6a13be649ec9e5c785))\r\n\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1001", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769/reactions", + "total_count": 5, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 5, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46930477", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46930477/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/46930477/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.07.0", + "id": 46930477, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ2OTMwNDc3", + "tag_name": "2021.07.0", + "target_commitish": "master", + "name": "Valetudo 2021.07.0", + "draft": false, + "prerelease": true, + "created_at": "2021-07-28T19:22:17Z", + "published_at": "2021-07-28T19:55:21Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41211878", + "id": 41211878, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjExODc4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32515454, + "download_count": 28, + "created_at": "2021-07-28T19:58:20Z", + "updated_at": "2021-07-28T19:58:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41212339", + "id": 41212339, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjEyMzM5", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11991550, + "download_count": 3, + "created_at": "2021-07-28T20:07:00Z", + "updated_at": "2021-07-28T20:07:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41211872", + "id": 41211872, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjExODcy", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30267970, + "download_count": 49, + "created_at": "2021-07-28T19:58:17Z", + "updated_at": "2021-07-28T19:58:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41211877", + "id": 41211877, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjExODc3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30267970, + "download_count": 143, + "created_at": "2021-07-28T19:58:19Z", + "updated_at": "2021-07-28T19:58:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41212337", + "id": 41212337, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjEyMzM3", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11364806, + "download_count": 3, + "created_at": "2021-07-28T20:06:59Z", + "updated_at": "2021-07-28T20:07:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41212335", + "id": 41212335, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjEyMzM1", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11365462, + "download_count": 4, + "created_at": "2021-07-28T20:06:58Z", + "updated_at": "2021-07-28T20:06:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.07.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.07.0", + "body": "
\r\n \"valetudo\"\r\n

2021.07.0

\r\n
\r\n\r\nThis release includes, SSDP and Zeroconf advertisement, an Event/Notification feature some bugfixes and lowmem optimizations.\r\n\r\n## Network advertisement\r\n\r\nTo make using Valetudo a bit easier and more straight-forward, advertisement of the Service via both SSDP/UPnP as well as Zeroconf was added.\r\n\r\nIf you're on Windows, opening \"Network\" in the File Explorer should look similar to this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/127387044-da7e8c18-390f-40bc-88b1-3ff316e4e6cf.png)\r\n\r\n\r\nIf you're on a Mac, I'm sure that there's also something.\r\nFurthermore, Valetudo will log the `.local` domain it's using, which might be useful in some setups.\r\n\r\n## ValetudoEvents\r\n\r\nStarting with this release, we now have something that will deal with everything that would've been a push notification\r\nwhen using the regular app. Utilizing this, the \"Bin Full\" notification on roborock vacuum robots may finally happen.\r\n\r\nThere's no UI for it just yet, however it will be implemented eventually.\r\n\r\n## Runtime Reuse\r\n\r\nAs storage space can be quite limited on these devices, it is now possible to use the NodeJS runtime bundled with\r\nValetudo for other things as well.\r\n\r\nThis can be helpful if one would e.g. want to implement a Microservice, which also runs on the Robot, talks to Valetudo\r\nand provides Telegram connectivity.\r\n\r\nJust add the `--ignore-payload` flag plus another JS file:\r\n`./valetudo --ignore-payload repl.js`\r\n\r\nThe baked-in v8 options will still apply when reusing the runtime.\r\nThat however shouldn't be an issue for most use-cases.\r\n\r\n## S5 Max Map issues\r\n\r\nApparently, the Map Reset on the S5 Max never worked. That might explain some issues users of this Robot were seeing.\r\nIt should be fixed now.\r\n\r\n## Memory-related changes\r\n\r\nDuring the development of 2021.07.0, a lot of time was spent optimizing Valetudo for use in lowmem environments\r\nsuch as the Roborock S5 Max or Dreame D9.\r\n\r\nIt was discovered that there were issues with the SSE Map update feature, which lead to Valetudo being killed by the\r\nKernel OOM killer. This was the cause of the confusing \"Hey my Valetudo is just.. gone\" reports.\r\n\r\nWhile this was fixed by introducing limits there, Valetudo was also extended to watch its own Memory usage\r\nand shut down if it exceeds 1/3 of system memory. This should provide an additional failsafe.\r\n\r\nFurthermore, Valetudo will also set its OOM score to a rather high value by itself, so that the Kernel OOM killer\r\nwill always kill Valetudo and nothing else.\r\n\r\nStill, if you can, please buy a 512mb or more RAM robot.\r\n\r\n## Misc\r\n\r\n- To help with debugging, you can now enable an option in the config file to store all uploaded maps in the filesystem.\r\n- Resetting the Map will now also invalidate the map cached by Valetudo to reduce confusion.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Network Announcement via SSDP/UPnP and mDNS/Zeroconf/Bonjour ([c158d77](https://github.com/Hypfer/Valetudo/commit/c158d7718c33d4b14b8710e636a25616c8e1acad))\r\n* **core:** MappingPassCapability ([1b09cde](https://github.com/Hypfer/Valetudo/commit/1b09cdec4ab4d3605ae2572f1f3eb187dfd2e1d5))\r\n* **core:** PendingMapChangeHandlingCapability ([ed0455d](https://github.com/Hypfer/Valetudo/commit/ed0455d66a46b7adc16e91d34daff2da3e784417))\r\n* **miio:** Add easy way to store uploaded maps for debugging purposes ([547f8c1](https://github.com/Hypfer/Valetudo/commit/547f8c13271f684d3285490b2365f161415b357d))\r\n* **vendor.dreame:** Add Support for the L10 Pro ([2f618c0](https://github.com/Hypfer/Valetudo/commit/2f618c030edf2bd27d254992940ac7514dd4b3c3))\r\n* **vendor.dreame:** DreamePendingMapChangeHandlingCapability ([d972121](https://github.com/Hypfer/Valetudo/commit/d972121d93f6cd552d868ae0935d698efba28d6b))\r\n* **vendor.dreame:** Handle more properties ([421e7de](https://github.com/Hypfer/Valetudo/commit/421e7dea340c8e364e82bb35770958b0c7b0792f))\r\n* **vendor.dreame:** MappingPassCapability ([7f9322b](https://github.com/Hypfer/Valetudo/commit/7f9322b060d354df13d3238328d99cb29ce2df43))\r\n* Set OOM Score Adj when embedded ([6de2f06](https://github.com/Hypfer/Valetudo/commit/6de2f06ba87f1884e74acab32976437cf34cf2c2))\r\n* ValetudoEvents ([aa15238](https://github.com/Hypfer/Valetudo/commit/aa152381d1c4b73e594b1dd36c04ccfc32de3f87))\r\n* **vendor.dreame:** Map fast mapping status ([021213e](https://github.com/Hypfer/Valetudo/commit/021213e8cd3b932685b590d896dcf640c311a2fc))\r\n* **vendor.dreame:** Sensor consumable ([4c1e319](https://github.com/Hypfer/Valetudo/commit/4c1e31980af77492f634fbaad375cd20d1fb8a2d))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Reverse event order ([a829ba5](https://github.com/Hypfer/Valetudo/commit/a829ba54ab95ea0e00c9e855467d715a98ba4055))\r\n* **vendor.dreame:** Fix segment cleanup via mqtt ([5dbb9d0](https://github.com/Hypfer/Valetudo/commit/5dbb9d0474b441a3285cae22140d82ecd71fb3d6))\r\n* **vendor.dreame:** Fix status mapping and ignore irrelevant property change ([68c1c0c](https://github.com/Hypfer/Valetudo/commit/68c1c0ceb0e13609b32b9637ee07addc67330c45)), closes [#969](https://github.com/Hypfer/Valetudo/issues/969)\r\n* **vendor.dreame:** Handle more properties ([6a834c8](https://github.com/Hypfer/Valetudo/commit/6a834c8ff888ab2c24516048c899f3bf42ec0290))\r\n* **vendor.dreame:** Handle sensor consumable push ([cc8b7a5](https://github.com/Hypfer/Valetudo/commit/cc8b7a5bc86014f61a6e792c69826e7ebed653db))\r\n* **vendor.dreame:** Handle sensor consumable push ([4276c36](https://github.com/Hypfer/Valetudo/commit/4276c3648e06a6951df9ee4f576db7cb1e5821bc))\r\n* **vendor.dreame:** Handle uploaded multi-map jsons ([01486b8](https://github.com/Hypfer/Valetudo/commit/01486b80292ddbafb9cae61f43ac19a0520e0a78))\r\n* **vendor.dreame:** Revert Fix status mapping ([8db8b6f](https://github.com/Hypfer/Valetudo/commit/8db8b6fd0dc22fc1b0cb23ec1052e1fa2e2ceae1))\r\n* **vendor.dreame:** Segments from rism might not apply in some situations ([e1161cf](https://github.com/Hypfer/Valetudo/commit/e1161cf6816db67306eff7ecf4935d36b2497347))\r\n* **vendor.dreame:** There actually is a difference between pause and stop ([6da5dc4](https://github.com/Hypfer/Valetudo/commit/6da5dc46a24b622b093af15024b729252b3c2e1d))\r\n* **vendor.roborock:** Add filename to map upload url ([90b7346](https://github.com/Hypfer/Valetudo/commit/90b73465159e65f89d94fce1096cf915b4903985))\r\n* **vendor.roborock:** Enable S7 Water Pump Control + No-Mop-Zones ([f699a55](https://github.com/Hypfer/Valetudo/commit/f699a558d49523f2683c08027538466c01b61ecc))\r\n* **vendor.roborock:** MapSnapshots are only available on Gen2 robots ([0752de2](https://github.com/Hypfer/Valetudo/commit/0752de2b862f697943171b4b56ba67ea0db3f203))\r\n* **vendor.roborock:** MapSnapshots IDs are strings in valetudo but numbers for roborock ([361dffa](https://github.com/Hypfer/Valetudo/commit/361dffacea59b76726ac93eb7a3296bb6905c763))\r\n* **webserver:** Remove unused parameter ([d27e3b1](https://github.com/Hypfer/Valetudo/commit/d27e3b1f626e935dcc1e279d300abc4517f45517))\r\n* Fix missing git commit id ([40ca9cb](https://github.com/Hypfer/Valetudo/commit/40ca9cb55884153c4ad582fd377cff863666d9f2))\r\n* Fix OOM-issues caused by SSE connections ([a0371f4](https://github.com/Hypfer/Valetudo/commit/a0371f4909b58403bf88fabecf2969d400c5487c))\r\n* Further tweak forced garbage collection ([c70393a](https://github.com/Hypfer/Valetudo/commit/c70393a4f19e296642ab1dd4540a3f4a64f931b4))\r\n* Further tweak SSE settings ([40d16f5](https://github.com/Hypfer/Valetudo/commit/40d16f5332f746f0d589ac530007c170eaa5a024))\r\n* Further tweak SSE settings ([cb8e01e](https://github.com/Hypfer/Valetudo/commit/cb8e01e20b195146b901f405fd87b3e45b3d69b6))\r\n* Resetting the map should also clear the Map cached by Valetudo ([e70041f](https://github.com/Hypfer/Valetudo/commit/e70041fd0318b4f8389db7b78bb4dc6bb6a75a05))\r\n* **vendor.roborock:** Multi-Map capable roborock robots use a different command for map resets ([2bbd86f](https://github.com/Hypfer/Valetudo/commit/2bbd86f9df27baeccb46580e3a24b08b02e28ab6))\r\n* Further tweak SSE settings ([8eae178](https://github.com/Hypfer/Valetudo/commit/8eae1786c9d85a10c3222144e1a9561141c10746))\r\n* **vendor.viomi:** Set correct env variables ([#979](https://github.com/Hypfer/Valetudo/issues/979)) ([5fd4a6a](https://github.com/Hypfer/Valetudo/commit/5fd4a6a618d6ea9b93991618a3f586ca4df76903))\r\n* **vendor.viomi:** Set correct ssh key location ([b15c707](https://github.com/Hypfer/Valetudo/commit/b15c707a8a7d9b344ba314a2109bc52531f0b395))\r\n* Try logging everything we can get about process memory before committing sudoku ([6578a99](https://github.com/Hypfer/Valetudo/commit/6578a99344a6d087450a0e4b45a630398fb3a544))\r\n* Tweak forced garbage collection ([d905864](https://github.com/Hypfer/Valetudo/commit/d905864f5e2b07579a0bcf6a13be649ec9e5c785))\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/998", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46930477/reactions", + "total_count": 3, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 3, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/45189083/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.06.0", + "id": 45189083, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ1MTg5MDgz", + "tag_name": "2021.06.0", + "target_commitish": "master", + "name": "Valetudo 2021.06.0", + "draft": false, + "prerelease": false, + "created_at": "2021-06-24T18:34:52Z", + "published_at": "2021-06-24T18:42:47Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173092", + "id": 39173092, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDky", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32315462, + "download_count": 98, + "created_at": "2021-06-24T18:54:23Z", + "updated_at": "2021-06-24T18:54:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173095", + "id": 39173095, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDk1", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11791774, + "download_count": 7, + "created_at": "2021-06-24T18:54:24Z", + "updated_at": "2021-06-24T18:54:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173084", + "id": 39173084, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDg0", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30067978, + "download_count": 321, + "created_at": "2021-06-24T18:54:19Z", + "updated_at": "2021-06-24T18:54:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173088", + "id": 39173088, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDg4", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30067978, + "download_count": 167, + "created_at": "2021-06-24T18:54:21Z", + "updated_at": "2021-06-24T18:54:22Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173091", + "id": 39173091, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDkx", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11165330, + "download_count": 9, + "created_at": "2021-06-24T18:54:22Z", + "updated_at": "2021-06-24T18:54:23Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173086", + "id": 39173086, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDg2", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11164986, + "download_count": 17, + "created_at": "2021-06-24T18:54:21Z", + "updated_at": "2021-06-24T18:54:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.06.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.06.0", + "body": "
\r\n \"valetudo\"\r\n

2021.06.0

\r\n
\r\n\r\nThis release features Swagger UI for proper REST API Documentation.\r\nAlso bugfixes and stability + performance improvements like the changelog of every single android app you have installed.\r\n\r\n## Swagger UI\r\n\r\n![image](https://user-images.githubusercontent.com/974410/123315997-9f21c580-d52c-11eb-8271-3f5ffd81931b.png)\r\n\r\n\r\nIn a tedious and brain-melting process, OpenAPI documentation was added to Valetudo.\r\nBy navigating to `ROBOT_IP/swagger/` you now have an interactive overview for the REST API, which directly lets you interface with the robot.\r\nThe schemas made for this are also used by the backend to validate every incoming request.\r\n\r\nSince staring at JSON Schemas all day is a pretty mind-numbing task, I didn't manage to also add examples for all responses and requests.\r\n\r\nI did however add examples for the Timers Endpoint, meaning that it is now easier to use those again.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/123316039-ab0d8780-d52c-11eb-9c17-34f20c944c16.png)\r\n\r\nUI support of course coming soon.\r\n\r\n## Config file Schema Validation\r\n\r\nThe new schemas are also used to validate the configuration file loaded by Valetudo.\r\nIf any errors arise, Valetudo will backup the config and create a new one using the defaults.\r\nThis will prevent issues with Valetudo not starting due to invalid configuration data.\r\n\r\nThe log will tell you what exactly was wrong in your config and where you can find the backup.\r\n\r\n\r\n## Other noteworthy changes\r\n\r\n### NodeJS v16.4.0\r\n\r\nThe Runtime was upgraded to v16.4.0 which brings v8 9.1 including the new Sparkplug thingy, which may result in CPU performance improvements.\r\n\r\n### MQTT ignores retained messages\r\n\r\nA common rookie mistake is that command MQTT messages are sent with the retain flag causing the robot to receive them on every reconnect.\r\nThis effectively executed a cleanup on each reboot at 4am.\r\n\r\nTo combat this, Valetudo will now simply ignore all retained messages received and complain about them in the logfile.\r\n\r\n### System REST Endpoints\r\n\r\nThere are new REST Endpoints providing system statistics such as Memory or CPU usage.\r\n\r\n`/api/v2/system/host/info`\r\n```json\r\n{\r\n \"hostname\": \"rockrobo\",\r\n \"arch\": \"arm\",\r\n \"mem\": {\r\n \"total\": 522792960,\r\n \"free\": 358219776,\r\n \"valetudo_current\": 59215872,\r\n \"valetudo_max\": 59699200\r\n },\r\n \"uptime\": 61036,\r\n \"load\": [\r\n 0.255,\r\n 0.2725,\r\n 0.28\r\n ]\r\n}\r\n```\r\n\r\n### Code Compression\r\n\r\nDue to the switch to `vercel/pkg` 5.3.0, Valetudo now uses the code compression feature, which results in smaller binaries.\r\n\r\n### Memory Usage\r\n\r\nMQTT Map compression is now streamed, which may or may not improve memory usage on 256mb ram robots.\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Ignore received retained message to work around common user errors ([26d8a4c](https://github.com/Hypfer/Valetudo/commit/26d8a4cd4c36410afabfda6f9e87e08fd01e9a28))\r\n* **mqtt:** Stream map serialization to improve memory usage with large maps ([98b2757](https://github.com/Hypfer/Valetudo/commit/98b2757aec0af94392038577eead7749ef659e17))\r\n* **timers:** Add endpoint which returns timer actions supported by this robot ([fe1fa88](https://github.com/Hypfer/Valetudo/commit/fe1fa88d715e1002d3ee607ce9646b8d8b2cdb9d))\r\n* **timers:** add ValetudoGoToTimerAction ([#953](https://github.com/Hypfer/Valetudo/issues/953)) ([d8a523e](https://github.com/Hypfer/Valetudo/commit/d8a523e40138f679411d2b8c33db3057d5f6c8d8))\r\n* **vendor.roborock:** Add support for the Roborock S7 ([c9ccb4a](https://github.com/Hypfer/Valetudo/commit/c9ccb4a11dc546da82684c5f2a80e96847ff2639))\r\n* **webserver:** Add SystemRouter ([efc46e6](https://github.com/Hypfer/Valetudo/commit/efc46e69001a2533077b1e30fd1d8f6de910e263))\r\n* **webserver:** Normalize reported system load ([b384ac3](https://github.com/Hypfer/Valetudo/commit/b384ac3038857f3e8677bac5859b8c1de99f80be))\r\n* **webserver:** Streamed compression of some heavy requests ([0d7d836](https://github.com/Hypfer/Valetudo/commit/0d7d8364b98e950d186d961062b81fbfff5e920a))\r\n* **webserver:** Validate actual endpoint existence against openApi schema ([f7cee31](https://github.com/Hypfer/Valetudo/commit/f7cee31eb20cba824d3fd2ed47cdb73a242de3f9))\r\n* Swagger Docs ([7842d9e](https://github.com/Hypfer/Valetudo/commit/7842d9ec0957a9a45f6c83ab357a901884b11ba1)), closes [#892](https://github.com/Hypfer/Valetudo/issues/892)\r\n* Validate configuration file and create a new one on error ([39e4613](https://github.com/Hypfer/Valetudo/commit/39e46137872f6774d2ebaf1120a10d0cddfff45b))\r\n\r\n### Bug Fixes\r\n\r\n* **configuration:** Add migration for invalid mqtt port type ([1220aa5](https://github.com/Hypfer/Valetudo/commit/1220aa5622dbf200ef2be88612f1e503ec887328))\r\n* **miio:** Allow setting new wifi credentials when provisioned ([32a12cf](https://github.com/Hypfer/Valetudo/commit/32a12cf82c698b64b3cc037a869f058fb4588f26)), closes [#657](https://github.com/Hypfer/Valetudo/issues/657)\r\n* **mqtt:** Calling GoTo Presets should use regular strings and not json strings ([ec975aa](https://github.com/Hypfer/Valetudo/commit/ec975aaec40c9857e7b35622253128ef75be3fbe)), closes [#960](https://github.com/Hypfer/Valetudo/issues/960)\r\n* **mqtt:** Use semaphore to avoid reconfigure race condition ([5b4b377](https://github.com/Hypfer/Valetudo/commit/5b4b377f98c5030aa13f2133b5a220c3366fae57))\r\n* **ntpclient:** Reduce loglevel of more error codes to avoid confusion ([ec4ee08](https://github.com/Hypfer/Valetudo/commit/ec4ee082eaba88d51d8948ebc97c0cb6e4347ed1))\r\n* **ui:** Allow resetting map when PersistentMapControl is unavailable ([#954](https://github.com/Hypfer/Valetudo/issues/954)) ([bc8feb9](https://github.com/Hypfer/Valetudo/commit/bc8feb936d373757093b79ed40ccd8b7318e8f67))\r\n* **ui:** Hide defunct zones button ([ae7c059](https://github.com/Hypfer/Valetudo/commit/ae7c05948c9cf7252bfedd1fe935c65d69a986b3))\r\n* **vendor.dreame:** Handle some previously unhandled messages ([810a212](https://github.com/Hypfer/Valetudo/commit/810a21226bb1580ed2afae9e2a2fad2b6faa475d))\r\n* **webserver:** Fix SystemRouter units ([fd908f6](https://github.com/Hypfer/Valetudo/commit/fd908f6da756d3d5a6f8350e1a4f4041990a6cf9))\r\n* **webserver:** os.freemem() isn't what it appears to be ([80743f4](https://github.com/Hypfer/Valetudo/commit/80743f455dd20d2abc316260308b9d322c33e284))\r\n* **webserver:** Properly report memory info for kernels older than 3.14 but newer than 2.6 ([9000f51](https://github.com/Hypfer/Valetudo/commit/9000f51eaf818ca465ad0b2ef9f91ca421ac2da4))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/968", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083/reactions", + "total_count": 13, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 13, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/49812967/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.09.1", + "id": 49812967, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4C-BXn", + "tag_name": "2021.09.1", + "target_commitish": "master", + "name": "Valetudo 2021.09.1", + "draft": false, + "prerelease": false, + "created_at": "2021-09-19T12:08:23Z", + "published_at": "2021-09-19T12:23:58Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138012", + "id": 45138012, + "node_id": "RA_kwDOCGKICM4CsMBc", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33923724, + "download_count": 145, + "created_at": "2021-09-19T12:31:14Z", + "updated_at": "2021-09-19T12:31:16Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138227", + "id": 45138227, + "node_id": "RA_kwDOCGKICM4CsMEz", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13400596, + "download_count": 7, + "created_at": "2021-09-19T12:39:08Z", + "updated_at": "2021-09-19T12:39:09Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138010", + "id": 45138010, + "node_id": "RA_kwDOCGKICM4CsMBa", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31676240, + "download_count": 287, + "created_at": "2021-09-19T12:31:09Z", + "updated_at": "2021-09-19T12:31:11Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138011", + "id": 45138011, + "node_id": "RA_kwDOCGKICM4CsMBb", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31676240, + "download_count": 206, + "created_at": "2021-09-19T12:31:12Z", + "updated_at": "2021-09-19T12:31:13Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138226", + "id": 45138226, + "node_id": "RA_kwDOCGKICM4CsMEy", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12774444, + "download_count": 9, + "created_at": "2021-09-19T12:39:06Z", + "updated_at": "2021-09-19T12:39:07Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138225", + "id": 45138225, + "node_id": "RA_kwDOCGKICM4CsMEx", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12773924, + "download_count": 9, + "created_at": "2021-09-19T12:39:05Z", + "updated_at": "2021-09-19T12:39:06Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.09.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.09.1", + "body": "
\r\n \"valetudo\"\r\n

2021.09.1

\r\n
\r\n\r\nThis release is packed with UI improvements thanks to @ccoors\r\n\r\n## Event UI\r\n\r\nThe new UI now subscribes to the ValetudoEvents endpoint and allows for interaction with them.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927122-054ed31b-7a47-447f-9193-6e92ca64757b.png)\r\n\r\nThis is helpful as they might contain errors that you've missed.\r\nAlso, your robot might require confirmation from you to store a new map so make sure to keep an eye on that.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927125-d069022e-8a18-4bd3-b879-734a4f9aba96.png)\r\n\r\n\r\n## Timer UI\r\n\r\nYou can now use the new UI to set up ValetudoTimers.\r\n\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927153-e109c4a5-2bff-45e7-af07-2ae7a4eb9ace.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927151-76b2daa1-9e26-4b6d-a2e1-ba20c97e9829.png)\r\n\r\nNote that timers are always stored and evaluated as UTC. The local time display is simply a convenience feature.\r\n\r\n## MQTT config UI\r\n\r\nMQTT configuration can now also be done via the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927206-8a4188a8-d178-46fb-9c2d-32907322f5f9.png)\r\n\r\nIt features a nice topic preview to make it easier for newcomers to interact with Valetudo via MQTT.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927215-e359d45a-c76e-47bb-a178-d1118cca25bc.png)\r\n\r\nAlso, the API will no longer return any MQTT credentials but instead replace them with `` for security reasons.\r\n\r\n## Logviewer UI\r\n\r\nA basic log viewer has been added to the new UI. While still WIP, it already allows for live updates as well as filtering, which is a neat improvement.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927245-d4f98b09-0cc4-448d-9752-f939987f9e3c.png)\r\n\r\n\r\n## Auto-empty Dock related features\r\n\r\nIf you own a Dreame Z10, you're now able to enable/disable the automatic dust collection via the Swagger UI.\r\nFurthermore, you can also trigger it manually via either the UI, the REST API or MQTT, meaning that you can now fully customize the collection interval by using e.g. Home Assistant automations.\r\n\r\n## Misc\r\n\r\n### Obstacle Avoidance\r\n\r\nYou can now disable the Obstacle Avoidance Feature of your Dreame L10/Z10 via the Swagger UI if you experience issues such as the robot refusing to drive onto a carpet.\r\n\r\n### Consumables UI\r\n\r\nThe new UI now also features a consumables section with a neat hover feature hopefully helping newcomers better understand the consumables.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927281-cd81083a-be3f-415f-bf78-81818a0c26af.png)\r\n\r\n\r\n### Runtime Information UI\r\n\r\nThe new UI about section has been extended to display data returned by the runtime information endpoint.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927292-91c520e9-210e-40c4-89a1-3c0fce037ad9.png)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** AutoEmptyDockAutoEmptyControlCapability ([eeeb46c](https://github.com/Hypfer/Valetudo/commit/eeeb46c8a2152049392b7df06c952dc44b101d98))\r\n* **core:** AutoEmptyDockManualTriggerCapability ([5678d4f](https://github.com/Hypfer/Valetudo/commit/5678d4fd8e3dab9364182fa8f40fa09465bc77eb))\r\n* **core:** ObstacleAvoidanceControlCapability ([e5fab92](https://github.com/Hypfer/Valetudo/commit/e5fab92172dd6c024201218bbe4889a770c3f7c2))\r\n* **core:** Robot properties ([b1713df](https://github.com/Hypfer/Valetudo/commit/b1713dff26a2bcfd707bd88fa0dcf3acbde4faa1))\r\n* **MockRobot:** MockAutoEmptyDockManualTriggerCapability ([31cb972](https://github.com/Hypfer/Valetudo/commit/31cb972d89cba474c3c8732e969015a5bb5d9851))\r\n* **ui:** Add button to trigger dock auto empty manually ([#1087](https://github.com/Hypfer/Valetudo/issues/1087)) ([fa2def7](https://github.com/Hypfer/Valetudo/commit/fa2def7c65a2641ec6321fcdfb4c3975e607867d))\r\n* **ui:** Consumables in new UI ([#1093](https://github.com/Hypfer/Valetudo/issues/1093)) ([144d6ed](https://github.com/Hypfer/Valetudo/commit/144d6edacdf264b5a835ee184c1639f982231d25))\r\n* **ui:** Implement MQTT config ui ([#1080](https://github.com/Hypfer/Valetudo/issues/1080)) ([2dd83e3](https://github.com/Hypfer/Valetudo/commit/2dd83e3a8c8e8c1629f873b9d20a52f7337fbcd9))\r\n* **ui:** Implement timer ui ([#1077](https://github.com/Hypfer/Valetudo/issues/1077)) ([abd6345](https://github.com/Hypfer/Valetudo/commit/abd63454588e510d23d55c4f08a1caad1cc7c649))\r\n* **ui:** Log with SSE and display log in new UI ([#1092](https://github.com/Hypfer/Valetudo/issues/1092)) ([1721df7](https://github.com/Hypfer/Valetudo/commit/1721df7dd6969fba8acd63d726a8ca14d1977afd))\r\n* **ui:** Navigation and Events in UI ([#1090](https://github.com/Hypfer/Valetudo/issues/1090)) ([27fd2ba](https://github.com/Hypfer/Valetudo/commit/27fd2ba97e98f534c20ca6e22b0d46510f355706))\r\n* **ui:** Show MQTT config defaults ([711c312](https://github.com/Hypfer/Valetudo/commit/711c312cc41fff57867e5b97d4e867b3ef41b4c3))\r\n* **ui:** Show MQTT topic preview ([#1082](https://github.com/Hypfer/Valetudo/issues/1082)) ([865905e](https://github.com/Hypfer/Valetudo/commit/865905ea58bfff9187c7463fce3a312b738a1e90))\r\n* **ui:** Show runtime info on about page ([#1089](https://github.com/Hypfer/Valetudo/issues/1089)) ([ece2dc9](https://github.com/Hypfer/Valetudo/commit/ece2dc9d6d5baafa4d0aa291565087bf2e1f6148))\r\n* **vendor.dreame:** DreameAutoEmptyDockAutoEmptyControlCapability ([a1fa6d8](https://github.com/Hypfer/Valetudo/commit/a1fa6d8a14bad572aca4ce6af714cacb9d4e1760))\r\n* **vendor.dreame:** DreameAutoEmptyDockManualTriggerCapability ([b7aed1a](https://github.com/Hypfer/Valetudo/commit/b7aed1afa217ebd90f411c91844a28f05946460d))\r\n* **vendor.dreame:** DreameDoNotDisturbCapability ([60972ca](https://github.com/Hypfer/Valetudo/commit/60972ca6dd8d8200d8c25a2e4e084c04f97ef8ce))\r\n* **vendor.dreame:** DreameObstacleAvoidanceControlCapability ([ca9a499](https://github.com/Hypfer/Valetudo/commit/ca9a49939d9499dddfc9f77aede70c655758031a))\r\n* **webserver:** Provide mqtt config properties ([7e6962b](https://github.com/Hypfer/Valetudo/commit/7e6962bd8094120168c960d550027efbf3a53d73))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Accepting/rejecting a pending map change should always invalidate a pending event ([94c8da2](https://github.com/Hypfer/Valetudo/commit/94c8da29c6f3f3adc3e9f02b546dd258e4bd30bc))\r\n* **timers:** Prevent timer drift ([#1078](https://github.com/Hypfer/Valetudo/issues/1078)) ([105d02a](https://github.com/Hypfer/Valetudo/commit/105d02a67d502ba727e90251f2b9325837833ebd))\r\n* **ui:** Improve word breaks in MQTT topic preview ([#1088](https://github.com/Hypfer/Valetudo/issues/1088)) ([8736f7f](https://github.com/Hypfer/Valetudo/commit/8736f7fc9ee1d76dcb8a5c21975f85040fbfd723))\r\n* **ui:** Make timers use correct time zone offset ([#1079](https://github.com/Hypfer/Valetudo/issues/1079)) ([f790db3](https://github.com/Hypfer/Valetudo/commit/f790db3ec1eadcaa91726a75ac994b5d527058f4))\r\n* **ui:** Remove staleTime: Infinity for queries that should actually refresh automatically ([b53d428](https://github.com/Hypfer/Valetudo/commit/b53d428846f3013768827296b193ed68f4ca0255))\r\n* **ui:** Show old ui timer page even when there's no DoNotDisturbCapability ([ac19d5d](https://github.com/Hypfer/Valetudo/commit/ac19d5d2c1751c12d614ebf2c8cb701cdc7a0473))\r\n* **ui:** Timer action controls Memo dependency ([#1091](https://github.com/Hypfer/Valetudo/issues/1091)) ([7ebbafc](https://github.com/Hypfer/Valetudo/commit/7ebbafce307fc5b3e07f73f3652d154a63d3a248))\r\n* **ValetudoEvents:** Resetting a consumable should also set its event to processed ([d705c5b](https://github.com/Hypfer/Valetudo/commit/d705c5bc67cff5cb4b085893f428bf7794a26bb1)), closes [#1096](https://github.com/Hypfer/Valetudo/issues/1096)\r\n* **webserver:** Remove obsolete mqtt config password stripping ([c4f6fab](https://github.com/Hypfer/Valetudo/commit/c4f6fabc62c69b6573782e31511f8df02ea2e7a3))\r\n* **webserver:** Strip credentials from mqtt config REST response and remove ssh key upload ([5b66887](https://github.com/Hypfer/Valetudo/commit/5b6688778bd3efb884e027b51d2989e28c7252af))\r\n* **webserver:** Terminate SSE connections on shutdown for a clean shutdown ([bfbf4dd](https://github.com/Hypfer/Valetudo/commit/bfbf4dd7192a443ca7e49d9efa0f382040370741))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1098", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967/reactions", + "total_count": 2, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 2, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/49298984/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.09.0", + "id": 49298984, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4C8D4o", + "tag_name": "2021.09.0", + "target_commitish": "master", + "name": "Valetudo 2021.09.0", + "draft": false, + "prerelease": false, + "created_at": "2021-09-09T17:50:14Z", + "published_at": "2021-09-09T18:00:31Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44406742", + "id": 44406742, + "node_id": "RA_kwDOCGKICM4CpZfW", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33691524, + "download_count": 104, + "created_at": "2021-09-09T18:06:20Z", + "updated_at": "2021-09-09T18:06:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44407365", + "id": 44407365, + "node_id": "RA_kwDOCGKICM4CpZpF", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13167284, + "download_count": 7, + "created_at": "2021-09-09T18:14:59Z", + "updated_at": "2021-09-09T18:14:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44406739", + "id": 44406739, + "node_id": "RA_kwDOCGKICM4CpZfT", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31444040, + "download_count": 225, + "created_at": "2021-09-09T18:06:17Z", + "updated_at": "2021-09-09T18:06:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44406740", + "id": 44406740, + "node_id": "RA_kwDOCGKICM4CpZfU", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31444040, + "download_count": 156, + "created_at": "2021-09-09T18:06:18Z", + "updated_at": "2021-09-09T18:06:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44407364", + "id": 44407364, + "node_id": "RA_kwDOCGKICM4CpZpE", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12541772, + "download_count": 9, + "created_at": "2021-09-09T18:14:57Z", + "updated_at": "2021-09-09T18:14:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44407363", + "id": 44407363, + "node_id": "RA_kwDOCGKICM4CpZpD", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12541788, + "download_count": 10, + "created_at": "2021-09-09T18:14:57Z", + "updated_at": "2021-09-09T18:14:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.09.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.09.0", + "body": "
\r\n \"valetudo\"\r\n

2021.09.0

\r\n
\r\n\r\nThis release features some more bugfixes and some breaking config changes\r\n\r\n## New UI\r\n\r\nIf you haven't seen it already, check out [the previous release notes](https://github.com/Hypfer/Valetudo/releases/tag/2021.08.1).\r\n\r\n## MQTT changes\r\n\r\n### Config Schema\r\nThis release features a much cleaner mqtt configuration schema. Now, one can actually understand what the options are for.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/132738325-10a47c75-f321-4c79-94ec-374484d7b7f4.png)\r\n\r\n\r\n\r\nSince this a **breaking change**, Valetudo will likely reject your old config file and create a new one.\r\nDon't worry though. The old one is backed up meaning that you can simply copy-paste your timers, presets etc.\r\nJust check the Log for more information.\r\n\r\n### Identifier\r\n\r\nValetudo will now use the autogenerated machine identifier as the mqtt identifier and friendly name.\r\nIf you've been using the defaults until now, you'll either want to manually configure the identifier or update your scripts, delete your Vacuum Device in Home Assistant etc.\r\n\r\nThe autogenerated unique machine identifier can be found in the Log.\r\nIt will sorta look like this: `ModestFewChinchilla`\r\n\r\n### Home Assistant Map Data\r\n\r\nThe Map data camera image has been replaced with a nicer looking one that will also hopefully lead to less confusion for newcomers.\r\nIt looks like this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/132737756-efba2973-0ed7-47cb-bae4-6b6ca18acf67.png)\r\n\r\n\r\n## Out-of-Memory Issues\r\n\r\nThe out of memory issues causing Valetudo to shut down have been fixed again even though that they were already fixed.\r\nFor some reason, npm started installing the old and unpatched dependency. Probably some weirdness regarding the `package-lock.json` or something like that.\r\n\r\nThis has been solved by reimplementing what the dependency did in Valetudo itself. Fortunately, this allowed us to add logging to that.\r\nIf you're seeing something like `[WARN] Stale SSE connection to the Map SSE Hub detected. Terminating.` in your log, the mitigation is working.\r\n\r\n## Updated Robot Docs\r\n\r\nI've added some notes for each implementation to the [Supported Robots Page](https://valetudo.cloud/pages/general/supported-robots.html) to make it easier for people to choose a robot to buy.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Log autogenerated system ID ([2cc365c](https://github.com/Hypfer/Valetudo/commit/2cc365c60415f68e3ec7d454eda8387adf8c9842))\r\n* **ui:** make toggle group full width ([#1060](https://github.com/Hypfer/Valetudo/issues/1060)) ([dfdd7f7](https://github.com/Hypfer/Valetudo/commit/dfdd7f7de54ad84f0f4fd52e34692879ce0116ff))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** reduce loglevel of user ack timeout spam messages ([3f81d4c](https://github.com/Hypfer/Valetudo/commit/3f81d4c063595f129d7b08114377b6b4703628e1))\r\n* **mqtt:** Poll robot state every refreshInterval to mitigate stale data on lost cloud connections ([95ce4bb](https://github.com/Hypfer/Valetudo/commit/95ce4bb333911f67afadd769af4104d8286dae6b))\r\n* **openapi:** Fix examples schema for ManualControlCapability ([b22ceb7](https://github.com/Hypfer/Valetudo/commit/b22ceb7288f87540492182eba58f821fe44a544e))\r\n* **ui:** Change path color to black for better visibility ([2454a85](https://github.com/Hypfer/Valetudo/commit/2454a85a650a9323293dd9190cf5a955b8b2e7f8))\r\n* **vendor.viomi:** catch set_timezone errors ([c2cbd45](https://github.com/Hypfer/Valetudo/commit/c2cbd4588dede2b4d6a86c7d0807b16d7308d0f2))\r\n\r\n### Reverts\r\n\r\n* Revert \"fix(vendor.viomi): Poll state every 30s to fix stale mqtt data\" ([b55e4a5](https://github.com/Hypfer/Valetudo/commit/b55e4a58edc20d3d7e3f67274891d46967f0fd8d))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1075", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984/reactions", + "total_count": 9, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 9, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/48695654/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.08.1", + "id": 48695654, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ4Njk1NjU0", + "tag_name": "2021.08.1", + "target_commitish": "master", + "name": "Valetudo 2021.08.1", + "draft": false, + "prerelease": false, + "created_at": "2021-08-30T18:48:12Z", + "published_at": "2021-08-30T19:15:34Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642309", + "id": 43642309, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyMzA5", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33724473, + "download_count": 117, + "created_at": "2021-08-30T19:23:13Z", + "updated_at": "2021-08-30T19:23:14Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642721", + "id": 43642721, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyNzIx", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13200601, + "download_count": 5, + "created_at": "2021-08-30T19:32:24Z", + "updated_at": "2021-08-30T19:32:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642306", + "id": 43642306, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyMzA2", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31476989, + "download_count": 252, + "created_at": "2021-08-30T19:23:11Z", + "updated_at": "2021-08-30T19:23:12Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642307", + "id": 43642307, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyMzA3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31476989, + "download_count": 181, + "created_at": "2021-08-30T19:23:12Z", + "updated_at": "2021-08-30T19:23:13Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642720", + "id": 43642720, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyNzIw", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12575097, + "download_count": 17, + "created_at": "2021-08-30T19:32:24Z", + "updated_at": "2021-08-30T19:32:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642719", + "id": 43642719, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyNzE5", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12574937, + "download_count": 7, + "created_at": "2021-08-30T19:32:23Z", + "updated_at": "2021-08-30T19:32:23Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.08.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.08.1", + "body": "
\r\n \"valetudo\"\r\n

2021.08.1

\r\n
\r\n\r\nThis release features the new React-based UI by @Jomik as well as some MQTT config changes\r\n\r\n## New UI\r\n\r\nThe new UI has been merged and is now available as a usable preview.\r\nThere's still a lot to do, however that should be much easier now that it is merged.\r\n\r\nUntil everything has been ported over, the old UI will still be the default.\r\n\r\nYou can open the new one via the menu, which now also houses a shortcut to the Swagger UI as well:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392121-d28f2ae6-278d-49a3-a51e-2ca338107ec6.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392013-d984ab62-b3c4-4590-9081-f7f457b8ad11.png)\r\n\r\n\r\nThere's a drop-down where you can select a zone preset to clean in the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392187-40648196-50be-4c23-8cea-4ed1864decd5.png)\r\n\r\n\r\nFuthermore, there's also a button, which lets you set the iteration count for segment cleanups.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392224-31302e3d-c8dc-43ce-823f-8c82732a6ffd.png)\r\n\r\n\r\n\r\nThis marks a huge step forward for the project, which has been due since years. Thanks again to @Jomik ❤\r\n\r\n## MQTT config changes\r\n\r\nThis release removes all mqtt settings where I couldn't find a reasonable explanation for why they exist.\r\nIf you're missing something, please let me know in the comments and include an explanation _why_ it was needed.\r\n\r\n## Dreame Z10 Pro Support\r\n\r\nIf you're looking for a Valetudo-supported and affordable Vacuum Robot featuring an Auto-Empty Dock, you can now buy\r\nthe Dreame Z10 Pro. I didn't know that I needed an auto-empty dock before I got one, but I definitely needed one.\r\n\r\nDo note that it's supported on the feature level of the L10 Pro, meaning that you can't control the Dock yet.\r\nThat shouldn't matter though as it is on by default and doesn't strictly require any interactions.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Add link to swagger ui to menu ([513bd8c](https://github.com/Hypfer/Valetudo/commit/513bd8c2778ae2f26186ae48f69030bbfde59628))\r\n* **ui:** Added html title to symbols in various map views ([#1026](https://github.com/Hypfer/Valetudo/issues/1026)) ([98d0f1e](https://github.com/Hypfer/Valetudo/commit/98d0f1e617cae48cbd44a171b5aa9178f0677a0b))\r\n* **ui:** Display system host info ([54df5ca](https://github.com/Hypfer/Valetudo/commit/54df5ca4f6b53a280bad52f0a73f074e1d5122f3))\r\n* **ui:** Support segment cleanup iteration count selection in map view ([f798ff5](https://github.com/Hypfer/Valetudo/commit/f798ff5d040e08a7b2f4d2606e61d8c5000957f5))\r\n* **vendor.dreame:** Add Dreame Z10 Pro ([4127ccd](https://github.com/Hypfer/Valetudo/commit/4127ccdc413155c5f3d03a29b51fc7c2f10a1353))\r\n* **vendor.dreame:** Log rootfs on startup if embedded ([cbde5a4](https://github.com/Hypfer/Valetudo/commit/cbde5a4873be1113b0dc5cfee0c1164cdc5bedf4))\r\n* **vendor.roborock:** Log rootfs on startup if embedded ([8d09fd6](https://github.com/Hypfer/Valetudo/commit/8d09fd6dab8413b3b5e9aa89921014ef267b3f23))\r\n* New React UI ([9acb2cd](https://github.com/Hypfer/Valetudo/commit/9acb2cd529a1b84dd7db333778dd523d8487c4e7))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Add proper shutdown methods to dummycloud and retrywrapper ([f0676ef](https://github.com/Hypfer/Valetudo/commit/f0676efa6d81535069f156dab2611b63b7e4d27c))\r\n* **miio:** Reduce loglevel for non-pending messages ([dbabe0b](https://github.com/Hypfer/Valetudo/commit/dbabe0b3a8e9540aff2d6f8f76dfdea2b68c767f))\r\n* **mqtt:** Catch exceptions on connect reconfiguration ([0e3bebd](https://github.com/Hypfer/Valetudo/commit/0e3bebda27553ee7f7b3796a4b89dbd53eec1ccb))\r\n* **mqtt:** Fix 100% cpu consumable fetch recursion ([ae163a9](https://github.com/Hypfer/Valetudo/commit/ae163a95e95b384e4e3e2804f9a4792c9e9793e9))\r\n* **mqtt:** Remove refreshInterval setting ([83d2a45](https://github.com/Hypfer/Valetudo/commit/83d2a45eb0d21cc15cc58cdf1734833688de0fac))\r\n* **networkadvertisement:** Hopefully fix valetudo crashing due to network issues ([4ace37e](https://github.com/Hypfer/Valetudo/commit/4ace37e0aaf88e5bb53dfbab5fbb4bf1d43c685e))\r\n* **ui:** Fix minor issues discovered by deepscan ([ee8b58b](https://github.com/Hypfer/Valetudo/commit/ee8b58b646ce006d8c1d6a5cca2f27d6af32392c))\r\n* **ui:** Only dark mode (for now?) ([db985f3](https://github.com/Hypfer/Valetudo/commit/db985f39fcfdf1bc9048d50a3e2d7d75bc42f3da))\r\n* **vendor.dreame:** Add error code 68 mapping ([741c711](https://github.com/Hypfer/Valetudo/commit/741c7114d4b88760cd30ab7e50697816f968ed2a))\r\n* **vendor.dreame:** Fix incorrect status mapping for powersave mode ([343c749](https://github.com/Hypfer/Valetudo/commit/343c749a107fdaa4f016965984065585c0872616))\r\n* **vendor.dreame:** Ignore \"event_occured\" cloud messages ([4d3f4ac](https://github.com/Hypfer/Valetudo/commit/4d3f4acf8fd864d690850070328b5f9b115934d4))\r\n* **vendor.roborock:** Handle more events ([972e4df](https://github.com/Hypfer/Valetudo/commit/972e4df9fc840c85324de7ef926763a521bd225d))\r\n* **vendor.viomi:** Poll state every 30s to fix stale mqtt data ([fdb315a](https://github.com/Hypfer/Valetudo/commit/fdb315a33beb6690a68f34a131bd7484802ded7d))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1055", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654/reactions", + "total_count": 10, + "+1": 2, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 8, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/43589051", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/43589051/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/43589051/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.05.0", + "id": 43589051, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQzNTg5MDUx", + "tag_name": "2021.05.0", + "target_commitish": "master", + "name": "Valetudo 2021.05.0", + "draft": false, + "prerelease": false, + "created_at": "2021-05-26T10:37:22Z", + "published_at": "2021-05-26T11:04:43Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565658", + "id": 37565658, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjU4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 36786214, + "download_count": 158, + "created_at": "2021-05-26T11:13:56Z", + "updated_at": "2021-05-26T11:13:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565661", + "id": 37565661, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjYx", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 16387654, + "download_count": 9, + "created_at": "2021-05-26T11:13:57Z", + "updated_at": "2021-05-26T11:13:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565650", + "id": 37565650, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjUw", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34465042, + "download_count": 400, + "created_at": "2021-05-26T11:13:51Z", + "updated_at": "2021-05-26T11:13:52Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565653", + "id": 37565653, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjUz", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34465042, + "download_count": 181, + "created_at": "2021-05-26T11:13:54Z", + "updated_at": "2021-05-26T11:13:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565656", + "id": 37565656, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjU2", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 15746822, + "download_count": 13, + "created_at": "2021-05-26T11:13:55Z", + "updated_at": "2021-05-26T11:13:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565651", + "id": 37565651, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjUx", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 15746694, + "download_count": 11, + "created_at": "2021-05-26T11:13:53Z", + "updated_at": "2021-05-26T11:13:53Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.05.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.05.0", + "body": "
\r\n \"valetudo\"\r\n

2021.05.0

\r\n
\r\n\r\nThis release features mostly bugfixes, unfinished features and a hostile takeover.\r\n\r\n## MQTT Rewrite\r\n\r\nDue to the scale of the MQTT rewrite that happened with 2021.04.0, some new bugs were introduced, which have been fixed with this release.\r\n\r\nFurthermore, this release removes the migration logic of the old mqtt config format so if you're planning on upgrading from something other than 2021.04.0, make sure to upgrade to that before installing 2021.05.0.\r\n\r\nAs always, reading all the release notes is strongly recommended during upgrades.\r\n\r\n## Not-yet finished things\r\n\r\nNot everything in this section is already part of this release.\r\n\r\n### UI Rewrite\r\n\r\n@jomik is still working on the rewrite of the Valetudo UI. It's already looking fantastic:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/119648987-635ae980-be22-11eb-82c9-3b1c999303c4.png)\r\n![image](https://user-images.githubusercontent.com/974410/119649000-6655da00-be22-11eb-831a-cb816a3991be.png)\r\n\r\n\r\nIf you're a frontend dev, a design person etc., feel free to join in. :)\r\nWe'll definitely need some design input, custom icons and much more stuff.\r\n\r\n### Timers\r\n\r\nA simple scheduler feature has been added to the backend for setups where a full-blown home automation system isn't required.\r\nThese shall be understood as WIP and can currently only be controlled [via REST API calls](https://github.com/Hypfer/Valetudo/discussions/824#discussioncomment-761574).\r\n\r\n### Dreame Support\r\n\r\nPublic root coming soon™, again.\r\n\r\nThe beta test has been expanded to more users. If you want to take part in that, make sure to join the [Telegram Dreame Usergroup](https://t.me/joinchat/2qGFUaQ2pV9hNzUy) and check out the pinned form.\r\nCurrently, the announcement of the Dreame W10 and Z10 is delaying the release of the rooting method.\r\n\r\n## Freenode hostile takeover\r\n\r\nAs you might've heard, Freenode, the FOSS IRC network has been taken over by the crown prince of korea, who decided to have some fun with it.\r\n\r\nToday, the #Valetudo Freenode channel was also taken over:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/119649150-97360f00-be22-11eb-9508-2dfb93ea39be.png)\r\n\r\n\r\nThere are other and much more popular victims of this:\r\n\r\n- https://mastodon.sdf.org/@kline/106299403921451814\r\n- https://news.ycombinator.com/item?id=27286628\r\n- https://twitter.com/fosdem/status/1397454352835653632\r\n\r\nI've left the network and strongly advice you to do the same.\r\n[https://libera.chat/](https://libera.chat/) is the continuation of Freenode with a different name, but the same Team that has been running Freenode for the last 20 years.\r\n\r\nFreenode on the other hand is just the same name but with completely different people.\r\n\r\nStick to the community. Not to the brand.\r\n\r\nFor more information, check out some of the resignation letters of the former freenode and current libera staff:\r\n\r\n- kline: https://www.kline.sh/\r\n- jess: https://gist.github.com/jesopo/45a3e9cdbe517dc55e6058eb43b00ed9\r\n- Md: https://blog.bofh.it/debian/id_461\r\n- niko: https://coevoet.fr/freenode.html\r\n- edk: https://gist.github.com/edk0/478fb4351bc3ba458288d6878032669d\r\n- emilsp: https://gist.github.com/pinkisemils/39d4ded8b1639b6f39dcab15618649f5\r\n- mniip: https://mniip.com/freenode.txt\r\n- Swant: https://swantzter.se/freenode-resignation/\r\n- JonathanD: https://gist.github.com/JonathanD82/6518b93708e0aaf4b8f92c8e7200816d\r\n\r\nThere's also a neat FAQ by @joepie91: https://gist.github.com/joepie91/df80d8d36cd9d1bde46ba018af497409\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **vendor.dreame:** Add iteration count to MapSegmentationCapability ([05b338f](https://github.com/Hypfer/Valetudo/commit/05b338f069feb7c311dcc11d7b50d91e310e79d3))\r\n* Timers ([7b8c37a](https://github.com/Hypfer/Valetudo/commit/7b8c37ad1006aec62e1f19e5aec83d54da94189d))\r\n* **ntpClient:** Keep track of the current state and enable configuration via REST ([e350eba](https://github.com/Hypfer/Valetudo/commit/e350eba43ab36076d406c02f933c7be108cc8e99))\r\n* **vendor.dreame:** 1C: Add/fix various Map & Volume capabilities ([#915](https://github.com/Hypfer/Valetudo/issues/915)) ([c88df12](https://github.com/Hypfer/Valetudo/commit/c88df12de41ec05797adeb4c5215bf4d18456c9b))\r\n* **vendor.roborock:** Add support for ordered segment cleanup with multiple iterations ([2541113](https://github.com/Hypfer/Valetudo/commit/25411138688454d43026d07c12e46b5eab5e9269))\r\n* **vendor.viomi:** Implement DND capability ([#877](https://github.com/Hypfer/Valetudo/issues/877)) ([dd05c51](https://github.com/Hypfer/Valetudo/commit/dd05c51f4dfa45ffdf973b95e6b4851e423a176c))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Better map upload logline ([0e7ce7c](https://github.com/Hypfer/Valetudo/commit/0e7ce7c7486498c55dd0443dd9cb0251fde1dab2))\r\n* **mqtt:** Allow strings as segment IDs ([#891](https://github.com/Hypfer/Valetudo/issues/891)) ([3e30414](https://github.com/Hypfer/Valetudo/commit/3e304146980c8dc2a394a54e7346528ec5a07620)), closes [#889](https://github.com/Hypfer/Valetudo/issues/889)\r\n* **mqtt:** Always publish state ([6a041c6](https://github.com/Hypfer/Valetudo/commit/6a041c62cfff4d2b04eb48e15ee20373512838fe))\r\n* **mqtt:** Only migrate HAss topics if enabled ([#912](https://github.com/Hypfer/Valetudo/issues/912)) ([eb2edaf](https://github.com/Hypfer/Valetudo/commit/eb2edaf969a175648cb0f53405b1780f0ac799d2))\r\n* **mqtt:** Publish state for both hass and homie, as the hass device availability_topic is set to the same topic ([#860](https://github.com/Hypfer/Valetudo/issues/860)) ([219bc34](https://github.com/Hypfer/Valetudo/commit/219bc348e95d78ff7dd279c52d498401b5e9d28c))\r\n* **mqtt:** Remove unnecessary availability_topic ([#859](https://github.com/Hypfer/Valetudo/issues/859)) ([aa85205](https://github.com/Hypfer/Valetudo/commit/aa85205fe09007b4b411ef9de754513dda98a4a0)), closes [#858](https://github.com/Hypfer/Valetudo/issues/858)\r\n* **ntpClient:** Support disabling the ntpClient ([949d8e3](https://github.com/Hypfer/Valetudo/commit/949d8e306b5de34c3a3755532f269f009eb50c51)), closes [#925](https://github.com/Hypfer/Valetudo/issues/925)\r\n* **timers:** Copy-paste antipattern ([e331eda](https://github.com/Hypfer/Valetudo/commit/e331eda332e12a138cd1d7e8b8994208f714833a))\r\n* **timers:** Fix zoned scheduled cleanup ([34443b3](https://github.com/Hypfer/Valetudo/commit/34443b3bea4feac5c48844554cd9a816df6f60ff))\r\n* **ui:** DND should be rendered as localtime but stored as UTC ([fd79163](https://github.com/Hypfer/Valetudo/commit/fd79163c3e9328562346a789ad5cec6e73bfe52d))\r\n* **vendor.dreame:** Ignore uploaded multi-map data ([6f3dcc5](https://github.com/Hypfer/Valetudo/commit/6f3dcc5a9a2a39eed6dcc73f2f08d1f438b09cac))\r\n* **vendor.roborock:** Handle DND as UTC ([8fc9ea8](https://github.com/Hypfer/Valetudo/commit/8fc9ea88d81505259f53e0dad5be3ed0e05d5d6f))\r\n* **vendor.roborock:** Roborock only accepts int coordinates ([c7efd6a](https://github.com/Hypfer/Valetudo/commit/c7efd6af1379de2e94594c440c126b74a36a7962))\r\n* Print error message when failing to load config file ([#914](https://github.com/Hypfer/Valetudo/issues/914)) ([9ebda7e](https://github.com/Hypfer/Valetudo/commit/9ebda7eb52185c5d8474344f0e25a653003c1d87))\r\n* **vendor.roborock:** Remove invalid RoborockCombinedVirtualRestrictionsCapability from V1 robot ([5a2bae4](https://github.com/Hypfer/Valetudo/commit/5a2bae404dfebf5e641a3e490e50f7bd254f633b))\r\n* **vendor.viomi:** Fix system timezone in init script ([#876](https://github.com/Hypfer/Valetudo/issues/876)) ([908d5dd](https://github.com/Hypfer/Valetudo/commit/908d5ddc16b03dbe92e1aafe9e0d4f755312e3d4))\r\n* **vendor.viomi:** Syntax error in init script ([2d53b7c](https://github.com/Hypfer/Valetudo/commit/2d53b7cf8a4e25764795859f88f6b4bb24a291e1))\r\n* **vendor.viomi:** Viomi minor bugfixes ([#820](https://github.com/Hypfer/Valetudo/issues/820)) ([4742214](https://github.com/Hypfer/Valetudo/commit/47422140a77e4253606e1e0f360eaaaebb6831f7))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/944" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/41971628", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/41971628/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/41971628/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.04.0", + "id": 41971628, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQxOTcxNjI4", + "tag_name": "2021.04.0", + "target_commitish": "master", + "name": "Valetudo 2021.04.0", + "draft": false, + "prerelease": false, + "created_at": "2021-04-25T16:42:16Z", + "published_at": "2021-04-25T17:40:22Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/35800383", + "id": 35800383, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM1ODAwMzgz", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34350491, + "download_count": 274, + "created_at": "2021-04-25T17:41:05Z", + "updated_at": "2021-04-25T17:41:05Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.04.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/35800380", + "id": 35800380, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM1ODAwMzgw", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32577571, + "download_count": 605, + "created_at": "2021-04-25T17:41:02Z", + "updated_at": "2021-04-25T17:41:03Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.04.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/35800381", + "id": 35800381, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM1ODAwMzgx", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32577571, + "download_count": 391, + "created_at": "2021-04-25T17:41:03Z", + "updated_at": "2021-04-25T17:41:04Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.04.0/valetudo-armv7-lowmem" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.04.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.04.0", + "body": "
\r\n \"valetudo\"\r\n

2021.04.0

\r\n
\r\n\r\nThis release features a complete rewrite of the MQTT interface, which brings superior OpenHAB support by fully\r\nimplementing the Homie specification, Segment renaming, Water Usage Controls, No-Mop-Zones, UI improvements and better\r\nstability in low-mem environments such as the Roborock S5 Max\r\n\r\n## Newcomer Guide\r\n\r\nTo answer common questions newcomers or people that haven't actively been following the project may have, there's now\r\nthe [Valetudo Newcomer Guide Early 2021 Edition](https://valetudo.cloud/pages/general/newcomer_guide_early_2021.html) in the docs.\r\n\r\n## MQTT Rewrite\r\n\r\n@depau has spent countless hours completely rewriting the MQTT Interface of Valetudo.\r\nNote that this is a breaking change and will require additional attention from you on upgrade.\r\n\r\nWe're now fully [Homie-compatible](https://homieiot.github.io) which brings much better support for Home Automation systems other than Home Assistant such as [OpenHAB](https://www.openhab.org/) which has recently been completely overhauled.\r\nMake sure to check out [their new demo](https://demo.openhab.org/) as well as the [Valetudo OpenHAB integration docs](https://valetudo.cloud/pages/integrations/openhab-integration.html).\r\n\r\nIf you're using something else such as FHEM or ioBroker, the new Homie MQTT implementation should also be much easier to work with.\r\nDocumentation on the new MQTT schema can be found in the [MQTT Docs](https://valetudo.cloud/pages/integrations/mqtt.html).\r\n\r\nDavide also went the extra mile and wrote an excellent [developer documentation for the new MQTT feature](https://valetudo.cloud/pages/development/mqtt.html) which is a must-read if you want to contribute to that part of Valetudo.\r\n\r\n### Home Assistant MQTT Rewrite FAQ\r\n\r\nValetudo will try its best to auto-migrate your configuration file and Home Assistant configuration.\r\nHowever, the latter may not work 100% all the time. Therefore, here's an FAQ for Home Assistant users migrating to Valetudo 2021.04.0\r\n\r\nQ: Home Assistant now shows everything as unavailable.\r\nA: Refresh the page\r\n\r\nQ: The consumables do not update in Home Assistant\r\nA: Wait one minute, or open valetudo and navigate to the consumables page\r\n\r\nQ: ICBINV does not seem to be retrieving the map\r\nA: The map topic changed, it is now TOPIC_PREFIX/IDENTIFIER/MapData/map-data, update your ICBINV config and ICBINV to 2021.04.0\r\n\r\nQ: Some stuff is still not detected by Home Assistant\r\nA: Reset the autodiscovery configuration by performing the following:\r\n1. Go to the MQTT settings\r\n2. Disable MQTT, enable \"Delete autodiscovery on shutdown\" under \"Home Assistant Autodscovery\".\r\n3. Save MQTT configuration\r\n4. Check Hass to ensure everything has disappeared, refresh the page as needed.\r\n5. Enable MQTT, disable \"Delete autodiscovery on shutdown\" under \"Home Assistant Autodscovery\".\r\n6. Save MQTT configuration\r\n\r\nQ: `vacuum.send_command` doesn't work anymore\r\nA: Yep. The docs will be updated shortly with information on how to achieve the same stuff now\r\n\r\n## Segment Renaming\r\n\r\nValetudo now supports (re-)naming segments and cleaning them from the UI Homepage in the same way you'd trigger a\r\nZonePreset cleanup.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/116003253-844ed580-a5fd-11eb-9ef1-4325a0104996.png)\r\n\r\n## Water Usage Control and No-Mop Zones\r\n\r\nIt is now possible to control the water grades of your robot using Valetudo, which is a completely new feature\r\nthat never appeared elsewhere before :^)\r\n\r\nFurthermore, no-mop-zones are back as well.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/116003434-38e8f700-a5fe-11eb-8273-39f8f713479d.png)\r\n![image](https://user-images.githubusercontent.com/974410/116003272-9d578680-a5fd-11eb-9c4d-8d954bec7913.png)\r\n\r\n\r\n## Lowmem enhancements\r\n\r\nAs it turns out, running nodejs in very resource-limited embedded environments such as vacuum robots isn't exactly\r\nthe intended core use-case of the runtime, which is why we seem to be pushing the limits especially on devices with\r\nonly 256mb ob ram such as the Roborock S5 Max.\r\n\r\nAnother surprising discovery is that Nodejs Buffers are not part of the configured heap, which is why even though we've\r\nset the maximum heap size to under 40mb, in some cases, the rss of Valetudo grew to over 100mb, which then caused some\r\nrobots to go out of memory.\r\n\r\nFor some reason, the garbage collector simply doesn't care about old and unused Buffers even if the memory pressure rises.\r\nTherefore, for now, we're forcing a manual garbage collection if the memory usage seems odd.\r\n\r\nThis significantly improved the stability on the S5 Max and is now enabled for all builds.\r\nStill, I'd recommend choosing the lowmem build for 256mb ram roborock robots.\r\n\r\n## UI\r\n\r\nStuff such as Virtual Walls will now snap to reasonable angles on creation so that you don't get virtual walls that are infuriatingly almost straight but not quite.\r\n\r\n## Musl\r\n\r\nThanks to recent changes in vercel/pkg, the nodejs base binaries used are now statically linked against musl instead of glibc,\r\nwhich apart from being neat enables us to drop the DNSHack.\r\n\r\nAlso, we've upgraded the runtime to Node v14.16.1\r\n\r\n## Dreame Support\r\n\r\nThe Dreame 1c support has been greatly improved thanks to the help of @frankZZ\r\n\r\nPublic root coming soon™\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Collect our own garbage ([3c3df9a](https://github.com/Hypfer/Valetudo/commit/3c3df9a584cdb7193715b583fbb90c9dcd8591ca))\r\n* **core:** MapSegmentRenameCapability ([6371291](https://github.com/Hypfer/Valetudo/commit/63712911c5a81584fc6482ac94d587aa35e5bfbb))\r\n* **MockRobot:** add GoToLocationCapability and MockMap ([2957e25](https://github.com/Hypfer/Valetudo/commit/2957e25bb57c9f9c8f8c68dcf4691900b4e68544))\r\n* **MockRobot:** add MapResetCapability ([531498b](https://github.com/Hypfer/Valetudo/commit/531498b47327ddf4be6337806e68020eafa597eb))\r\n* **MockRobot:** Add MockCarpetModeControlCapability ([#759](https://github.com/Hypfer/Valetudo/issues/759)) ([5bd5fb7](https://github.com/Hypfer/Valetudo/commit/5bd5fb7a99988cc6f0db7d2ed2d39b16d756cca7))\r\n* **MockRobot:** Add MockConsumableMonitoringCapability ([6d8b8e0](https://github.com/Hypfer/Valetudo/commit/6d8b8e092ad31190c111c7a0b12f5acbcb319b5b))\r\n* **MockRobot:** Add MockDoNotDisturbCapability ([f85194c](https://github.com/Hypfer/Valetudo/commit/f85194c0192a8a0d5b6b0058f6250841eb08d89f))\r\n* **MockRobot:** Add MockWifiConfigurationCapability ([accba05](https://github.com/Hypfer/Valetudo/commit/accba051906cdb111e734bf1950484f918562e9c))\r\n* **MockRobot:** add PersistentMapControlCapability ([f91e8e7](https://github.com/Hypfer/Valetudo/commit/f91e8e7e38d0a14de7f22fd432ef14cb8dd5d09f))\r\n* **MockRobot:** Add speaker capabilities ([12d1a27](https://github.com/Hypfer/Valetudo/commit/12d1a27119fad31a9f4d3b56c3a73b9f0cde24f2))\r\n* **mqtt:** Add MapSegmentationCapabilityMqttHandle ([#842](https://github.com/Hypfer/Valetudo/issues/842)) ([0534888](https://github.com/Hypfer/Valetudo/commit/0534888b23295d031fac7358a1846a0355b7b504))\r\n* **mqtt:** Add vacuum error state description property ([#850](https://github.com/Hypfer/Valetudo/issues/850)) ([14793c7](https://github.com/Hypfer/Valetudo/commit/14793c7744aa38f83de5c8eab88b0abfebd1edb1)), closes [#816](https://github.com/Hypfer/Valetudo/issues/816)\r\n* **mqtt:** Await MQTT disconnect before proceeding with shutdown ([1c0410c](https://github.com/Hypfer/Valetudo/commit/1c0410c1d6fe0554609baaaa521ebe9d300fe5f3))\r\n* **mqtt:** Provide segment information ([f104189](https://github.com/Hypfer/Valetudo/commit/f1041890164d451d7ee9e6c8a991a8f360bd394c))\r\n* **mqtt:** Remove increase/decrease from intensity capability ([#843](https://github.com/Hypfer/Valetudo/issues/843)) ([e6fd6e4](https://github.com/Hypfer/Valetudo/commit/e6fd6e4534db0366078b7cd7797dc0f0051ade99))\r\n* **ui:** Add dialog for renaming segments ([#772](https://github.com/Hypfer/Valetudo/issues/772)) ([306b8ba](https://github.com/Hypfer/Valetudo/commit/306b8ba9c27331bb79f886b468b0edadd86c1e70))\r\n* **ui:** add Segments on home ([2129e22](https://github.com/Hypfer/Valetudo/commit/2129e2278362424f42eab7c2062094461911f720)), closes [#773](https://github.com/Hypfer/Valetudo/issues/773)\r\n* **ui:** capitalize robot states in UI ([#765](https://github.com/Hypfer/Valetudo/issues/765)) ([c988e69](https://github.com/Hypfer/Valetudo/commit/c988e6992d85b84a1d24c1f01b097d7734ac6603))\r\n* **ui:** Generate consumables list dynamically ([#764](https://github.com/Hypfer/Valetudo/issues/764)) ([05d658b](https://github.com/Hypfer/Valetudo/commit/05d658bc90fb8a4fee13a81caae4fb2a0fb5de8c))\r\n* **ui:** Snap zones and walls to grid and reasonable angles to implement [#796](https://github.com/Hypfer/Valetudo/issues/796) ([25836e8](https://github.com/Hypfer/Valetudo/commit/25836e87b70e9065d943daf1ce85478bee179074))\r\n* **ui:** Toggle button states depending on Robot Capabilities ([#769](https://github.com/Hypfer/Valetudo/issues/769)) ([cc66d52](https://github.com/Hypfer/Valetudo/commit/cc66d5292f1ba0306e8b5362b63860d177fb5b0f))\r\n* **ui:** Water Usage Control ([cf375ce](https://github.com/Hypfer/Valetudo/commit/cf375ceeb65ace4f0cbe99a7ef58d865426e6e07))\r\n* **vendor.dreame:** 1C voicepack install support ([#795](https://github.com/Hypfer/Valetudo/issues/795)) ([b72ca53](https://github.com/Hypfer/Valetudo/commit/b72ca53f99bfa94f693c1b9c36a904cc417c2533))\r\n* **vendor.dreame:** Add Dreame F9 ([4fe0ff7](https://github.com/Hypfer/Valetudo/commit/4fe0ff7fd952533a073cd51432626f99aeadd856))\r\n* **vendor.dreame:** Add more 1C variants ([9e2e194](https://github.com/Hypfer/Valetudo/commit/9e2e194bcdacc141fc87e5c49489eb669de9c8a9))\r\n* **vendor.dreame:** Add MOVA Z500 ([0107932](https://github.com/Hypfer/Valetudo/commit/01079324727b71acd17eb8d8b16a2547663179b3))\r\n* **vendor.dreame:** DreameCarpetModeControlCapability ([2d674d4](https://github.com/Hypfer/Valetudo/commit/2d674d4d6381f9ca7f146d71445e671f14195773))\r\n* **vendor.dreame:** DreameMapResetCapability ([f60fe24](https://github.com/Hypfer/Valetudo/commit/f60fe242ba8b2bba4560a7c91443ba0c07dbd133))\r\n* **vendor.dreame:** DreameWaterUsageControlCapability ([8be7cd4](https://github.com/Hypfer/Valetudo/commit/8be7cd437bcd2cb938ea5798f767b112c22f87b5))\r\n* **vendor.viomi:** Add viomi.vacuum.v6 to supported devices ([#849](https://github.com/Hypfer/Valetudo/issues/849)) ([a18633c](https://github.com/Hypfer/Valetudo/commit/a18633c97bb3897ecf60d6736b68ab9f9477a3ed)), closes [#848](https://github.com/Hypfer/Valetudo/issues/848)\r\n* **webserver:** Add X-Valetudo-Version header ([d494510](https://github.com/Hypfer/Valetudo/commit/d494510e0209f743e5f8bc8bef898a9e787bf9db))\r\n* Debug capability ([#813](https://github.com/Hypfer/Valetudo/issues/813)) ([4866475](https://github.com/Hypfer/Valetudo/commit/48664757035ebd0a6493c3de5433c02eb197800e))\r\n* Remove DNSHack since we're using musl now ([79194b6](https://github.com/Hypfer/Valetudo/commit/79194b690d27d4ba012536564ed35cad4d3df3b4))\r\n* SSE Endpoints for State and StateAttributes ([c90d426](https://github.com/Hypfer/Valetudo/commit/c90d426cb96c26b2326d64e2a7da27694ea08014))\r\n* **vendor.dreame:** 1C active zone & segments ([2281701](https://github.com/Hypfer/Valetudo/commit/22817015de62d93a9aaf46fb9fa4304d66603d6e))\r\n* **vendor.dreame:** DreameMapSegmentRenameCapability ([1470c53](https://github.com/Hypfer/Valetudo/commit/1470c539d3fb0425906b989f59adaad4b9efa739))\r\n* **vendor.dreame:** Implement/setup most capabilities of the 1C ([256b907](https://github.com/Hypfer/Valetudo/commit/256b9076a3727e3f85bfc8412e296e8009a42052))\r\n* **vendor.dreame:** Update 1C properties_changed handling ([83dddfe](https://github.com/Hypfer/Valetudo/commit/83dddfe402183456d50781435b154281d03acf1e))\r\n* **vendor.dreame:** Use currently configured water grade and fanspeed when starting a zone or segment cleanup ([200b13b](https://github.com/Hypfer/Valetudo/commit/200b13b5c8434375db486b93067278ddca490a42))\r\n* **vendor.roborock:** RoborockManualControlCapability ([59b9bd5](https://github.com/Hypfer/Valetudo/commit/59b9bd5e7a315c21f459613a9f09e8f50787ab7b))\r\n* **vendor.roborock:** RoborockMapSegmentRenameCapability ([4d6a1a4](https://github.com/Hypfer/Valetudo/commit/4d6a1a415c67c2d4e43f8220f7babe18e322e641))\r\n* **vendor.roborock:** RoborockWaterUsageControlCapability ([fdebd3c](https://github.com/Hypfer/Valetudo/commit/fdebd3c45df68797b353866dfd7a1e8684600a99))\r\n* **vendor.viomi:** Add MapResetCapability ([#785](https://github.com/Hypfer/Valetudo/issues/785)) ([696d76b](https://github.com/Hypfer/Valetudo/commit/696d76be682a905c809298c86032041243a2e1fe))\r\n* **vendor.viomi:** Add ViomiMapSegmentationCapability ([#762](https://github.com/Hypfer/Valetudo/issues/762)) ([1a9eef4](https://github.com/Hypfer/Valetudo/commit/1a9eef40b34fe991ed26989033daafdd8ace856d))\r\n* **vendor.viomi:** Add ViomiMapSegmentRenamenCapability ([0123f24](https://github.com/Hypfer/Valetudo/commit/0123f245bf6b7cedabaebf61da15f1959727c9e8))\r\n* **vendor.viomi:** Manual control capability ([#740](https://github.com/Hypfer/Valetudo/issues/740)) ([a5324e8](https://github.com/Hypfer/Valetudo/commit/a5324e8ece40709be7168730ef77978c3f971d94))\r\n* **vendor.viomi:** ViomiMapSegmentEditCapability ([#766](https://github.com/Hypfer/Valetudo/issues/766)) ([a210b0e](https://github.com/Hypfer/Valetudo/commit/a210b0edcadc29e7ab82e29258b2594fc622c53c))\r\n* no-mop zones ([f011023](https://github.com/Hypfer/Valetudo/commit/f0110231fe84f9ae7d7ed219bcece1bf387f2088))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Add name to ValetudoMapSegment ([e9da2cf](https://github.com/Hypfer/Valetudo/commit/e9da2cf5ea2cc408365fc96fb34430fcf73585d4))\r\n* **core:** Lowmem enhancements ([5787afa](https://github.com/Hypfer/Valetudo/commit/5787afa34d281e709dbe7e5f81af33e5623154e0))\r\n* **core:** Segment IDs should be strings ([97c832e](https://github.com/Hypfer/Valetudo/commit/97c832ea527665459ad9e3eb2c8f562f70a08478))\r\n* **miio:** Improve error message on missing keys in device.conf ([7ed177a](https://github.com/Hypfer/Valetudo/commit/7ed177a85ac50ec23a913c5265511e9adf839f8a))\r\n* **mqtt:** Await close event before considering MQTT closed ([1afa717](https://github.com/Hypfer/Valetudo/commit/1afa717d6e4815ba773200523324a8e835cc382d))\r\n* **mqtt:** Do not disconnect on cfg reload if not connected ([5c74342](https://github.com/Hypfer/Valetudo/commit/5c74342f94774333b42398c9a4373015bf9bbc4d))\r\n* **mqtt:** Handle nested reconfiguration ([#841](https://github.com/Hypfer/Valetudo/issues/841)) ([c0ff5ce](https://github.com/Hypfer/Valetudo/commit/c0ff5ce03fdcdf282f56adfabf3362bae5de38c6))\r\n* **mqtt:** Make BasicCtl actually home when HOME is sent ([8272dd5](https://github.com/Hypfer/Valetudo/commit/8272dd59e0fcbfd75ad75c0b992b56469cab2c53))\r\n* **mqtt:** Map zone presets to zones ([#839](https://github.com/Hypfer/Valetudo/issues/839)) ([8ac882f](https://github.com/Hypfer/Valetudo/commit/8ac882f75e3b4c67bc2a9192f28074e4609aaa58))\r\n* **mqtt:** Remove test leftovers from consumable monitoring ([#831](https://github.com/Hypfer/Valetudo/issues/831)) ([ec289a0](https://github.com/Hypfer/Valetudo/commit/ec289a08de38f4e24bfab61f2467cee9d99e2cba))\r\n* **ui:** instead of hiding settings based on capabilities at page load, unhide at page load ([#774](https://github.com/Hypfer/Valetudo/issues/774)) ([e5f0f4f](https://github.com/Hypfer/Valetudo/commit/e5f0f4fe2494ab7faf6825f54bfd38b8217d40e1))\r\n* **vendor.roborock:** do not send empty layers ([#809](https://github.com/Hypfer/Valetudo/issues/809)) ([a2e1c21](https://github.com/Hypfer/Valetudo/commit/a2e1c21bcc3dbf12a83fdaea84701b98d9387c17))\r\n* **vendor.roborock:** Don't store null to this.state.map on map parse failure ([ae4bf24](https://github.com/Hypfer/Valetudo/commit/ae4bf248d6c3848abae0a6ebc039aa2f0efc6bbc))\r\n* **vendor.roborock:** Fix segment rename ([0bed81a](https://github.com/Hypfer/Valetudo/commit/0bed81ab4f0ddccdad044ce805dda3af8736eb96))\r\n* **vendor.roborock:** Fix V1 capabilities ([6cdcc1e](https://github.com/Hypfer/Valetudo/commit/6cdcc1eb00a414d5f450c83f27f0267c082e7099))\r\n* **vendor.roborock:** Renaming map segments always requires the full list of names ([559d1ad](https://github.com/Hypfer/Valetudo/commit/559d1ada913e04258217134f3c7aa148d7eb7e21))\r\n* **vendor.roborock:** Roborock expects a number as the segmentId ([1e6db81](https://github.com/Hypfer/Valetudo/commit/1e6db81e71d43bf2060dec7ff90173a4cdc6e150))\r\n* **vendor.viomi:** Don't store paths with zero points ([77e7128](https://github.com/Hypfer/Valetudo/commit/77e712813191bc427306c80bf79f1b81f47202fd))\r\n* **vendor.viomi:** Fix \"Unknown water grade\" ([#784](https://github.com/Hypfer/Valetudo/issues/784)) ([04f2df4](https://github.com/Hypfer/Valetudo/commit/04f2df4c1cb546d195f3414c79557fcf0d320ae1))\r\n* **vendor.viomi:** Fix basic control functionality ([#782](https://github.com/Hypfer/Valetudo/issues/782)) ([a0fa7f4](https://github.com/Hypfer/Valetudo/commit/a0fa7f49f7f0779357c3ce61d354badd5bac07ed))\r\n* **vendor.viomi:** Fix last clean time ([#822](https://github.com/Hypfer/Valetudo/issues/822)) ([21b5876](https://github.com/Hypfer/Valetudo/commit/21b5876362939fc2e0d7ee7edbb4651411be39da))\r\n* **vendor.viomi:** Fix map issues (hopefully) ([#819](https://github.com/Hypfer/Valetudo/issues/819)) ([07a1c7a](https://github.com/Hypfer/Valetudo/commit/07a1c7ad78e3593b90e12ba0bb8286ed0c4f58e1))\r\n* **vendor.viomi:** Fix operation mode selection ([710758d](https://github.com/Hypfer/Valetudo/commit/710758d4840b06b3bff3bfb1e7dd521e48fa3d3b))\r\n* **vendor.viomi:** Fix water grade controlling fan speed instead ([#791](https://github.com/Hypfer/Valetudo/issues/791)) ([3f4d844](https://github.com/Hypfer/Valetudo/commit/3f4d844c2979527624623bb2ff67654a0961f768))\r\n* **vendor.viomi:** Increase timeout for set_timezone ([#806](https://github.com/Hypfer/Valetudo/issues/806)) ([a128a91](https://github.com/Hypfer/Valetudo/commit/a128a91499d94f0e75d17f87396571f6c889a7ac)), closes [#799](https://github.com/Hypfer/Valetudo/issues/799)\r\n* **vendor.viomi:** Raise default miIO timeout ([#817](https://github.com/Hypfer/Valetudo/issues/817)) ([5f6068d](https://github.com/Hypfer/Valetudo/commit/5f6068d7790a8f3f322f4825493608605ed80a63))\r\n* **vendor.viomi:** replace fanSpeeds with waterGrades ([#825](https://github.com/Hypfer/Valetudo/issues/825)) ([2b5d3e6](https://github.com/Hypfer/Valetudo/commit/2b5d3e69b9ea9a1ab966efc67652f55e638bf0f4))\r\n* **vendor.viomi:** Viomi segment edit fixes ([#821](https://github.com/Hypfer/Valetudo/issues/821)) ([5c8495c](https://github.com/Hypfer/Valetudo/commit/5c8495ce2eff247a667e87b2649c98ee13bddf28))\r\n* Improve state handling in MockConsumableMonitoringCapability ([1138c84](https://github.com/Hypfer/Valetudo/commit/1138c8466ca776960e0dc6030b1efe5f6e8343f2))\r\n* MapParsers should not return empty path map entities ([371ceea](https://github.com/Hypfer/Valetudo/commit/371ceea9e4e7b591b19b0dc3d4887feca3ab8692))\r\n* Typo in ConsumableStateAttribute ([7d64a1a](https://github.com/Hypfer/Valetudo/commit/7d64a1a90407d555cdd84eca6d1fae2ed828d5e2))\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/39835836", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/39835836/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/39835836/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.03.0", + "id": 39835836, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM5ODM1ODM2", + "tag_name": "2021.03.0", + "target_commitish": "master", + "name": "Valetudo 2021.03.0", + "draft": false, + "prerelease": false, + "created_at": "2021-03-15T17:48:10Z", + "published_at": "2021-03-15T18:15:42Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/33495678", + "id": 33495678, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMzNDk1Njc4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 36243394, + "download_count": 508, + "created_at": "2021-03-15T18:16:57Z", + "updated_at": "2021-03-15T18:16:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.03.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/33495673", + "id": 33495673, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMzNDk1Njcz", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32291086, + "download_count": 3226, + "created_at": "2021-03-15T18:16:54Z", + "updated_at": "2021-03-15T18:16:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.03.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/33495674", + "id": 33495674, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMzNDk1Njc0", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32291086, + "download_count": 83, + "created_at": "2021-03-15T18:16:56Z", + "updated_at": "2021-03-15T18:16:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.03.0/valetudo-armv7-lowmem" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.03.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.03.0", + "body": "
\r\n \"valetudo\"\r\n

2021.03.0

\r\n
\r\n\r\nThis release features segment editing, SVG path and icon rendering, and a cool new companion service.\r\n\r\n## Segment editing\r\n\r\nYep. It's finally here.
\r\nStarting with this release, you can split and merge your Segments, which you might also refer to as Rooms.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201031-a565e480-85c2-11eb-8650-ec0b46d9b348.png)\r\n\r\n\r\nIf this was the only thing holding you back from switching back to Valetudo: Welcome back.\r\n\r\n## SVG Path + Icons\r\n\r\nThe map rendering was reworked. It's still a canvas but everything that isn't pixel-based is now drawn as an SVG, which results in greatly improved visual fidelity.\r\nSee for yourself:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201075-b31b6a00-85c2-11eb-894e-877a136a84e6.png)\r\n\r\n\r\nFurthermore, this might also improve performance. In any case, I'm quite happy with how good zooming in looks now.\r\n\r\n## Valeronoi\r\n\r\n@ccoors built a companion service which connects to Valetudo and generates a Wifi signal strength heatmap.
\r\nYou should definitely check that out. It's great!\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201122-be6e9580-85c2-11eb-9d7c-3dcdcf7cd8f3.png)\r\n\r\n\r\nIts repo can be found here: [https://github.com/ccoors/Valeronoi](https://github.com/ccoors/Valeronoi)\r\n\r\nI'm looking forward to seeing more companion services appear in the near future.\r\n\r\n## More Valetudo Builds\r\n\r\nStarting with this release, there's more than one Valetudo binary available for download in the releases section.
\r\nThe regular `valetudo` binary has been renamed to `valetudo-armv7` so just take that one if you're upgrading.\r\n\r\nThere's also a `valetudo-armv7-lowmem` with a slightly decreased heap size. I haven't testet that very much yet so feel free to do that\r\nespecially if your robot only has 256mb or less of ram available.\r\n\r\nAnd finally there's now a `valetudo-aarch64` binary to support robots with that cpu architecture.\r\n\r\nWhile doing that, I've also upgraded the Valetudo nodejs base binaries to `v14.16.0` which should include performance, stability and security improvements.\r\n\r\n## Misc\r\n\r\n### VoicePacks\r\n\r\n@depau added a way to install new VoicePacks. There's no UI support for that and the request required might vary from vendor to vendor.
\r\nUsually, it should be sufficient to provide an URL to the VoicePack + its hash and it should install fine.\r\n\r\n\r\n### MockRobot\r\n\r\n@alexkn added a `MockRobot` to make development easier and enable you to contribute to Valetudo even if you don't have a robot around.\r\n\r\n### ID Button\r\n\r\nFurthermore, I've added an ID button to the Zone and Location Preset map edit view, which shows you the ID of the preset you're editing so that you can\r\nuse it via MQTT.\r\nIt's pretty much a hack but that's better than nothing ¯\\_(ツ)_/¯\r\n\r\n### Git Commit UI Info\r\n\r\nThe info section of the UI will now also contain your currently running git commit id, which should make debugging a bit easier in certain situations.\r\n\r\n### Docs\r\n\r\nThe Docs at [valetudo.cloud](https://valetudo.cloud) have been improved and now feature an autogenerated overview of all supported robots\r\nplus a page that explains all available capabilities.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Log and display git commit id ([2d94408](https://github.com/Hypfer/Valetudo/commit/2d9440832a0f0c5efa83e5a8d065907e1d9b89b2))\r\n* **MockRobot:** add BatteryStateAttribute ([584bfcb](https://github.com/Hypfer/Valetudo/commit/584bfcb1ba7e782d0697c36d4a3fd467451c9d6c))\r\n* **MockRobot:** add ModelName ([db643c6](https://github.com/Hypfer/Valetudo/commit/db643c687f9fb1d43a4a29b41ffe18af93542c78))\r\n* **MockRobot:** add returning state to BasicControlCapability ([721cd78](https://github.com/Hypfer/Valetudo/commit/721cd78b053ac72fdcbe01df83e7a741f0204a2b))\r\n* **MockRobot:** introduce MockRobot ([96c4bae](https://github.com/Hypfer/Valetudo/commit/96c4bae2750971d121e3165b9aff3cc6f76398ca))\r\n* **MockRobot:** MockLocateCapability ([#752](https://github.com/Hypfer/Valetudo/issues/752)) ([5c41d49](https://github.com/Hypfer/Valetudo/commit/5c41d499b2478b09007a1af1a395f3a946dcb2ea))\r\n* **ui:** Add info button which shows the id of a zone or location preset ([ea7cce4](https://github.com/Hypfer/Valetudo/commit/ea7cce4a27c54412a6818e4b969d294d0190493c))\r\n* **ui:** Draw path as SVG ([48e5d54](https://github.com/Hypfer/Valetudo/commit/48e5d54417fb0e11cb92ea82930ce81580f70743))\r\n* **ui:** Nice rounded paths ([59aaee3](https://github.com/Hypfer/Valetudo/commit/59aaee3bf9d2cdfd3823ef0f91566d17b388af1d))\r\n* **ui:** Render icons as SVGs ([12f2907](https://github.com/Hypfer/Valetudo/commit/12f290741bb16c05530294a934f8167069288675))\r\n* **ui:** Segment editing ([e306569](https://github.com/Hypfer/Valetudo/commit/e306569d2daaa6f8ab7cfe75d3cd4a99b37faa8b))\r\n* **vendor.dreame:** DreameVoicePackManagementCapability ([f9d6ab1](https://github.com/Hypfer/Valetudo/commit/f9d6ab13ad8939b5fbdb09372b2f8b3fc3ac5187))\r\n* **vendor.dreame:** Fully implemented segment joining + splitting ([82e4fe3](https://github.com/Hypfer/Valetudo/commit/82e4fe3609b706c7a38efd47086604d5e92c1f36))\r\n* **vendor.roborock:** Add support for the S4 Max ([#699](https://github.com/Hypfer/Valetudo/issues/699)) ([f7eb451](https://github.com/Hypfer/Valetudo/commit/f7eb45105751827d371661e78b44b5e2d8c190d6))\r\n* **vendor.roborock:** RoborockVoicePackManagementCapability ([d81befc](https://github.com/Hypfer/Valetudo/commit/d81befc121116864faad129a06327325bf3b8dd4))\r\n* **vendor.viomi:** Ensure timezone is UTC ([#732](https://github.com/Hypfer/Valetudo/issues/732)) ([bafa158](https://github.com/Hypfer/Valetudo/commit/bafa158814c3185cffbbaa9c9529227883f13071)), closes [#728](https://github.com/Hypfer/Valetudo/issues/728)\r\n* **vendor.viomi:** initial implementation of ViomiZoneCleaningCapability class ([#675](https://github.com/Hypfer/Valetudo/issues/675)) ([f760137](https://github.com/Hypfer/Valetudo/commit/f7601370353659ce8a35e6c2a942c48d4f614226))\r\n* **vendor.viomi:** Speaker control capabilities ([#738](https://github.com/Hypfer/Valetudo/issues/738)) ([630d2ab](https://github.com/Hypfer/Valetudo/commit/630d2ab4f7c52c5c26d306e2b4e34d518123e64d))\r\n* **vendor.viomi:** ViomiCarpetModeControlCapability ([#739](https://github.com/Hypfer/Valetudo/issues/739)) ([fe31438](https://github.com/Hypfer/Valetudo/commit/fe3143854ff94de1b11d5c86720b97dbeff44058))\r\n* **webserver:** Fully implemented MapSegmentationCapabilityRouter ([eda7dcd](https://github.com/Hypfer/Valetudo/commit/eda7dcd071ac6d5438fbd1124c5b78704a8dc2ed))\r\n* Add os.freemem() to debug memoryStats ([5c7dfc3](https://github.com/Hypfer/Valetudo/commit/5c7dfc37392467602acea038407a12ccb39244e3))\r\n* Add voice pack managemenet capability ([#725](https://github.com/Hypfer/Valetudo/issues/725)) ([c953e2b](https://github.com/Hypfer/Valetudo/commit/c953e2b558b7bce5eace00655c3fb2f3ad30b0d6))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Fix map canvas size ([3c05e2d](https://github.com/Hypfer/Valetudo/commit/3c05e2d9917e222a777a9d86207712d3b798dbec))\r\n* Fix default map ([25eac7c](https://github.com/Hypfer/Valetudo/commit/25eac7c57eb6b761ac6124fe6278cc628aad24a0))\r\n* **dnshack:** Don't try resolving ip addresses ([b8c456d](https://github.com/Hypfer/Valetudo/commit/b8c456d20cfe27946390aa528a7c99ab0a02801d))\r\n* **logger:** Use the windows equivalent of /dev/null on windows machines ([fa8f909](https://github.com/Hypfer/Valetudo/commit/fa8f9097496111d4664600553538729e105d8858))\r\n* **miio:** Bind dummycloud after setting event listeners ([#741](https://github.com/Hypfer/Valetudo/issues/741)) ([2aba77e](https://github.com/Hypfer/Valetudo/commit/2aba77e1330690bb7b422e29a79951c06d62e671))\r\n* **miio:** Discard handshake packets with older stamps to avoid endless loops with 100% cpu ([e274cf1](https://github.com/Hypfer/Valetudo/commit/e274cf145b635e2cd421657da29e53e54c8e521a))\r\n* **miio:** Fix broken development token refresh ([9217f70](https://github.com/Hypfer/Valetudo/commit/9217f70702eec6fe5ba0b2e41382eaaf42482d08))\r\n* **miio:** Fix Valetudo crashing due to missing onMessage function ([4512fe0](https://github.com/Hypfer/Valetudo/commit/4512fe08a3c9bbb46aa734a625261fa8418ba6e1))\r\n* **miio:** Various fixes related to Valetudo crashing in some situations ([a62d7e3](https://github.com/Hypfer/Valetudo/commit/a62d7e35745180260d4a8a28d0b40332e7cf1f66))\r\n* **mqtt:** Log on command-less custom command json ([3fa8232](https://github.com/Hypfer/Valetudo/commit/3fa823212fe97cb62704f04c560bce365a5dfd23))\r\n* **ui:** Decouple svg path generation from rendering to eliminate flicker ([9ebee25](https://github.com/Hypfer/Valetudo/commit/9ebee2515df021ddffac52ae1ed537430e9239f1))\r\n* **ui:** do not cache API responses ([#698](https://github.com/Hypfer/Valetudo/issues/698)) ([6e3b462](https://github.com/Hypfer/Valetudo/commit/6e3b462a36db49819718d47d58cb708728477360))\r\n* **ui:** Fix copy-paste error ([4479777](https://github.com/Hypfer/Valetudo/commit/4479777743df99ce4f042f5f641ee6a22e09f292))\r\n* **ui:** Fix initial map offset ([#711](https://github.com/Hypfer/Valetudo/issues/711)) ([a408edc](https://github.com/Hypfer/Valetudo/commit/a408edce5139f4aa2d767d52da0bb527eec8160f))\r\n* **ui:** Fix log UI only working once ([#718](https://github.com/Hypfer/Valetudo/issues/718)) ([2d02570](https://github.com/Hypfer/Valetudo/commit/2d02570f0c85c078941e67020e5e02a89fa62894))\r\n* **ui:** Fix new zone placement ([036752a](https://github.com/Hypfer/Valetudo/commit/036752a58ae73fd7180d4c46ef0424d38b52dc48))\r\n* **ui:** Only show presets if the robot is capable of having those ([d996beb](https://github.com/Hypfer/Valetudo/commit/d996beb4291146e71c90971dc3654926ed72f698))\r\n* **ui:** Reduce path render resolution ([aa64016](https://github.com/Hypfer/Valetudo/commit/aa64016c29151499cad8f7fef11d8826e7cd58ad))\r\n* **ui:** Reduce path render solution and render charger + robot as locations ([1c4e4f3](https://github.com/Hypfer/Valetudo/commit/1c4e4f3374251d64f3c79689747050c469a02ad7))\r\n* **ui:** Remove old paths if they vanish from the map data ([eef055e](https://github.com/Hypfer/Valetudo/commit/eef055ed42b208deb1caaf0d2fe1b16cd48ca046))\r\n* **ui:** Various scaling-related issues ([fb92c16](https://github.com/Hypfer/Valetudo/commit/fb92c162cff7f6f42099781596cd82e9afeeca4d))\r\n* **vendor.dreame:** Maps are always persistent ([3630fa3](https://github.com/Hypfer/Valetudo/commit/3630fa36d3137516245b738ee0102721fb4f217c))\r\n* **vendor.roborock:** Fix map not being available on a fresh boot for another 60s ([f4c4c1a](https://github.com/Hypfer/Valetudo/commit/f4c4c1a0784b4930bd6913cd9da6f092e1f0aa03))\r\n* **vendor.roborock:** Fix S4 detection logic ([#729](https://github.com/Hypfer/Valetudo/issues/729)) ([75974a5](https://github.com/Hypfer/Valetudo/commit/75974a5be0735035193118594f0ee3362d3e2a43))\r\n* **vendor.roborock:** RoborockS4 actually needs the MultiMapPersistentMapControlCapability ([6279831](https://github.com/Hypfer/Valetudo/commit/6279831f16c60a8115c9a2849e1c1258d75e2477))\r\n* **vendor.viomi:** Use marketing model name for viomi.v8 ([#742](https://github.com/Hypfer/Valetudo/issues/742)) ([7987168](https://github.com/Hypfer/Valetudo/commit/79871685bec0b4afb89d6b8e41f13d5db4dd8042))\r\n* **vendor.viomi:** Wait a few seconds after cloud connected before fixing TZ ([#736](https://github.com/Hypfer/Valetudo/issues/736)) ([f9bfb00](https://github.com/Hypfer/Valetudo/commit/f9bfb001c68f20f9438ad7703f4bbb3dd9e84626))\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/38135830", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/38135830/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/38135830/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.02.0", + "id": 38135830, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM4MTM1ODMw", + "tag_name": "2021.02.0", + "target_commitish": "master", + "name": "Valetudo 2021.02.0", + "draft": false, + "prerelease": false, + "created_at": "2021-02-16T21:17:31Z", + "published_at": "2021-02-16T22:37:28Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/32171459", + "id": 32171459, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMyMTcxNDU5", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32961247, + "download_count": 1241, + "created_at": "2021-02-16T22:38:04Z", + "updated_at": "2021-02-16T22:38:05Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.02.0/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.02.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.02.0", + "body": "
\r\n \"valetudo\"\r\n

2021.02.0

\r\n
\r\n\r\nThis release features Home Assistant MQTT Autoconfig for the Map Data, an NTP Client and more.\r\n\r\n## Map Autodiscovery\r\n\r\nThe Valetudo Map Data is now optionally (on by default) provided as embedded and compressed text of a PNG file.
\r\nThis is not only easy due to the nature of the PNG file format but also 100% according to specs.\r\nWe're actually publishing a completely valid PNG to MQTT containing the full Map as a JSON.\r\n\r\nThis enables Valetudo to do Home Assistant Autoconfiguration for the Map as well since camera entities aren't persistent to the HA database and therefore no user interaction regarding the exclusion of the map entity from the recorder is needed.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/108130382-de886300-70af-11eb-9dca-146b677cad18.png)\r\n\r\n\r\nI'm quite happy with this approach because there's no added CPU load to Valetudo since we're just sandwiching the deflated Map JSON between other PNG chunks.\r\nFurthermore, providing the raw map data instead of an image enables better interactions with the map such as\r\n- better zooming\r\n- custom colors\r\n- custom icons\r\n- mouseover things\r\n- click-to-select things\r\n\r\netc.\r\n\r\n\r\nThe [lovelace-valetudo-map-card](https://github.com/TheLastProject/lovelace-valetudo-map-card) is required to extract and render\r\nthe map data from the camera image.\r\n\r\nIf you were already using the Valetudo Map in Home Assistant, you will need to revise your setup.
\r\nNo worries though. It is much easier now :)\r\n\r\n## NTP Client\r\n\r\nDuring \"normal\" cloud operation, miio-based robots receive the time via the miio protocol. This of course resulted in\r\nthe robots syncing their time to their time, which doesn't make much sense and may even interfere with some features.\r\n\r\nAlso, not all robot firmwares contain a build of `ntpd` and cross-compiling can be hard.\r\n\r\nTherefore, there's now a simple NTP Client integrated into Valetudo, which by default fetches the time from `pool.ntp.org` on startup\r\nand every 8 hours after a successful sync.\r\n\r\nIt can be disabled via the configuration file and doesn't do anything if Valetudo isn't running in `embedded`-mode.\r\n\r\nOf course, you can also change the ntp server to a different one in the configuration file if you happen to own a\r\nstratum-0 cesium atomic clock or even a fritzbox with an integrated ntp server.\r\n\r\n## UI-Accessible Logs\r\n\r\nThanks to @ccoors, you will now find the contents of your Valetudo logfile under Settings > Info in the Web UI.\r\nNo need for SSH anymore.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/108130399-e516da80-70af-11eb-8b15-57649eac37af.png)\r\n\r\n\r\nIt is also possible to temporarily increase the Loglevel there until the next reboot.\r\n\r\n\r\nIf you're looking for stuff like the firmware version or your local token, the log viewer is the right place for you.\r\n\r\n## Misc\r\n\r\n@bensweet86 ported even more capabilities over to the new capabilities system. Starting with this release, Valetudo is now\r\nable to both control the volume and the carpet mode setting again.\r\n\r\nFurthermore, he also fixed a long outstanding bug regarding pinch to zoom on iOS devices.\r\n\r\n\r\n\r\nDreame support has been improved as well.\r\nPublic root for those is still TBA.\r\n\r\n\r\n\r\nThere were also quite a few changes regarding the cloud redirection in this release.\r\nPlease make sure to follow the official upgrade instructions so that you don't run into any issues.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Log config and logfile location to logfile ([0171a8d](https://github.com/Hypfer/Valetudo/commit/0171a8d1ba12c96045124d0e1f5b1b215655c314))\r\n* Add Valetudo log to UI ([#690](https://github.com/Hypfer/Valetudo/issues/690)) ([89320f4](https://github.com/Hypfer/Valetudo/commit/89320f45c4b7e49d8246f9b2508bdacd4c549efb))\r\n* Log the firmware version if embedded ([4bd09c8](https://github.com/Hypfer/Valetudo/commit/4bd09c8b8ad0d2f411630430a88dacd3e6230063))\r\n* **core:** Change the interface of the SpeakerVolumeControlCapability and add the SpeakerTestCapability ([56b0637](https://github.com/Hypfer/Valetudo/commit/56b06378a8c183d488eb503056bee39ff8872486))\r\n* **mqtt:** Home Assistant Autodiscovery for Maps by embedding the map data in a png ([83d1d13](https://github.com/Hypfer/Valetudo/commit/83d1d13bc47bb7a16f1a9ed8937ce616a0f2b5ec))\r\n* **vendor.dreame:** Consumable monitoring ([e986687](https://github.com/Hypfer/Valetudo/commit/e986687f649e0f3c061653aac9d362b74bde5065))\r\n* **vendor.dreame:** D9 error codes ([669f192](https://github.com/Hypfer/Valetudo/commit/669f19273eb9e849b578508adaa7e37f99d79fed))\r\n* **vendor.dreame:** Improve handling of RISM maps ([186abd3](https://github.com/Hypfer/Valetudo/commit/186abd34852d62b3ab418216a500bfbb72423b85))\r\n* **vendor.dreame:** Minor improvements for D9 Firmware 1072 ([ef949be](https://github.com/Hypfer/Valetudo/commit/ef949be485ba97bd8c65066ff5c3f427fbf35f6e))\r\n* **vendor.dreame:** Virtual Restrictions ([3f1f494](https://github.com/Hypfer/Valetudo/commit/3f1f4940c582534f6fb5d18442e21e1183498378))\r\n* **vendor.dreame:** Volume Control + Volume Test ([1509be3](https://github.com/Hypfer/Valetudo/commit/1509be361552f76148c4f38b3d7ec1da3c400735))\r\n* **vendor.roborock:** Roborock/Capability Carpet Mode ([#661](https://github.com/Hypfer/Valetudo/issues/661)) ([54ca606](https://github.com/Hypfer/Valetudo/commit/54ca6068dbe8f09cf8105fd11c50b9107c2b739f)), closes [#656](https://github.com/Hypfer/Valetudo/issues/656)\r\n* **vendor.roborock:** Volume Control + Volume Test ([4a47939](https://github.com/Hypfer/Valetudo/commit/4a47939ebea220e19ed9da3b4427c53da429e700))\r\n* NTPClient ([8b54c7d](https://github.com/Hypfer/Valetudo/commit/8b54c7d0066d7b4b306aaf1b096ce1027651998c))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **logger:** Default loglevel should be info ([3e23678](https://github.com/Hypfer/Valetudo/commit/3e2367875b364d4ca63ea98548fbc3c2e841ee15))\r\n* **logger:** Do not log twice if logfile is the same as stdout redirection ([#691](https://github.com/Hypfer/Valetudo/issues/691)) ([2bd4c82](https://github.com/Hypfer/Valetudo/commit/2bd4c820a5f46e77383d9d489867494d4696fc09))\r\n* **logger:** Logger should log 🪵 ([58515d9](https://github.com/Hypfer/Valetudo/commit/58515d97559b 8bd2ab2ac12ddfbadd4fad576d9f))\r\n* **miio:** Don't get confused by the system clock doing weird things ([5e6d8df](https://github.com/Hypfer/Valetudo/commit/5e6d8df224d845da5218d0836f20f7eb4027d39c))\r\n* **miio:** http_dns: Block ott.io.mi.com requests ([#671](https://github.com/Hypfer/Valetudo/issues/671)) ([852683b](https://github.com/Hypfer/Valetudo/commit/852683b25815a05235b580a313a2464714786f4c))\r\n* **miio:** One failing message should not kill the process 20 minutes later ([e5fd0a5](https://github.com/Hypfer/Valetudo/commit/e5fd0a54ab1e040c2c82c60a4c5c310f4709fc6e))\r\n* **miio:** Set ServerSocket to disconnected on timeouts to prevent valetudo breaking on wifi issues ([e14935d](https://github.com/Hypfer/Valetudo/commit/e14935dfa9ef06a15871b3bd7683c55956b4db52))\r\n* **mqtt:** Fix home assistant vacuum.send_command functionality ([97ac35e](https://github.com/Hypfer/Valetudo/commit/97ac35e7e34fc7da3dbc3e4774f1f9ecbe7afe64))\r\n* **ntpClient:** Intercept dns lookup calls for our ntp server as well ([c7095a7](https://github.com/Hypfer/Valetudo/commit/c7095a7a340cfad293385a37f6f9dcf04a477e61))\r\n* **ui:** Fix for pinch zoom bug in IOS / Safari ([#683](https://github.com/Hypfer/Valetudo/issues/683)) ([3c0a644](https://github.com/Hypfer/Valetudo/commit/3c0a644da402f1e392fe7f088ba7fd3da4dafc69))\r\n* **ui:** SSE Map updates should use a relative path ([54bc2b7](https://github.com/Hypfer/Valetudo/commit/54bc2b71d99c0d2c411e807a2365107eb7949b36))\r\n* **vendor.dreame:** Don't store empty MapLayers ([1230c08](https://github.com/Hypfer/Valetudo/commit/1230c082b50f9264a27219f4f8e211de54541caf))\r\n* **vendor.dreame:** Proper angles ([43aa8c6](https://github.com/Hypfer/Valetudo/commit/43aa8c60ded5ed1bf52fdfce406c6bb0933f1cc1))\r\n* **vendor.dreame:** Properly parse map with correct rotation, offsets etc ([5e037c2](https://github.com/Hypfer/Valetudo/commit/5e037c22dfb27be9f3cdfa50b6d18911998da913))\r\n* **vendor.roborock:** calculation of max elements for virtual restrictions ([#681](https://github.com/Hypfer/Valetudo/issues/681)) ([2e4421b](https://github.com/Hypfer/Valetudo/commit/2e4421b0e27adc563a40ab9c8d2e3b804128ce57))\r\n* **vendor.viomi:** consumables command fix for viaomi.v8 ([#677](https://github.com/Hypfer/Valetudo/issues/677)) ([bef609e](https://github.com/Hypfer/Valetudo/commit/bef609efbe772632b270c67efb660ef2b8f06c0f))\r\n* **vendor.viomi:** Resolve [#672](https://github.com/Hypfer/Valetudo/issues/672): Fix viomi fan speed control ([#673](https://github.com/Hypfer/Valetudo/issues/673)) ([be0efca](https://github.com/Hypfer/Valetudo/commit/be0efca344ea7fe53858b9a28c7097ad4c99dea1))\r\n* **vendor.viomi:** Various fixes for 2020.01.1 ([a38987a](https://github.com/Hypfer/Valetudo/commit/a38987affba30f37e0cd09a67627a51adf695679)), closes [#641](https://github.com/Hypfer/Valetudo/issues/641)\r\n* **webserver:** Fix handleHttpDnsRequest scope ([8226e4a](https://github.com/Hypfer/Valetudo/commit/8226e4ad3e840539f13a358d817ec1b9217a2085))\r\n* **webserver:** Rate-limit logfile access ([8fd53a5](https://github.com/Hypfer/Valetudo/commit/8fd53a5237bc847708b7ee631da4afbd8fe7b950))\r\n\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/36957518", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/36957518/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/36957518/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.01.1", + "id": 36957518, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM2OTU3NTE4", + "tag_name": "2021.01.1", + "target_commitish": "master", + "name": "Valetudo 2021.01.1", + "draft": false, + "prerelease": false, + "created_at": "2021-01-27T08:58:03Z", + "published_at": "2021-01-27T09:10:00Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/31246605", + "id": 31246605, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMxMjQ2NjA1", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33170157, + "download_count": 894, + "created_at": "2021-01-27T09:10:38Z", + "updated_at": "2021-01-27T09:10:36Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.01.1/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.01.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.01.1", + "body": "
\r\n \"valetudo\"\r\n

2021.01.1

\r\n
\r\n\r\n**Be advised: This release will break (almost) everything that you're currently using.**
\r\n\r\nConfig format, HTTP API and MQTT have changed significantly in this release.
\r\nYou will need to recreate your Zone presets as well as your Home Assistant Robot entity.\r\n\r\nMake sure to disable any Timers you might've configured before upgrading, since there's no way to delete/configure them in this release anymore!\r\n\r\nAlso, note that this release comes with fewer features than the previous, because not everything has been ported to the new structures yet.\r\n\r\n## Core rewrite (Capabilities)\r\n\r\nTo support a growing number of Vacuum Robots with different feature sets made by different Vendors, the core infrastructure\r\nof Valetudo was completely rewritten.\r\n\r\nNow, instead of having robots that inherit from other robots, there are so-called `capabilities` as an abstraction of features.
\r\nThere's always a generic base class for each feature (e.g. `GoToLocationCapability`) which is extended by multiple vendor-specific\r\nimplementations (e.g. `RoborockGoToLocationCapability`, `ViomiGoToLocationCapability` etc).\r\n\r\nThis approach completely encapsulates vendor-specific implementation details and makes them invisible for e.g. the webinterface or other\r\nusers of the HTTP API which has also been rewritten.\r\n\r\nOverall, I'm quite happy with how it turned out. Time will tell whether this abstraction was generic enough to deal with\r\nall possible vendor-specific differences.\r\n\r\n## New HTTP REST Interface\r\n\r\nAs mentioned, the REST interface was rewritten and is now an official way of communicating with Valetudo.
\r\n\r\nAll endpoints are dynamically generated according to which capabilities are available for the robot implementation Valetudo is using.\r\nFor example basic controls such as \"start\", \"stop\" or \"home\" are done via a PUT request to `/api/v2/robot/capabilities/BasicControlCapability`.\r\n\r\nTo find out more about all possible endpoints for your Valetudo instance, a meta-endpoint has also been added.
\r\nAt `/api/v2/` you will get JSON containing all endpoints as well as their accepted methods.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436664-9061f200-4c1e-11eb-8541-5c8ed6ccc4c2.png)\r\n\r\n## New MQTT Interface\r\n\r\nThe MQTT interface was also rewritten to support different subsets of capabilities.\r\nInstead of having a single topic, which contains all the information available, data is now split up onto different topics\r\nbased on capabilities.\r\n\r\nThis also means that you will have multiple entities for your robot in Home Assistant:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436641-44af4880-4c1e-11eb-8a9f-019d17398359.png)\r\n\r\nFurthermore, Wi-Fi information is now also available over MQTT so in theory, one could build a microservice which subscribes\r\nto both map and Wi-Fi data updates and build a Wi-Fi heatmap of their home by mapping the measurements to the position in the map.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436651-5f81bd00-4c1e-11eb-99f9-9efe6875d5b3.png)\r\n\r\n\r\nNote that the default identifier changed from `rockrobo` to `robot`, since Valetudo is not just dealing with Roborock anymore.
\r\nTherefore when reconfiguring this release, you may want to change that back to the old value if your setup relies on it.\r\n\r\n## New Config Schema + Location\r\n\r\nTo support different robots with different folder structures (some of them being read-only), the configuration location\r\nhad to be made configurable, which is a chicken/egg problem, because the information on where to find the configuration\r\nwould be configured within the configuration.\r\n\r\nTo solve this, Valetudo is now using the environment variable `VALETUDO_CONFIG_PATH` and defaults to `os.tmpdir()` if it isn't set.\r\n\r\nDue to the fact that the configuration schema also changed significantly, **you will need to reconfigure Valetudo on upgrade**.\r\n\r\nYou will also need to update your means of running valetudo to include this ENV variable since otherwise your configuration will vanish on each reboot.\r\nThis can be done either by building a new firmware image or copying the changes required from these commits\r\n\r\n[Roborock](https://github.com/zvldz/vacuum/commit/5981577aa8e8f75c4fbea7045bf4484066881b55)\r\n\r\n[Viomi](https://github.com/Hypfer/Valetudo/commit/923f941e76e2e41be7a714e47f3a08428d09cfd4)\r\n\r\n## Dreame Support\r\n\r\nWith the launch of the Dreame D9, there's now a promising successor to the Roborock S5 regarding both pricing and ease of installation.\r\nThis release already contains support for basic controls, Map Rendering, Segment Cleaning and Zoned Cleaning.\r\n\r\nRooting instructions will follow soon-ish. :)\r\n\r\nIt looks like this code should also be adaptable to the F9. We'll see about that if/when I get my hands on one\r\n\r\n## Misc\r\n\r\n**Viomi note:** If you're upgrading on a Viomi, make sure to change the cloud IP used for redirection to `203.0.113.1` which is now hardcoded.
\r\nThe docs have been updated to reflect that.\r\n\r\nValetudo is now using the CalVer versioning scheme, because it better fits the constantly changing scope of the project.\r\n\r\nI'd like to especially thank @depau for his port of the Viomi robot to the new infrastructure using only the half-finished capabilities branch\r\nand no documentation whatsoever as a reference.\r\n\r\nFurthermore, thanks to @bensweet86 for porting more capabilities to the new framework.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Publish ValetudoGoToLocations & ValetudoZonePresets ([76a9c52](https://github.com/Hypfer/Valetudo/commit/76a9c5234dfbcce864d70d1d6db781af86d6a98b))\r\n* **ui:** Bring back consumable monitoring & resetting for now ([fde2ffd](https://github.com/Hypfer/Valetudo/commit/fde2ffd8d3c7b5869f221870774a2032232d6c54))\r\n* **vacuum.roborock:** Add support for no-mopping zones on S5 Max and S6 ([#630](https://github.com/Hypfer/Valetudo/issues/630)) ([61902ed](https://github.com/Hypfer/Valetudo/commit/61902edd8b185d116dd27a02827866e3defd01b1)\r\n)\r\n* **vacuum.roborock:** Re-added support for S6 Pure ([0226cd5](https://github.com/Hypfer/Valetudo/commit/0226cd56a6f245e307944dab623d28bda8fcc288))\r\n* **vacuum.viomi:** Virtual Walls & No-Go Areas ([96462ac](https://github.com/Hypfer/Valetudo/commit/96462ac752b025a3385e31d4ea0cfbea268b207c))\r\n* **vendor.dreame:** Basic Dreame D9 support ([7c5e231](https://github.com/Hypfer/Valetudo/commit/7c5e231326bc8ca454e303b31c647f14f6773cd8))\r\n* **vendor.dreame:** Re-add support for 1c as well as more dreame capabilities ([cd76abe](https://github.com/Hypfer/Valetudo/commit/cd76abe952cda43fd260eda2b217aff677b98d29))\r\n* **vendor.roborock:** Do not disturb capability ([#659](https://github.com/Hypfer/Valetudo/issues/659)) ([4b3ed97](https://github.com/Hypfer/Valetudo/commit/4b3ed974d064b788f470c9439a719a3f3ed95cb9))\r\n* **vendor.roborock:** Use the lo alias approach for more robots ([58a2618](https://github.com/Hypfer/Valetudo/commit/58a26186f34e5331fe5373e231e97f403e15e147))\r\n* Add properties to capability ([7114fcc](https://github.com/Hypfer/Valetudo/commit/7114fccb502305e3176b350973f1ba0825e98845))\r\n* Configure authorized_keys location via ENV variable ([d06520d](https://github.com/Hypfer/Valetudo/commit/d06520da114f45778527e54446eed70df38e66ba))\r\n* Viomi capabilities port ([8486f04](https://github.com/Hypfer/Valetudo/commit/8486f04fdd9176af6e4e7be684bb3eecebaa39e1))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Only report a new token from handshake if it is actually new ([b373703](https://github.com/Hypfer/Valetudo/commit/b37370349514fea07fc8b27b89637a44e6df668e))\r\n* Fix map layer dimensions calculation for empty layers ([216c347](https://github.com/Hypfer/Valetudo/commit/216c3474e7680b90859b47e2ea5308ced8d1c7ff))\r\n* **ui:** fix [#565](https://github.com/Hypfer/Valetudo/issues/565) ui not working with safari and basic auth ([252c22d](https://github.com/Hypfer/Valetudo/commit/252c22dc9d457aa69bdbee0829930aa156430a9b))\r\n* **vendor.dreame:** Fix map parser tests ([a81b8e9](https://github.com/Hypfer/Valetudo/commit/a81b8e94a6db0c39b0881bbb29122ca62f5a2247))\r\n* **vendor.roborock:** Use lo alias cloud redirection approach for S6 & S5Max with miio_client 3.5.8 ([71bc1f8](https://github.com/Hypfer/Valetudo/commit/71bc1f8b91b47503a45b3771c3217655cc30a7fd))\r\n* Set VALETUDO_CONFIG_PATH variable for Upstart ([#648](https://github.com/Hypfer/Valetudo/issues/648)) ([f75b70d](https://github.com/Hypfer/Valetudo/commit/f75b70d7f7d3092f724555090db99aea4bccf6d9))\r\n* **mqtt:** missing / in set_fan_speed topic ([26ceb95](https://github.com/Hypfer/Valetudo/commit/26ceb95a71154396d14adfb01b6fb1d198fa3490))\r\n* **vacuum.roborock:** Fix broken cloud connectivity on newer roborock vacuums caused by missing region ([28483ab](https://github.com/Hypfer/Valetudo/commit/28483abd4431cf0d38953aefeb3995e9d45ea2b8))\r\n* **vacuum.viomi:** Added model names for viomi.v8 ([20d86c3](https://github.com/Hypfer/Valetudo/commit/20d86c3c005ac78d36bab29a78946e17f163f2c3))\r\n* **vacuum.viomi:** Fix fan speed state parsing ([3ca7450](https://github.com/Hypfer/Valetudo/commit/3ca745054d3c159023edb632e198126e89d7494a))\r\n* **vacuum.viomi:** Fix invalid property access ([6da2822](https://github.com/Hypfer/Valetudo/commit/6da282201172b3fb5efa1969aac6192d5ead5842))\r\n* **vacuum.viomi:** Segments + Docs ([#600](https://github.com/Hypfer/Valetudo/issues/600)) ([89a5485](https://github.com/Hypfer/Valetudo/commit/89a5485f17e7ac68e7b8d97ae9a8381d2f0a7767))\r\n* Improved dnshack to catch all problematic dns.lookup requests ([8609612](https://github.com/Hypfer/Valetudo/commit/8609612e03bc756194982d35b4389d27557842ac))\r\n\r\n" + } +] diff --git a/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/regular_overview_response.json b/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/regular_overview_response.json new file mode 100644 index 00000000..b44f4b7b --- /dev/null +++ b/backend/test/lib/updater/lib/update_provider/res/GithubValetudoUpdateProvider/regular_overview_response.json @@ -0,0 +1,6638 @@ +[ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/73473495/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.08.0", + "id": 73473495, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4EYR3X", + "tag_name": "2022.08.0", + "target_commitish": "master", + "name": "Valetudo 2022.08.0", + "draft": false, + "prerelease": false, + "created_at": "2022-08-02T17:45:28Z", + "published_at": "2022-08-02T19:20:05Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482161", + "id": 73482161, + "node_id": "RA_kwDOCGKICM4EYT-x", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31579356, + "download_count": 309, + "created_at": "2022-08-02T19:26:01Z", + "updated_at": "2022-08-02T19:26:02Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482970", + "id": 73482970, + "node_id": "RA_kwDOCGKICM4EYULa", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14444544, + "download_count": 1, + "created_at": "2022-08-02T19:35:53Z", + "updated_at": "2022-08-02T19:35:54Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482158", + "id": 73482158, + "node_id": "RA_kwDOCGKICM4EYT-u", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27935884, + "download_count": 612, + "created_at": "2022-08-02T19:25:57Z", + "updated_at": "2022-08-02T19:25:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482159", + "id": 73482159, + "node_id": "RA_kwDOCGKICM4EYT-v", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27935884, + "download_count": 190, + "created_at": "2022-08-02T19:25:59Z", + "updated_at": "2022-08-02T19:26:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482963", + "id": 73482963, + "node_id": "RA_kwDOCGKICM4EYULT", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11321896, + "download_count": 2, + "created_at": "2022-08-02T19:35:51Z", + "updated_at": "2022-08-02T19:35:52Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482959", + "id": 73482959, + "node_id": "RA_kwDOCGKICM4EYULP", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11321728, + "download_count": 11, + "created_at": "2022-08-02T19:35:50Z", + "updated_at": "2022-08-02T19:35:51Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/73482979", + "id": 73482979, + "node_id": "RA_kwDOCGKICM4EYULj", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 926, + "created_at": "2022-08-02T19:35:55Z", + "updated_at": "2022-08-02T19:35:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.08.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.08.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.08.0", + "body": "
\r\n \"valetudo\"\r\n

2022.08.0

\r\n
\r\n\r\nNew firmwares for dreame robots and some bugfixes\r\n\r\n## New dreame firmwares\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454333-356ba835-4f69-4041-a720-7c2d97eb3209.png)\r\n\r\nIt took quite a lot of time and work, but now we're proud to announce that we've managed to get newer dreame firmwares\r\nto work rooted and with Valetudo. A big thank you to everyone who helped during the beta test!\r\n\r\n**Important**: That does **not** mean that these newer firmwares have become rootable.\r\nYou will need to have an already rooted robot to install these latest rooted firmwares.\r\n\r\nTo update, head over to the dustbuilder at [https://builder.dontvacuum.me/](https://builder.dontvacuum.me/) to build and install a new image.\r\nMake sure to update Valetudo **before** updating the firmware.\r\n\r\n## Other dreame news\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454516-57ef159d-d97e-458a-815d-97a60db689ba.png)\r\n\r\nStarting today, every firmware image built with the dustbuilder will contain a fix for the vanishing Valetudo issue,\r\nwhich occasionally left people with a rooted robot but no Valetudo.\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454599-cab62e88-6179-43da-b907-6ac7236c7d17.png)\r\n\r\nIf a user starts a new mapping pass, the fresh map should now appear instantly.\r\nFurthermore, issues with frozen maps either during cleanups or when editing segments were fixed as well.\r\n\r\n## Robot Coverage View\r\n\r\n[](https://user-images.githubusercontent.com/974410/182455081-879226c5-aa14-4160-bc2f-f9c0f2a2d3d3.png)\r\n\r\n\r\nThe UI has been extended with a view displaying a much thicker path.\r\nThis can be used to better see which areas of the map have been cleaned.\r\n\r\nWhether this view will stick around long-term is yet to be decided. It was pretty easy to implement though.\r\nFeel free to leave your feedback in the comments.\r\n\r\n\r\n## The usual\r\n\r\n[](https://user-images.githubusercontent.com/974410/182454845-cc693f37-a126-4978-b2f0-5c9f77a970d8.png)\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Misc\r\n\r\nThis changelog features artworks generated by DALL-E 2 because I thought it would be neat to have something to look at.\r\nUnfortunately, it doesn't like generating artworks featuring lidar-based vacuum robots (yet?)\r\n\r\nI hope they've nonetheless enhanced your changelog reading experience.\r\nFeel free to leave feedback on that as well.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n- **vendor.dreame**: Newer D9 Firmwares also have a sensor consumable [`17c0d27`](http://github.com/Hypfer/Valetudo/commit/17c0d27fb69b92b5a8028d6bab489e5b97fb4537)\r\n- **ui**: Trim whitespaces when renaming segments [`39d72f4`](http://github.com/Hypfer/Valetudo/commit/39d72f4e787108c75a1cb501995151fb19b4d8b1)\r\n- **ui**: Add robot coverage map [`a9661a0`](http://github.com/Hypfer/Valetudo/commit/a9661a02bcbe642c3e7de46be4015f9532e4ce49)\r\n- **vendor.dreame**: Add mop-only quirk for newer firmwares [`a33afe3`](http://github.com/Hypfer/Valetudo/commit/a33afe351c1b868919bc7b036e2e02a05b8e581c)\r\n- **vendor.dreame**: Add Mop Dock UV-C Toggle Quirk [`7ce4abe`](http://github.com/Hypfer/Valetudo/commit/7ce4abe7353567fd3db6a7a9cc1c767d68a9db93)\r\n\r\n### Fixes\r\n\r\n- **vendor.dreame**: Add support for more features of newer firmwares [`b74c281`](http://github.com/Hypfer/Valetudo/commit/b74c281e1727ca2a007d96915c6fceb3f386bd28)\r\n- **ui**: Add margin to apple touch icon (#1526) [`dc72ef0`](http://github.com/Hypfer/Valetudo/commit/dc72ef05319799020a504a3b20e0b7e6092984ee)\r\n- **vendor.dreame**: Ignore empty maps [`99aad7b`](http://github.com/Hypfer/Valetudo/commit/99aad7be8b20c9459e849dd6b9ce8df5171b9690)\r\n- **networkadvertisement**: Don't crash the process on ssdp multicast membership errors [`bfb96c0`](http://github.com/Hypfer/Valetudo/commit/bfb96c09aa2bc0ff9e151fb6cdab4ac5bbd58a36)\r\n- **miio**: Allow two simultaneous FDS uploads [`6e26374`](http://github.com/Hypfer/Valetudo/commit/6e26374c32e9fe33c93f4f91c189f917c5f884a5)\r\n- **vendor.dreame**: Switch to async map preprocessing to not block the event loop [`3b5743b`](http://github.com/Hypfer/Valetudo/commit/3b5743b41264c3d8d36d8cc0a75da30e90bb7338)\r\n- **miio**: Further improve fds upload timeout handling [`8c1ba9e`](http://github.com/Hypfer/Valetudo/commit/8c1ba9ea2fcc980bf726a4678902afd2577a0191)\r\n- **miio**: Gracefully handle connectivity issues when receiving fds uploads [`8aab94f`](http://github.com/Hypfer/Valetudo/commit/8aab94fa2ab01479997968904e9312fbc8111a83)\r\n- **vendor.dreame**: Ignore timezone update message [`5ecf7fa`](http://github.com/Hypfer/Valetudo/commit/5ecf7fa0842c498a2ad8abfd792a71b420ce34bf)\r\n- **ui**: Allow sending home basic control command while paused [`0dfb4ba`](http://github.com/Hypfer/Valetudo/commit/0dfb4ba59bd1334f994beea211ac17fdf5323f1f)\r\n- **vendor.dreame**: Fix maps for newer firmwares [`5f67103`](http://github.com/Hypfer/Valetudo/commit/5f6710348fd304046a201c2423490555e44d3b20)\r\n- **webserver**: Fix openapi schema for MapSegmentEditCapability [`f106735`](http://github.com/Hypfer/Valetudo/commit/f106735cbae0eed2ebfebaa6843c7da976c5127e)\r\n\r\n### Refactoring\r\n\r\n- **webserver**: Response cleanup [`839310a`](http://github.com/Hypfer/Valetudo/commit/839310ab0941941d68ea4ba0c1fbfc17b8924443)\r\n- **webserver**: Actually make use of the openapi schema validation [`6e2d2e1`](http://github.com/Hypfer/Valetudo/commit/6e2d2e1904040aa891dda5d35909654553e04eb7)\r\n- Introduce RobotFirmwareError and refactor CapabilityRouter for unified error logs [`1d2ad47`](http://github.com/Hypfer/Valetudo/commit/1d2ad47e9d49eac71f0621d2aa0444acf871acec)\r\n\r\n### Chores\r\n\r\n- **release**: 2022.08.0 [`214b5c0`](http://github.com/Hypfer/Valetudo/commit/214b5c0c11c0cf70fa56ff915fda05e064a18355)\r\n- Minor cleanup [`9356ba8`](http://github.com/Hypfer/Valetudo/commit/9356ba8e19825a1602cd842db9487389aa553ccf)\r\n- **vendor.dreame**: Fix tests [`15eee37`](http://github.com/Hypfer/Valetudo/commit/15eee3749e41fc77ddf62fbaf8fc348f8d872672)\r\n- **mqtt**: Minor cleanup [`4ae1d03`](http://github.com/Hypfer/Valetudo/commit/4ae1d0365d2b54f9d27c49caf5e38b915ff47e4c)\r\n- Minor misc cleanups [`7bf3c87`](http://github.com/Hypfer/Valetudo/commit/7bf3c87db34a8f27624fe735737a4ccd17fbf8bc)\r\n- Add eslintrc flavors [`b3843f8`](http://github.com/Hypfer/Valetudo/commit/b3843f8bd3c95346735d674f7df4543ff5f78b81)\r\n- Add close_threads github workflow [`e10313d`](http://github.com/Hypfer/Valetudo/commit/e10313dc75a0f7867d64c195fbd9ef69ca3b199b)\r\n- **ui**: Add missing rel=\"noopener\" tag to menu bar [`a7e6920`](http://github.com/Hypfer/Valetudo/commit/a7e6920c7924b5db43b9eb086a434fddaa276d75)\r\n- **build**: Bump to NodeJS v18.5.0 [`66712f9`](http://github.com/Hypfer/Valetudo/commit/66712f91dd3f16c24b0b22b334a37ecfeb983df9)\r\n- Update wording in VoicepackHelp.ts [`05a6b89`](http://github.com/Hypfer/Valetudo/commit/05a6b89848b5c1e9a04f4a822da58e03cd89b5f8)\r\n- Update issue template [`cebca05`](http://github.com/Hypfer/Valetudo/commit/cebca057ceb05d202f3f76211a2e63290f39b002)", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1537", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/73473495/reactions", + "total_count": 14, + "+1": 0, + "-1": 0, + "laugh": 1, + "hooray": 0, + "confused": 0, + "heart": 10, + "rocket": 3, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/69327065/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.06.0", + "id": 69327065, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4EIdjZ", + "tag_name": "2022.06.0", + "target_commitish": "master", + "name": "Valetudo 2022.06.0", + "draft": false, + "prerelease": false, + "created_at": "2022-06-13T18:02:35Z", + "published_at": "2022-06-13T18:16:34Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368217", + "id": 68368217, + "node_id": "RA_kwDOCGKICM4EEzdZ", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31454413, + "download_count": 726, + "created_at": "2022-06-13T18:22:05Z", + "updated_at": "2022-06-13T18:22:06Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368623", + "id": 68368623, + "node_id": "RA_kwDOCGKICM4EEzjv", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14405897, + "download_count": 5, + "created_at": "2022-06-13T18:29:48Z", + "updated_at": "2022-06-13T18:29:49Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368213", + "id": 68368213, + "node_id": "RA_kwDOCGKICM4EEzdV", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27827381, + "download_count": 1623, + "created_at": "2022-06-13T18:22:02Z", + "updated_at": "2022-06-13T18:22:03Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368215", + "id": 68368215, + "node_id": "RA_kwDOCGKICM4EEzdX", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27827381, + "download_count": 428, + "created_at": "2022-06-13T18:22:03Z", + "updated_at": "2022-06-13T18:22:04Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368622", + "id": 68368622, + "node_id": "RA_kwDOCGKICM4EEzju", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11299441, + "download_count": 13, + "created_at": "2022-06-13T18:29:47Z", + "updated_at": "2022-06-13T18:29:48Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368620", + "id": 68368620, + "node_id": "RA_kwDOCGKICM4EEzjs", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11299577, + "download_count": 10, + "created_at": "2022-06-13T18:29:46Z", + "updated_at": "2022-06-13T18:29:47Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/68368624", + "id": 68368624, + "node_id": "RA_kwDOCGKICM4EEzjw", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2170, + "created_at": "2022-06-13T18:29:50Z", + "updated_at": "2022-06-13T18:29:50Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.06.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.06.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.06.0", + "body": "
\r\n \"valetudo\"\r\n

2022.06.0

\r\n
\r\n\r\nAnother maintenance release featuring upgraded dependencies, refactoring and some bugfixes\r\n\r\n## Bonjour/mDNS fixes\r\n\r\nUsers can now discover multiple robots of the same model in their home network:\r\n\r\n[](https://user-images.githubusercontent.com/974410/173417472-ca0d279e-05f2-4980-9f1b-d46af2897882.png)\r\n\r\nApparently, the Bonjour service name needs to be unique or else _some_ bonjour implementations will deduplicate it.\r\nBecause of this, the companion app only displayed one robot even though there were multiple ones on the network.\r\n\r\n\r\n## Nightly build enhancements\r\n\r\nThe nightly update provider will now display a changelog of all changes since the last release.\r\n\r\n[](https://user-images.githubusercontent.com/974410/173417506-3f156a64-4130-48cc-ab21-6bdabf747707.png)\r\n\r\nYou can switch to the nightly update provider by changing the `updater.updateProvider.type` in your `valetudo_config.json` to `github_nightly`.\r\nPlease keep in mind that nightly builds might be unstable. They should only be used by people that know what they're doing and are willing to handle occasional breakage.\r\n\r\n## UI Improvements\r\n\r\nMultiple issues that caused the live map to stop refreshing have been fixed.\r\n\r\nChecking back on the Valetudo UI after having it in a background tab for a while during a cleanup will now display the latest map data.\r\nAlso, running Valetudo behind a flaky reverse proxy should not interfere with the SSE connection anymore.\r\n\r\n## Boring chores\r\n\r\nThis release features plenty of dependency upgrades, the migration to create-react-app 5 and more.\r\nIt also contains a lot of refactorings that should further improve the code quality.\r\n\r\nWhile all that doesn't offer any directly noticeable benefits to the user, it is worth noting nonetheless, as keeping the project well-maintained is vital to its longevity.\r\n\r\nThe exciting stuff will hopefully happen later this year :-)\r\n\r\n\r\nApart from code changes, I've been busy figuring out how to build statically linked recent versions of common tools that might be added to our robot firmware images. It's all done using dockerfiles to make it easy to understand, document and reproduce.\r\nInterestingly, information on the internet do to just that is rather sparse so this might also be useful to someone with a different embedded use-case.\r\n\r\nYou can find that stuff here: [https://github.com/Hypfer/valetudo-misc](https://github.com/Hypfer/valetudo-misc)\r\nIf you're missing a tool there please let me know\r\n\r\n## Other news\r\n\r\nAs mentioned in the previous release notes, we're currently still pretty busy figuring out how to root new robots and/or firmware versions.\r\nSince that worked well in the past, I shall continue mentioning it here.\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\nThe autogenerated changelog generation has been updated to be even better and less of a hassle to use.\r\nEnjoy\r\n\r\n### Breaking Changes\r\n\r\n- **timers**: Updating timers should be a PUT instead of a POST [`9c57f0c`](http://github.com/Hypfer/Valetudo/commit/9c57f0c6db069eae796b6fb68766ca2f5d16c907)\r\n\r\n### Features\r\n\r\n- **updater**: Add changelog to nightly update provider [`3a874db`](http://github.com/Hypfer/Valetudo/commit/3a874db088f445d03e71f08f9125ac5ce9cbc4d6)\r\n- **mqtt**: Deduplicate mqtt map data as well [`269aa30`](http://github.com/Hypfer/Valetudo/commit/269aa3004f3925e26afe66139109b201133afcfe)\r\n\r\n### Fixes\r\n\r\n- **networkadvertisement**: Bonjour service names need to be unique [`956487e`](http://github.com/Hypfer/Valetudo/commit/956487ee1f06e571371eb237aa87a86e50969356)\r\n- **ui**: Remove obsolete css statement [`6793c67`](http://github.com/Hypfer/Valetudo/commit/6793c67eb12bb4bf90a83adfb22c0dca01b741ef)\r\n- **ui**: Fix map SSE EventSource not reconnecting on error [`d84efd5`](http://github.com/Hypfer/Valetudo/commit/d84efd586122aff81cab8524517cc2c5a0b7b37b)\r\n- **ui**: fix circular chunk dependency [`271e53c`](http://github.com/Hypfer/Valetudo/commit/271e53c6fa6aa659f94e14e4fd10934901857b82)\r\n- **ui**: Fix map not properly redrawing on visibility state change [`bd77d2e`](http://github.com/Hypfer/Valetudo/commit/bd77d2e22adc33813fb4ab5e3897e6b58d5340e2)\r\n- **utils**: hash key instead of value (#1503) [`bae09ab`](http://github.com/Hypfer/Valetudo/commit/bae09ab9f1d09ca98cd54272aab96afac05e52cb)\r\n- **miio**: Fix ERR_HTTP_HEADERS_SENT exception (#1501) [`a47f3b9`](http://github.com/Hypfer/Valetudo/commit/a47f3b9c97c4abd3f8a5c9a61750312ffce05800)\r\n- **vendor.dreame**: The STYTJO6ZHM does not feature a watertank [`9b75974`](http://github.com/Hypfer/Valetudo/commit/9b7597420084cd579ce9990667d1118c8d5a27ed)\r\n- **vendor.roborock**: copy statusflag from previous state on state update (#1497) [`84de0ef`](http://github.com/Hypfer/Valetudo/commit/84de0ef9d869f5150c504fa13bcd49956c71bf4c)\r\n\r\n### Refactoring\r\n\r\n- **updater**: Move type constant to update providers [`5ca525e`](http://github.com/Hypfer/Valetudo/commit/5ca525ec8f6899f577cc21a616e0fbcf26b2c76e)\r\n- **vendor.roborock**: Improve logic legibility in ZoneCleaningCapability [`560a50e`](http://github.com/Hypfer/Valetudo/commit/560a50edfca23c6a80378f0bed9cc3c1a533d8bc)\r\n- **ui**: Port map color finder to typescript [`6c1b126`](http://github.com/Hypfer/Valetudo/commit/6c1b126138f4e8b751913eb4d4c411a22d7f492c)\r\n- **ui**: Make use of webpack 5 and convert the map layer render webworker to typescript [`d17b66d`](http://github.com/Hypfer/Valetudo/commit/d17b66d6be3381a9c14cf3dfe118f560bd5ed408)\r\n- **ui**: Port map touch handling to typescript [`9548012`](http://github.com/Hypfer/Valetudo/commit/95480129dbf4d72eb2e87a7a0ac1d9c18e429369)\r\n- **ui**: Do not monkey patch the 2d context of the map renderer [`212e4f5`](http://github.com/Hypfer/Valetudo/commit/212e4f541b14a9d5a55d4fe10d54a5c173fc2800)\r\n- **ui**: Remove unnecessary nullchecks in the map component [`96ba8cf`](http://github.com/Hypfer/Valetudo/commit/96ba8cf83f6a4d0c9235359b77414e0cbd70d658)\r\n- **vendor.dreame**: Improve mop dock settings handling [`412a65a`](http://github.com/Hypfer/Valetudo/commit/412a65ab4c5cf3c7ba061ea59d61c88c1d345e34)\r\n- **miio**: Unify previously duplicated map poll code [`356d144`](http://github.com/Hypfer/Valetudo/commit/356d144b9cd15840ccd32c2b2a0a21cb0fa011a8)\r\n\r\n### Chores\r\n\r\n- **release**: 2022.06.0 [`3504a4a`](http://github.com/Hypfer/Valetudo/commit/3504a4a6974afe4ff35d52ab1d676104a77ca86b)\r\n- Fix nightly changelog generation [`2c73de3`](http://github.com/Hypfer/Valetudo/commit/2c73de3cb7d4a564c4b3306e37a5bfa3f3755ff2)\r\n- Minor misc code cleanups [`3c3c561`](http://github.com/Hypfer/Valetudo/commit/3c3c5617dfac3b8a48f43e695c005d95593857ac)\r\n- More dependency changes [`0becd44`](http://github.com/Hypfer/Valetudo/commit/0becd4490b397539de3a8a6593e547cbc4fcba15)\r\n- Delete obsolete Events.js [`5176cce`](http://github.com/Hypfer/Valetudo/commit/5176cce43a9dff88d7acfc39038b3b4e7c303a86)\r\n- Bump dependencies [`8ae420c`](http://github.com/Hypfer/Valetudo/commit/8ae420c1576331dd26acfdf2d3e7a83ff05ebf06)\r\n- bump GitHub codeql action to v2 [`643dcc5`](http://github.com/Hypfer/Valetudo/commit/643dcc581c556797bc6b989dde25671e9ad55378)\r\n- **vendor.dreame**: Add documentation on the mop dock settings data format [`881f717`](http://github.com/Hypfer/Valetudo/commit/881f717ac37505c7f113b6c82f6754837e8a9d43)\r\n- typo fix [`41055d1`](http://github.com/Hypfer/Valetudo/commit/41055d1c9a4615fe9664487e66ec7e9a81773428)", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1516", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/69327065/reactions", + "total_count": 7, + "+1": 1, + "-1": 0, + "laugh": 0, + "hooray": 6, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/66310630/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.05.1", + "id": 66310630, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4D89Hm", + "tag_name": "2022.05.1", + "target_commitish": "master", + "name": "Valetudo 2022.05.1", + "draft": false, + "prerelease": false, + "created_at": "2022-05-08T09:21:48Z", + "published_at": "2022-05-08T09:27:12Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843029", + "id": 64843029, + "node_id": "RA_kwDOCGKICM4D3W0V", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31364500, + "download_count": 761, + "created_at": "2022-05-08T09:35:16Z", + "updated_at": "2022-05-08T09:35:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843691", + "id": 64843691, + "node_id": "RA_kwDOCGKICM4D3W-r", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14315984, + "download_count": 14, + "created_at": "2022-05-08T09:45:58Z", + "updated_at": "2022-05-08T09:46:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64842989", + "id": 64842989, + "node_id": "RA_kwDOCGKICM4D3Wzt", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27737468, + "download_count": 2016, + "created_at": "2022-05-08T09:35:12Z", + "updated_at": "2022-05-08T09:35:13Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843007", + "id": 64843007, + "node_id": "RA_kwDOCGKICM4D3Wz_", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 27737468, + "download_count": 461, + "created_at": "2022-05-08T09:35:14Z", + "updated_at": "2022-05-08T09:35:16Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843690", + "id": 64843690, + "node_id": "RA_kwDOCGKICM4D3W-q", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11209336, + "download_count": 12, + "created_at": "2022-05-08T09:45:57Z", + "updated_at": "2022-05-08T09:45:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843688", + "id": 64843688, + "node_id": "RA_kwDOCGKICM4D3W-o", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11209384, + "download_count": 18, + "created_at": "2022-05-08T09:45:55Z", + "updated_at": "2022-05-08T09:45:56Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64843692", + "id": 64843692, + "node_id": "RA_kwDOCGKICM4D3W-s", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2944, + "created_at": "2022-05-08T09:46:01Z", + "updated_at": "2022-05-08T09:46:01Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.05.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.05.1", + "body": "
\r\n \"valetudo\"\r\n

2022.05.1

\r\n
\r\n\r\nA small incremental release featuring a few UI/UX improvements\r\n\r\n## MQTT/REST Segment/Zone/GoTo improvements\r\n\r\nThis release adds an easy way of getting the payload to automate zoned cleanups, segment cleanups and go-to commands via MQTT or REST.\r\nSimply set up your zones/select your presets as you'd usually do but instead of just clicking the cleanup button, long-press it, and you will receive a dialog containing the copy-pastable payload for MQTT/REST. `ctrl + a` also works :)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/167289945-4b84df5c-8ebd-4dc4-a121-efc997454aab.png)\r\n\r\n\r\n## Client Map Structure Visibility\r\n\r\nThis release adds a shadow to zones drawn onto the map to improve visibility especially when using the light theme.\r\n\r\nBefore:\r\n![image](https://user-images.githubusercontent.com/974410/167289951-151daef5-bbcf-4fbd-b81c-5674ef12c74f.png)\r\n\r\nAfter:\r\n![image](https://user-images.githubusercontent.com/974410/167289957-d6422c64-7feb-4ab1-905f-cb76ffd38d16.png)\r\n\r\n\r\nFurthermore, NoGoAreas and VirtualWalls now are slightly less transparent to improve visibility on orange segments.\r\n\r\n## Map Crispness\r\n\r\nAt some point for some reason, the map renderer canvas lost the `image-rendering: crisp-edges` css property, which caused occasional blurry maps.\r\n\r\nThis has been fixed. We can now all again enjoy crisp edges :)\r\n\r\nUncrisp edges:\r\n![image](https://user-images.githubusercontent.com/974410/167289962-65a5ffc4-0b86-490a-959e-1f27f3570470.png)\r\n\r\nCrisp edges:\r\n![image](https://user-images.githubusercontent.com/974410/167289969-0d3d78cd-b71e-4dd9-8092-2608b43acee4.png)\r\n\r\n\r\n## Node V18\r\n\r\nThe base binaries have been upgraded to the latest NodeJS v18.1.0.\r\nThey're also now built with `-Os`, which decreased our binary size by a few percent.\r\n\r\n## Other news\r\n\r\nAs mentioned in the previous release notes, we're currently still pretty busy figuring out how to root new robots and/or firmware versions.\r\nSince that worked well the last time, I shall continue mentioning it here.\r\n\r\nIf you want to see Valetudo on more robots and/or like this release, you might want to consider donating if you haven't done so already:\r\n\r\n[https://github.com/sponsors/Hypfer](https://github.com/sponsors/Hypfer)\r\n\r\n[https://builder.dontvacuum.me/donations.txt](https://builder.dontvacuum.me/donations.txt)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Get payload of segment/zone cleanup via long-press ([52731bf](https://github.com/Hypfer/Valetudo/commit/52731bf3b218b58f8469342bcdfdb08f9725ccb1))\r\n* **vendor.roborock:** Add support for the M1S ([f234925](https://github.com/Hypfer/Valetudo/commit/f234925aef5415784c9358f39435aa7e01d9ef79))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Limit the maximum fdsUpload filesize ([c1de1c5](https://github.com/Hypfer/Valetudo/commit/c1de1c59084cfe9dfcd9f5659c4be92b153bbfc2))\r\n* **miio:** process _async.stat, _otc.ncstat and _otc.ncinfo messages ([#1488](https://github.com/Hypfer/Valetudo/issues/1488)) ([7cf1fe9](https://github.com/Hypfer/Valetudo/commit/7cf1fe98b7546fa97ad06ce75e04952e436fcbb2))\r\n* **ui:** Add shadow to some client structures for better visibility ([d4e7f83](https://github.com/Hypfer/Valetudo/commit/d4e7f83521b4324bbf9263822d33f7603765d088))\r\n* **ui:** Fix map crispness ([e55a5dc](https://github.com/Hypfer/Valetudo/commit/e55a5dc646e12b3cda2510ff3e792d2d88aa0ee3))\r\n* **ui:** Improve visibility of red virtual restrictions on orange segments ([797143a](https://github.com/Hypfer/Valetudo/commit/797143a1b330c2bcbc44deb4dead656eb381cc56))\r\n* Work around Node v18 breaking os.networkInterfaces ([226dae1](https://github.com/Hypfer/Valetudo/commit/226dae13b9ebd49797d6b0e2f0dacd9ac394cd53))\r\n* **vendor.roborock:** copy metadata from previous state on state update ([#1489](https://github.com/Hypfer/Valetudo/issues/1489)) ([6ecc76b](https://github.com/Hypfer/Valetudo/commit/6ecc76b843e5a582936702f4a5c0fea04a9a4d07))\r\n* **vendor.roborock:** Ignore event.fan_power_reduced ([c56e7a2](https://github.com/Hypfer/Valetudo/commit/c56e7a26df92e628906f78e7b2ee28b243dcd70b))\r\n* **vendor.roborock:** Multiple fixes for Mijia 1S ([#1485](https://github.com/Hypfer/Valetudo/issues/1485)) ([c66798d](https://github.com/Hypfer/Valetudo/commit/c66798db6e19a8a2dac494bf10f444795015872f))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1491", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/66310630/reactions", + "total_count": 8, + "+1": 8, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/65762409/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.05.0", + "id": 65762409, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4D63Rp", + "tag_name": "2022.05.0", + "target_commitish": "master", + "name": "Valetudo 2022.05.0", + "draft": false, + "prerelease": false, + "created_at": "2022-05-01T15:55:06Z", + "published_at": "2022-05-01T16:02:49Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64183833", + "id": 64183833, + "node_id": "RA_kwDOCGKICM4D014Z", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33106996, + "download_count": 609, + "created_at": "2022-05-01T16:09:21Z", + "updated_at": "2022-05-01T16:09:22Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184367", + "id": 64184367, + "node_id": "RA_kwDOCGKICM4D02Av", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12787852, + "download_count": 2, + "created_at": "2022-05-01T16:17:51Z", + "updated_at": "2022-05-01T16:17:51Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64183827", + "id": 64183827, + "node_id": "RA_kwDOCGKICM4D014T", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30948968, + "download_count": 1780, + "created_at": "2022-05-01T16:09:18Z", + "updated_at": "2022-05-01T16:09:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64183830", + "id": 64183830, + "node_id": "RA_kwDOCGKICM4D014W", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30948968, + "download_count": 350, + "created_at": "2022-05-01T16:09:19Z", + "updated_at": "2022-05-01T16:09:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184364", + "id": 64184364, + "node_id": "RA_kwDOCGKICM4D02As", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12203608, + "download_count": 6, + "created_at": "2022-05-01T16:17:50Z", + "updated_at": "2022-05-01T16:17:50Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184363", + "id": 64184363, + "node_id": "RA_kwDOCGKICM4D02Ar", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12203536, + "download_count": 11, + "created_at": "2022-05-01T16:17:49Z", + "updated_at": "2022-05-01T16:17:49Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/64184370", + "id": 64184370, + "node_id": "RA_kwDOCGKICM4D02Ay", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2848, + "created_at": "2022-05-01T16:17:52Z", + "updated_at": "2022-05-01T16:17:53Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.05.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.05.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.05.0", + "body": "
\r\n \"valetudo\"\r\n

2022.05.0

\r\n
\r\n\r\nSpring-cleaning 2022: Usability improvements, bugfixes and the removal of zone/goto presets + the old UI\r\n\r\n## Zone/GoTo Preset removal\r\n\r\nValetudo 2022.05.0 removes the Zone Preset/GoTo Location feature that has been deprecated since more than six months now.\r\n\r\nAs a replacement for this feature, the MQTT interface now accepts coordinates instead of preset IDs.\r\nThus, users can just change the place where they store their coordinates from the Valetudo config file to e.g., the Home Assistant config files.\r\n\r\nPlease head over to the MQTT docs to find out how to use it.\r\nIt's the same payload that is used by the REST API. No surprises there.\r\n\r\n
\r\nIf you're unhappy and/or like to know more about why this change was done, feel free to click on this spoiler\r\n\r\n
\r\nFeature removal is delicate topic, since there always will be at least one person that is very upset and unhappy with whatever change was done to a project. See also: XKCD 1172.\r\n\r\nStill, it has to be done once in a while to keep a clean codebase and focus on what is most important.\r\nWithout these kinds of cleanups, projects eventually grow to a point when they start suffocating under their own weight.\r\n\r\nIf you've ever worked with larger legacy enterprise codebases, you should understand the issue.\r\nThey tend to be torn apart by\r\n\r\n- legacy features/behaviour having to stay like they are for existing customers/long-running support contracts\r\n\r\nand\r\n\r\n- management, sales and the market in general demanding newer features that no one could ever have predicted previously\r\n\r\nSee also this anecdote on Oracle 12.2 found on Hackernews.\r\n\r\n\r\nAs avid listeners of my ramblings have likely been aware, I've been very unhappy with that preset feature for more much more than just half a year now.\r\nIt was always a very fragile feature to begin with, given that Valetudo itself would store these coordinates without knowing anything about the underlying map.\r\nThe robot might've decided to rotate the map, leading to them pointing to a completely different location without Valetudo being able to catch that.\r\n\r\nAt the time when it was added, it was the best we had, given that map segments simply weren't invented just yet.\r\nWe didn't even have persistent maps, which is very strange to look back to.\r\n\r\nThat however was almost four years ago. Since then, the market changed a lot as you can tell.\r\nBasically every robot now supports not only persistent maps but also the map segmentation, which is handled by the firmware and not Valetudo.\r\nThose are objectively superior to some rectangles that are drawn onto the map, which is why it was finally time to remove this hack.\r\n\r\n\r\nI know that this may be bad news for V1 owners who do not have segments support and also don't want to use something like Home Assistant.\r\nHowever, I'd like to point out that there is nothing forcing anyone to upgrade to a newer Valetudo version.\r\nThere is no automatic update check that periodically annoys the user.\r\nThere is no cloud that will change its API.\r\nIt just works and will continue to do so.\r\n\r\nTherefore, for those who want to continue using zone presets and goto locations, it is recommended to stick with Valetudo 2022.03.1.\r\nIt also shouldn't be too hard to backport changes to that version. I however simply can't provide that kind of support.\r\nI hope that you will all understand that.\r\n
\r\n
\r\n\r\n## Removal of the old UI\r\n\r\nWith the presets gone, we can finally remove the old frontend entirely, which reduced the binary size by around 1MiB.\r\nWhile this doesn't sound like much given that it's \"only\" 3%, it's important to note that currently, 24MiB of the armv7 build consist of the bundled nodejs runtime. This means that with this update, the size of Valetudo itself shrunk by **15%**!\r\n\r\n## UI improvements\r\n\r\nThe menu opening thingy of the mobile UI now always stays at the bottom of the screen to improve user experience when using long phones.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154092-65a71eec-1af7-4268-83c2-50c827065824.png)\r\n\r\n\r\nThe live map now renders virtual restrictions with more opacity and less bright colors as they were pretty obstructive previously.\r\nThe edit map remains unchanged.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154102-0d9f9700-59a2-42af-a488-6cb953b97add.png)\r\n\r\n\r\nThe log viewer now uses the jetbrains mono font.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/166154108-8bb2a3ec-4dbe-4ae2-9af9-00eb2a5921f4.png)\r\n\r\n\r\n## Attachments\r\n\r\nYour robot will now only report and display attachments whose state it is able to track. No more always attached dustbins confusing users.\r\n\r\n\r\n## Companion apps\r\n\r\nOver the last weeks, a few new companion applications were built:\r\n\r\n1. valetudo-tray-companion\r\n\r\n A tray icon that allows easy access to Valetudo instances on your network. It's mostly handy when dealing with 4+ robots\r\n\r\n2. valetudo-helper-miioota\r\n\r\n A standalone all-in-one firmware update flasher tool for roborock v1 and s5. The docs have been updated to suggest using it\r\n\r\n3. valetudo-helper-httpbridge\r\n\r\n A standalone self-contained utility webserver currently most useful for rooting dreames. The docs have been updated to suggest using it\r\n\r\n4. valetudo-helper-miio\r\n\r\n A standalone self-contained utility to send raw miio commands. Useful for development of valetudo or other software interacting via miio\r\n\r\n5. valetudo-helper-voicepacks\r\n\r\n A WIP tool to help with Voicepacks\r\n\r\nThese should make installation and usage of Valetudo even easier than before.\r\n\r\n## Other news\r\n\r\nWe're currently pretty busy figuring out how to root new robots and/or firmware versions.\r\nThese endeavors are partly funded by your donations. Thank you!\r\n\r\nIf you want to see Valetudo on more robots, you might want to consider donating:\r\n\r\nhttps://github.com/sponsors/Hypfer\r\n\r\nhttps://builder.dontvacuum.me/donations.txt\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Provide attachment state attributes autodiscovery for home assistant ([b7b6344](https://github.com/Hypfer/Valetudo/commit/b7b6344281183fa022d83f4635894af3beae7a97))\r\n* **ui:** Improve mobile controls for long screens ([f7f3f0d](https://github.com/Hypfer/Valetudo/commit/f7f3f0db6e155aff25344d293e9822b589e43d9a))\r\n* **ui:** Reduce live map obstructions caused by virtual restrictions ([ddec0b3](https://github.com/Hypfer/Valetudo/commit/ddec0b34b215cc9b81d5b2e86926c8b73e446ca5))\r\n* **ui:** Use JetBrains Mono ([5a7045c](https://github.com/Hypfer/Valetudo/commit/5a7045c1a03c97bf892738d40999824fb2ae6a81))\r\n* **vendor.dreame:** 1C PendingMapChangeHandling ([1b2f3bf](https://github.com/Hypfer/Valetudo/commit/1b2f3bf0055587faadaaa2bd841449e887de0a49))\r\n* **vendor.dreame:** Add support for the STYTJO6ZHM ([519c5b4](https://github.com/Hypfer/Valetudo/commit/519c5b4a437868e9d7de2e20448bbc6d1f1cfceb))\r\n* **vendor.viomi:** Fetch and display firmware version ([7f08743](https://github.com/Hypfer/Valetudo/commit/7f087438e08e66a5663ae6f52868249cb5348659))\r\n* **vendor.viomi:** Raise zone count limit to 10 ([8130e24](https://github.com/Hypfer/Valetudo/commit/8130e24dc31be40d76a4f417ca8ceb7f40751de5))\r\n* Provide list of attachments supported by the model of robot ([fe65df3](https://github.com/Hypfer/Valetudo/commit/fe65df3696d2a0af608db27c54f32b49bcb88635))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** MqttController default state should be disconnected ([137e630](https://github.com/Hypfer/Valetudo/commit/137e630147eadb06673d269920f29abed07c7dcf))\r\n* **networkadvertisement:** Disabling the Network advertisement multiple times in a row should not cause any issues ([789608f](https://github.com/Hypfer/Valetudo/commit/789608f8cc384692ad05c66223480a555843c729))\r\n* **ui:** Allow closing of ValetudoEvents even if there are a lot ([ec599b2](https://github.com/Hypfer/Valetudo/commit/ec599b2f7ed2b328f0ab801ac029902eec54e7fe))\r\n* **ui:** Fix auto empty dock control loading state ([7ec1e5d](https://github.com/Hypfer/Valetudo/commit/7ec1e5d62cd53c8829cb70bc46a0402b5a3306d6))\r\n* **ui:** Handle timers with invalid actions ([b467443](https://github.com/Hypfer/Valetudo/commit/b4674433c40a576cc4c51e97a7a6ea9aedfcf29a))\r\n* **ui:** use correct relative paths to allow hosting in a subdirectory ([6129ec5](https://github.com/Hypfer/Valetudo/commit/6129ec5f4282edf07de1a5173fcf3a88067fe151))\r\n* **vendor.dreame:** Fix 1C powersave state mapping ([fdb51e7](https://github.com/Hypfer/Valetudo/commit/fdb51e7945fd908dec498b8b0b90a272227daf47))\r\n* **vendor.roborock:** Don't update state for attachments that we don't have ([f27bbfd](https://github.com/Hypfer/Valetudo/commit/f27bbfd97f71fb5f4b0c6dea4c3be9cf8774d22d))\r\n* **vendor.roborock:** Fix manual control for roborock v1 ([abccee4](https://github.com/Hypfer/Valetudo/commit/abccee47dbdd8972431cad3873029c502a093928))\r\n* **vendor.roborock:** Fix obnoxious \"no error\" error event ([f3b4a54](https://github.com/Hypfer/Valetudo/commit/f3b4a548dffc3aa96c2ecdf37c063b73847b0d5e))\r\n* **vendor.roborock:** Remove confusing attachments that never get updated ([e4274d3](https://github.com/Hypfer/Valetudo/commit/e4274d3da8ba64d0bc31f9d7683a4f3fbf91c79a))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1483", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/65762409/reactions", + "total_count": 7, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 7, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/60521593/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.03.1", + "id": 60521593, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4Dm3x5", + "tag_name": "2022.03.1", + "target_commitish": "master", + "name": "Valetudo 2022.03.1", + "draft": false, + "prerelease": false, + "created_at": "2022-02-25T23:40:23Z", + "published_at": "2022-02-25T23:43:51Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57948762", + "id": 57948762, + "node_id": "RA_kwDOCGKICM4DdDpa", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34122267, + "download_count": 794, + "created_at": "2022-02-25T23:51:05Z", + "updated_at": "2022-02-25T23:51:06Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949356", + "id": 57949356, + "node_id": "RA_kwDOCGKICM4DdDys", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13803443, + "download_count": 13, + "created_at": "2022-02-26T00:00:11Z", + "updated_at": "2022-02-26T00:00:12Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57948736", + "id": 57948736, + "node_id": "RA_kwDOCGKICM4DdDpA", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964239, + "download_count": 2172, + "created_at": "2022-02-25T23:51:02Z", + "updated_at": "2022-02-25T23:51:03Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57948749", + "id": 57948749, + "node_id": "RA_kwDOCGKICM4DdDpN", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964239, + "download_count": 569, + "created_at": "2022-02-25T23:51:04Z", + "updated_at": "2022-02-25T23:51:05Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949355", + "id": 57949355, + "node_id": "RA_kwDOCGKICM4DdDyr", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13218871, + "download_count": 20, + "created_at": "2022-02-26T00:00:10Z", + "updated_at": "2022-02-26T00:00:11Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949354", + "id": 57949354, + "node_id": "RA_kwDOCGKICM4DdDyq", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13218639, + "download_count": 23, + "created_at": "2022-02-26T00:00:09Z", + "updated_at": "2022-02-26T00:00:10Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57949359", + "id": 57949359, + "node_id": "RA_kwDOCGKICM4DdDyv", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2894, + "created_at": "2022-02-26T00:00:13Z", + "updated_at": "2022-02-26T00:00:14Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.03.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.03.1", + "body": "
\r\n \"valetudo\"\r\n

2022.03.1

\r\n
\r\n\r\nOrdered segment cleanups via the UI, MQTT deduplication and a lot of internal refactoring\r\n\r\n## Ordered segment cleanup\r\n\r\nThe UI now tracks the order in which segments were selected, meaning that if your robots' firmware supports it, they will be cleaned in the order you've specified.\r\n\r\nIf supported, the order will be displayed as a roman numeral above the segment label triangle.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770812-180860d1-44f4-4531-a746-eff91e97e0cf.png)\r\n\r\n## MQTT\r\n\r\nThe MQTT connectivity feature now reports a state to the UI. Furthermore, it also collects some statistics.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770843-92204a3d-23e6-469f-b053-704ff2ec2347.png)\r\n\r\n\r\nBy watching those stats, you will notice that this release also causes less traffic, as most outgoing messages are deduplicated.\r\n\r\nInitially, I didn't want to do that as the solution proposed was to just store every payload in memory and then compare on each mqtt publish.\r\nThat would work, however it comes with a hefty ram overhead as you now have to constantly keep 300+ somewhat long string payloads in memory.\r\nWith each character taking up 2 byte, this approach isn't feasible with the ram budget we have (32 Mbyte or less).\r\n\r\nTo reduce the amount of ram required, we could use a hash function such as md5, however that would still be too much.\r\nAs they'd be saved as hex strings, that would mean 32 characters each with each character taking up 2 bytes, resulting in each pair of topic and payload using 128 byte or more.\r\n\r\nThus, instead we're now using 32-bit CRC32. With object keys being strings, I'd think that these pairs should use around 20 byte each.\r\nThe downside of CRC32 is that the risk of collisions is much higher. However, I highly doubt that that could actually happen in this application.\r\n\r\nTo save CPU time, which is also quite limited on our robots, the (in comparison) huge map data is not being deduplicated.\r\n\r\n## Misc\r\n\r\n- The system information page will now display the current robot firmware version if available\r\n- The UI will now prevent the user from configuring invalid MQTT topic names (containing spaces, # or +)\r\n- The UPnP/SSDP lib was dropped in favour of our own implementation, which should fix some unhandledRejections caused by the lib\r\n- The log viewer now doesn't scroll back down automatically if the user scrolled up\r\n- TotalStatistics should now also work for the Roborock S7\r\n- It is now possible to disable network advertisement (bonjour/mDNS and UPnP/SSDP) via the UI if you so desire\r\n- The nonsensical always-attached dustbin attachment has been removed\r\n- It is now possible to have 50% more virtual restrictions on roborock robots\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Allow setting the order of segments cleaned if support by the robot ([9eec3b6](https://github.com/Hypfer/Valetudo/commit/9eec3b6200dee08d4094fdac47e9200e9585961e))\r\n* NetworkAdvertisementManager UI control ([bd5fa9c](https://github.com/Hypfer/Valetudo/commit/bd5fa9c1d156cab2b499952acb7664ebee554623)), closes [#1168](https://github.com/Hypfer/Valetudo/issues/1168)\r\n* **core:** Remove outdated VirtualWallCapability and RestrictedZoneCapability ([5e24783](https://github.com/Hypfer/Valetudo/commit/5e247835e3772ed57d445c8be82849bcedba6db6))\r\n* **core:** Remove SensorCalibrationCapability ([5b081a7](https://github.com/Hypfer/Valetudo/commit/5b081a78a4dbccf54ad2fb547daaa622ce8c8c7f))\r\n* **mqtt:** Collect runtime metrics and provide them via REST ([dcc1db4](https://github.com/Hypfer/Valetudo/commit/dcc1db4f86265be47242d2f836ba3ffac521ed67))\r\n* **ui:** Display firmware version if available ([e78e9b4](https://github.com/Hypfer/Valetudo/commit/e78e9b4e1dc84b7ce2b60adb36ec35675664ded0))\r\n* **ui:** Display MQTTClient status ([c54ebc8](https://github.com/Hypfer/Valetudo/commit/c54ebc8c1eae6c14a35247e7e55ce2bb2e0d0ccd))\r\n* **vendor.roborock:** Support S7 total statistics ([d1926a9](https://github.com/Hypfer/Valetudo/commit/d1926a9b33dfdbdf53f8b3b53ef0ee695c53c867))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Fix free memory reporting on kernels >= 3.14 ([dceea16](https://github.com/Hypfer/Valetudo/commit/dceea16f5a3fbc7b69ea938dd3c112e12a874019))\r\n* **miio:** Don't throw plain objects on error responses ([e84fe8c](https://github.com/Hypfer/Valetudo/commit/e84fe8c066b3ad3b7576405ee7d8cd8f17fd3d85))\r\n* **miio:** Fix RetryWrapper never handshaking on stale stamp ([326cb4b](https://github.com/Hypfer/Valetudo/commit/326cb4bafda8b558e8eff2937aa034d3ae25306a))\r\n* **mqtt:** Deduplicate outgoing messages ([b835336](https://github.com/Hypfer/Valetudo/commit/b835336089aa02430cdeb7e877353869fd3e363d))\r\n* **networkadvertisement:** Replace ssdp lib with custom implementation ([f5e505a](https://github.com/Hypfer/Valetudo/commit/f5e505ae3c04313237a0648e5a35d04b6af59ef6))\r\n* **ui:** Disallow whitespaces, + and # for mqtt topic customization ([8148736](https://github.com/Hypfer/Valetudo/commit/81487363a0158c643ce55c7d555790d02d35d48a))\r\n* **ui:** Make the logviewer only auto-scroll if it is already scrolled down ([3c24eba](https://github.com/Hypfer/Valetudo/commit/3c24eba7794b01188f8e0446c4b6dc73c23af96c))\r\n* **vendor.dreame:** Mapping passes can only be done by lidar-based robots ([411fab5](https://github.com/Hypfer/Valetudo/commit/411fab5496c9c2eba9f488d7d97a742073ddf3de))\r\n* **vendor.dreame:** Re-enable custom order segment cleanups and hope for the best ([744a4bb](https://github.com/Hypfer/Valetudo/commit/744a4bb8558e2c938c3b163b3916a6408478b23b))\r\n* **vendor.roborock:** Fix roborock virtual restrictions counting vertices incorrectly ([cc5e37b](https://github.com/Hypfer/Valetudo/commit/cc5e37b6d4e81987005760f867f2487c40435073)), closes [#1423](https://github.com/Hypfer/Valetudo/issues/1423)\r\n* **vendor.roborock:** Properly parse and handle lab_status and map_status ([e158ac4](https://github.com/Hypfer/Valetudo/commit/e158ac4b7fc58ad9ee06bbf4bb296d054afb77d9)), closes [#1424](https://github.com/Hypfer/Valetudo/issues/1424)\r\n* Remove nonsensical always-attached dustbin attachment ([b9bd959](https://github.com/Hypfer/Valetudo/commit/b9bd9599c9931940cc7536eaccbbe2f11f25e066))\r\n* SegmentIds should be strings ([6325045](https://github.com/Hypfer/Valetudo/commit/63250452dfeeaae0e477dc66060be3136df5a7c2))\r\n* SegmentIds should be strings pt2 ([a8d314d](https://github.com/Hypfer/Valetudo/commit/a8d314d2e8878c58a16c2fd4f58f5e866b4fcf85))\r\n* **ui:** Fix customOrder flag for segmentActions ([07c5281](https://github.com/Hypfer/Valetudo/commit/07c5281ae7b52571f49e0e8d553339cf01b6f450))\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1430", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60521593/reactions", + "total_count": 8, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 8, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60507121", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60507121/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/60507121/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.03.0", + "id": 60507121, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4Dm0Px", + "tag_name": "2022.03.0", + "target_commitish": "master", + "name": "Valetudo 2022.03.0", + "draft": false, + "prerelease": true, + "created_at": "2022-02-25T18:10:57Z", + "published_at": "2022-02-25T18:49:08Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926335", + "id": 57926335, + "node_id": "RA_kwDOCGKICM4Dc-K_", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34122221, + "download_count": 46, + "created_at": "2022-02-25T18:55:30Z", + "updated_at": "2022-02-25T18:55:32Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926849", + "id": 57926849, + "node_id": "RA_kwDOCGKICM4Dc-TB", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13802973, + "download_count": 4, + "created_at": "2022-02-25T19:03:25Z", + "updated_at": "2022-02-25T19:03:26Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926332", + "id": 57926332, + "node_id": "RA_kwDOCGKICM4Dc-K8", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964193, + "download_count": 80, + "created_at": "2022-02-25T18:55:27Z", + "updated_at": "2022-02-25T18:55:28Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926333", + "id": 57926333, + "node_id": "RA_kwDOCGKICM4Dc-K9", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31964193, + "download_count": 33, + "created_at": "2022-02-25T18:55:29Z", + "updated_at": "2022-02-25T18:55:30Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926848", + "id": 57926848, + "node_id": "RA_kwDOCGKICM4Dc-TA", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13218985, + "download_count": 6, + "created_at": "2022-02-25T19:03:24Z", + "updated_at": "2022-02-25T19:03:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926845", + "id": 57926845, + "node_id": "RA_kwDOCGKICM4Dc-S9", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13219169, + "download_count": 4, + "created_at": "2022-02-25T19:03:23Z", + "updated_at": "2022-02-25T19:03:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/57926852", + "id": 57926852, + "node_id": "RA_kwDOCGKICM4Dc-TE", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 90, + "created_at": "2022-02-25T19:03:27Z", + "updated_at": "2022-02-25T19:03:28Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.03.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.03.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.03.0", + "body": "
\r\n \"valetudo\"\r\n

2022.03.0

\r\n
\r\n\r\nOrdered segment cleanups via the UI, MQTT deduplication and a lot of internal refactoring\r\n\r\n## Ordered segment cleanup\r\n\r\nThe UI now tracks the order in which segments were selected, meaning that if your robots' firmware supports it, they will be cleaned in the order you've specified.\r\n\r\nIf supported, the order will be displayed as a roman numeral above the segment label triangle.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770812-180860d1-44f4-4531-a746-eff91e97e0cf.png)\r\n\r\n## MQTT\r\n\r\nThe MQTT connectivity feature now reports a state to the UI. Furthermore, it also collects some statistics.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/155770843-92204a3d-23e6-469f-b053-704ff2ec2347.png)\r\n\r\n\r\nBy watching those stats, you will notice that this release also causes less traffic, as most outgoing messages are deduplicated.\r\n\r\nInitially, I didn't want to do that as the solution proposed was to just store every payload in memory and then compare on each mqtt publish.\r\nThat would work, however it comes with a hefty ram overhead as you now have to constantly keep 300+ somewhat long string payloads in memory.\r\nWith each character taking up 2 byte, this approach isn't feasible with the ram budget we have (32 Mbyte or less).\r\n\r\nTo reduce the amount of ram required, we could use a hash function such as md5, however that would still be too much.\r\nAs they'd be saved as hex strings, that would mean 32 characters each with each character taking up 2 bytes, resulting in each pair of topic and payload using 128 byte or more.\r\n\r\nThus, instead we're now using 32-bit CRC32. With object keys being strings, I'd think that these pairs should use around 20 byte each.\r\nThe downside of CRC32 is that the risk of collisions is much higher. However, I highly doubt that that could actually happen in this application.\r\n\r\nTo save CPU time, which is also quite limited on our robots, the (in comparison) huge map data is not being deduplicated.\r\n\r\n## Misc\r\n\r\n- The system information page will now display the current robot firmware version if available\r\n- The UI will now prevent the user from configuring invalid MQTT topic names (containing spaces, # or +)\r\n- The UPnP/SSDP lib was dropped in favour of our own implementation, which should fix some unhandledRejections caused by the lib\r\n- The log viewer now doesn't scroll back down automatically if the user scrolled up\r\n- TotalStatistics should now also work for the Roborock S7\r\n- It is now possible to disable network advertisement (bonjour/mDNS and UPnP/SSDP) via the UI if you so desire\r\n- The nonsensical always-attached dustbin attachment has been removed\r\n- It is now possible to have 50% more virtual restrictions on roborock robots\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Allow setting the order of segments cleaned if support by the robot ([9eec3b6](https://github.com/Hypfer/Valetudo/commit/9eec3b6200dee08d4094fdac47e9200e9585961e))\r\n* NetworkAdvertisementManager UI control ([bd5fa9c](https://github.com/Hypfer/Valetudo/commit/bd5fa9c1d156cab2b499952acb7664ebee554623)), closes [#1168](https://github.com/Hypfer/Valetudo/issues/1168)\r\n* **core:** Remove outdated VirtualWallCapability and RestrictedZoneCapability ([5e24783](https://github.com/Hypfer/Valetudo/commit/5e247835e3772ed57d445c8be82849bcedba6db6))\r\n* **core:** Remove SensorCalibrationCapability ([5b081a7](https://github.com/Hypfer/Valetudo/commit/5b081a78a4dbccf54ad2fb547daaa622ce8c8c7f))\r\n* **mqtt:** Collect runtime metrics and provide them via REST ([dcc1db4](https://github.com/Hypfer/Valetudo/commit/dcc1db4f86265be47242d2f836ba3ffac521ed67))\r\n* **ui:** Display firmware version if available ([e78e9b4](https://github.com/Hypfer/Valetudo/commit/e78e9b4e1dc84b7ce2b60adb36ec35675664ded0))\r\n* **ui:** Display MQTTClient status ([c54ebc8](https://github.com/Hypfer/Valetudo/commit/c54ebc8c1eae6c14a35247e7e55ce2bb2e0d0ccd))\r\n* **vendor.roborock:** Support S7 total statistics ([d1926a9](https://github.com/Hypfer/Valetudo/commit/d1926a9b33dfdbdf53f8b3b53ef0ee695c53c867))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Fix free memory reporting on kernels >= 3.14 ([dceea16](https://github.com/Hypfer/Valetudo/commit/dceea16f5a3fbc7b69ea938dd3c112e12a874019))\r\n* **miio:** Don't throw plain objects on error responses ([e84fe8c](https://github.com/Hypfer/Valetudo/commit/e84fe8c066b3ad3b7576405ee7d8cd8f17fd3d85))\r\n* **miio:** Fix RetryWrapper never handshaking on stale stamp ([326cb4b](https://github.com/Hypfer/Valetudo/commit/326cb4bafda8b558e8eff2937aa034d3ae25306a))\r\n* **mqtt:** Deduplicate outgoing messages ([b835336](https://github.com/Hypfer/Valetudo/commit/b835336089aa02430cdeb7e877353869fd3e363d))\r\n* **networkadvertisement:** Replace ssdp lib with custom implementation ([f5e505a](https://github.com/Hypfer/Valetudo/commit/f5e505ae3c04313237a0648e5a35d04b6af59ef6))\r\n* **ui:** Disallow whitespaces, + and # for mqtt topic customization ([8148736](https://github.com/Hypfer/Valetudo/commit/81487363a0158c643ce55c7d555790d02d35d48a))\r\n* **ui:** Make the logviewer only auto-scroll if it is already scrolled down ([3c24eba](https://github.com/Hypfer/Valetudo/commit/3c24eba7794b01188f8e0446c4b6dc73c23af96c))\r\n* **vendor.dreame:** Mapping passes can only be done by lidar-based robots ([411fab5](https://github.com/Hypfer/Valetudo/commit/411fab5496c9c2eba9f488d7d97a742073ddf3de))\r\n* **vendor.dreame:** Re-enable custom order segment cleanups and hope for the best ([744a4bb](https://github.com/Hypfer/Valetudo/commit/744a4bb8558e2c938c3b163b3916a6408478b23b))\r\n* **vendor.roborock:** Fix roborock virtual restrictions counting vertices incorrectly ([cc5e37b](https://github.com/Hypfer/Valetudo/commit/cc5e37b6d4e81987005760f867f2487c40435073)), closes [#1423](https://github.com/Hypfer/Valetudo/issues/1423)\r\n* **vendor.roborock:** Properly parse and handle lab_status and map_status ([e158ac4](https://github.com/Hypfer/Valetudo/commit/e158ac4b7fc58ad9ee06bbf4bb296d054afb77d9)), closes [#1424](https://github.com/Hypfer/Valetudo/issues/1424)\r\n* Remove nonsensical always-attached dustbin attachment ([b9bd959](https://github.com/Hypfer/Valetudo/commit/b9bd9599c9931940cc7536eaccbbe2f11f25e066))\r\n* SegmentIds should be strings ([6325045](https://github.com/Hypfer/Valetudo/commit/63250452dfeeaae0e477dc66060be3136df5a7c2))\r\n* SegmentIds should be strings pt2 ([a8d314d](https://github.com/Hypfer/Valetudo/commit/a8d314d2e8878c58a16c2fd4f58f5e866b4fcf85))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1429", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/60507121/reactions", + "total_count": 3, + "+1": 3, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/58174812/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.02.0", + "id": 58174812, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4Dd61c", + "tag_name": "2022.02.0", + "target_commitish": "master", + "name": "Valetudo 2022.02.0", + "draft": false, + "prerelease": false, + "created_at": "2022-01-28T10:32:30Z", + "published_at": "2022-01-28T10:39:20Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55189921", + "id": 55189921, + "node_id": "RA_kwDOCGKICM4DSiGh", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34276203, + "download_count": 598, + "created_at": "2022-01-28T10:46:14Z", + "updated_at": "2022-01-28T10:46:16Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190622", + "id": 55190622, + "node_id": "RA_kwDOCGKICM4DSiRe", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13956163, + "download_count": 7, + "created_at": "2022-01-28T10:54:30Z", + "updated_at": "2022-01-28T10:54:31Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55189918", + "id": 55189918, + "node_id": "RA_kwDOCGKICM4DSiGe", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32118175, + "download_count": 1828, + "created_at": "2022-01-28T10:46:11Z", + "updated_at": "2022-01-28T10:46:12Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55189920", + "id": 55189920, + "node_id": "RA_kwDOCGKICM4DSiGg", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32118175, + "download_count": 489, + "created_at": "2022-01-28T10:46:13Z", + "updated_at": "2022-01-28T10:46:14Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190621", + "id": 55190621, + "node_id": "RA_kwDOCGKICM4DSiRd", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13373375, + "download_count": 14, + "created_at": "2022-01-28T10:54:29Z", + "updated_at": "2022-01-28T10:54:30Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190619", + "id": 55190619, + "node_id": "RA_kwDOCGKICM4DSiRb", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13373215, + "download_count": 16, + "created_at": "2022-01-28T10:54:28Z", + "updated_at": "2022-01-28T10:54:29Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/55190626", + "id": 55190626, + "node_id": "RA_kwDOCGKICM4DSiRi", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 2526, + "created_at": "2022-01-28T10:54:32Z", + "updated_at": "2022-01-28T10:54:32Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.02.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.02.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.02.0", + "body": "
\r\n \"valetudo\"\r\n

2022.02.0

\r\n
\r\n\r\nLots of UI changes and more polishing\r\n\r\n## Quirks\r\n\r\nThis release adds the quirks concept, which shall be understood as a catch-all and/or staging area containing vendor-specific toggles that don't fit the generic abstraction that is Valetudo (yet).\r\nThis should make it fairly easy to quickly implement (some of the) exciting new vendor features without jeopardizing the architecture of Valetudo in the long run.\r\n\r\nHere's an example taken from the Dreame Z10:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532264-ff6b848f-0c5a-4083-af92-d3bc29be77a0.png)\r\n\r\n\r\n## Settings\r\n\r\nRobot, Map and Connectivity settings have been reorganized/redone.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532305-e97a3534-3f8a-44bc-8d4d-dec5537d7c70.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532320-456cda6f-b5f7-4104-95f5-4b258d0b576b.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532335-d0a79b27-b1ae-4114-b5f2-e5f2311ed8e0.png)\r\n\r\n\r\nWi-Fi and NTP state display has been redone as well:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532430-07629c75-e112-4d8c-acb6-5138d0d6de3d.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532445-ba2b34b4-6b25-4a22-9a7b-558054405b3f.png)\r\n\r\n\r\n## Quality of Life\r\n\r\nA _lot_ of help text sections and dialogs have been added all around the application to make usage of Valetudo even easier.\r\nThey should also answer a lot of common support questions, so make sure to read them before asking questions.\r\n\r\nFurthermore, all password fields have been updated to feature a plain-text-display toggle.\r\n\r\n\r\n## Total Statistics\r\n\r\nBecause displaying three numbers is boring, @ccoors had the great idea of adding gamification the total statistics feature.\r\nAfter some iteration on that idea, we've ended up with this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532462-7843b526-9c81-4b7f-bffe-1165d7dd02c9.png)\r\n\r\n\r\nThere's also an overview of all achievements:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/151532488-d0cfc8d4-c477-4ed6-8d48-edcfe6d6bec7.png)\r\n\r\n\r\nI'm very happy with how this turned out. Now we just need to think of more achievements.\r\nIf you have any ideas, feel free to leave them down in the comments.\r\n\r\n\r\n\r\n## Nightly builds\r\n\r\nThere are now automated nightly builds, which you can install using the updater.\r\n\r\nAs this is meant for people willing to accept and capable of handling breakage, there is no UI toggle to switch to nightly builds.\r\nTo enable them, ssh into your robot and change the update provider to `github_nightly`.\r\n\r\n## Misc\r\n\r\n- Viomi consumables have been fixed by @adrez99\r\n- @schinken fixed local access via IPv6\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** WifiScanCapability ([a4fe895](https://github.com/Hypfer/Valetudo/commit/a4fe895c9944ffe8fae6e621a87e2aa70e9aecde))\r\n* **ui:** Add general help ([ec298dc](https://github.com/Hypfer/Valetudo/commit/ec298dc2cf2d81ca40031dfae455abf490f9fcf8))\r\n* **ui:** Add help for dnd, voice packs and the updater ([84c8c04](https://github.com/Hypfer/Valetudo/commit/84c8c04657778795cb7e7acd76bbef001465ba3a))\r\n* **ui:** Add Map Management Help ([9d62c26](https://github.com/Hypfer/Valetudo/commit/9d62c26318ecda5d5a38e21333f56ac0ff1f70c6))\r\n* **ui:** Add quirks help ([77183ed](https://github.com/Hypfer/Valetudo/commit/77183ed3e63c94d30afbefc6d48cab8bf946b9f2))\r\n* **ui:** Add total statistics page ([#1330](https://github.com/Hypfer/Valetudo/issues/1330)) ([8fd0b2e](https://github.com/Hypfer/Valetudo/commit/8fd0b2eb3c59a5b949da8c9c6f0f4230886d48e6))\r\n* **ui:** Allow display of Wi-Fi passwords entered ([89624eb](https://github.com/Hypfer/Valetudo/commit/89624eb5b6c2b8091ab66821ebf1c3f82f119316))\r\n* **ui:** Allow newlines in confirmation dialog ([df2ee4f](https://github.com/Hypfer/Valetudo/commit/df2ee4f0ac0e209ac537a77705a860c5161f756b))\r\n* **ui:** Another achievement ([0ffbef4](https://github.com/Hypfer/Valetudo/commit/0ffbef4f3d64e1c50ae6663c277ef33d9c2e80ce))\r\n* **ui:** Extend map management help ([e1514bc](https://github.com/Hypfer/Valetudo/commit/e1514bcc59f8c0022aef588b58b10e2cc05c1ef9))\r\n* ValetudoWifiStatus may contain a bssid ([86fe2f2](https://github.com/Hypfer/Valetudo/commit/86fe2f207c2f050ca7351c21bd736de4f2d5d27b))\r\n* **ui:** Allow display of entered passwords for mqtt and basic auth ([4e75531](https://github.com/Hypfer/Valetudo/commit/4e7553100abb4dba247fbb036a6539499c619b89))\r\n* **ui:** Disable edit map tap interaction while not docked to reduce confusion ([b68e444](https://github.com/Hypfer/Valetudo/commit/b68e44428b3c2669cae147c8c4f21bbfc9bc016d))\r\n* **ui:** Improve achievement badges ([7eea13e](https://github.com/Hypfer/Valetudo/commit/7eea13e84950d01c044bc69ef385b33908ee20df))\r\n* **ui:** Improve NTP client state display ([0a265a7](https://github.com/Hypfer/Valetudo/commit/0a265a7dce5468e2948a077bd7e6f364212a285b))\r\n* **ui:** More achievements ([892017e](https://github.com/Hypfer/Valetudo/commit/892017ea38c16eee3ac6bc52d8ff5bde76e87ab1))\r\n* **ui:** Move map-related features to map management page ([ea45f01](https://github.com/Hypfer/Valetudo/commit/ea45f01b6a597f43d6000318500936702c89e397))\r\n* **ui:** Move Wi-Fi settings to connectivity ([dff909c](https://github.com/Hypfer/Valetudo/commit/dff909cae688b2106cc526475247cf0659251e46))\r\n* **ui:** Provide an overview of all achievements ([381e3cd](https://github.com/Hypfer/Valetudo/commit/381e3cd4dab807b85d8066ca4aa9f8628fe599d6))\r\n* **ui:** Rename about page to system information ([ad1dd16](https://github.com/Hypfer/Valetudo/commit/ad1dd1608dc0e2668914d7ab7a2eb68cb6978163))\r\n* **ui:** Restructure connectivity settings ([bfe33e4](https://github.com/Hypfer/Valetudo/commit/bfe33e4d4d929741a1a3191559ae84343dbe9a61))\r\n* **ui:** Restructure robot settings ([5c71be4](https://github.com/Hypfer/Valetudo/commit/5c71be44eb4a9f30674af550e230590b203ea82d))\r\n* **ui:** Restructure routers and add about page ([e3a1f13](https://github.com/Hypfer/Valetudo/commit/e3a1f1303bb8693aea0a8ea7ffb32d8fd658110a))\r\n* **updater:** Add nightly builds ([d1a0d91](https://github.com/Hypfer/Valetudo/commit/d1a0d919a6fd7df93031bdb7da469b1b61cdbc13))\r\n* **vendor.dreame:** Add auto empty interval quirk ([1b6205a](https://github.com/Hypfer/Valetudo/commit/1b6205a467304bcd4c9ce32aa28721fe0fd377f5))\r\n* **vendor.roborock:** Add quirks ([7fc584a](https://github.com/Hypfer/Valetudo/commit/7fc584af029efbe2a7b8e063fb9659afa43d0955))\r\n* **vendor.viomi:** Add quirks ([#1369](https://github.com/Hypfer/Valetudo/issues/1369)) ([b369e4d](https://github.com/Hypfer/Valetudo/commit/b369e4d7a253bd668f354f179a878fd8ce9c0717))\r\n* QuirksCapability ([79deeb1](https://github.com/Hypfer/Valetudo/commit/79deeb14eb855e294f0b9d3197151e8af5cc03ce))\r\n* **webserver:** Allow IPv6 requests from own network ([#1342](https://github.com/Hypfer/Valetudo/issues/1342)) ([165deff](https://github.com/Hypfer/Valetudo/commit/165deff8e033b45ec1e507d4678833dbca8b22d4))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix consumables not being polled by the autorefresh ([58d6267](https://github.com/Hypfer/Valetudo/commit/58d6267e3008c6637725ed7f531f07d182b01ddf)), closes [#1355](https://github.com/Hypfer/Valetudo/issues/1355)\r\n* **networkadvertisement:** Attempt to catch issues of the ssdp lib ([ee3154b](https://github.com/Hypfer/Valetudo/commit/ee3154bfdb6c5caadc22382e0e48e9a42a2df202))\r\n* **ui:** Allow refetching when there are zero quirks ([7f3ed2b](https://github.com/Hypfer/Valetudo/commit/7f3ed2b8b688ecf9f26436209625dda35e654b62))\r\n* **ui:** Allow user-selection of wifi IP addresses ([33c9470](https://github.com/Hypfer/Valetudo/commit/33c9470162ba4fe6ae2bbf5ba2de26ea08f1d47f))\r\n* **ui:** Allow user-selection of wifi IP addresses... again ([2bdcea4](https://github.com/Hypfer/Valetudo/commit/2bdcea4701b8828dfbcdde79aac12823ece07295))\r\n* **ui:** Disable updater buttons when busy ([f82ae1a](https://github.com/Hypfer/Valetudo/commit/f82ae1a0a114c3255c43d2700cab54a9f87067ff))\r\n* **ui:** Don't display updater warning if state is busy ([4d5c781](https://github.com/Hypfer/Valetudo/commit/4d5c7811b74c3a61f3eebaf1064bb18f6a1810a0))\r\n* **ui:** Don't provide the wifi configuration route if there is no wifi configuration capability ([82e954e](https://github.com/Hypfer/Valetudo/commit/82e954e2d072dcf7888aeef7eb732b78a73311f4))\r\n* **ui:** Fix about title ([67a9a05](https://github.com/Hypfer/Valetudo/commit/67a9a051c7d2071099a57a3a6dbf1e4fa101ca31))\r\n* **ui:** Fix display of text in conjunction with controls in Map Management ([1cc76c5](https://github.com/Hypfer/Valetudo/commit/1cc76c55f3c27be5f03e5a7cbfd6cc184ad40675))\r\n* **ui:** Fix logviewer timestamp display for chrome ([56f5ba0](https://github.com/Hypfer/Valetudo/commit/56f5ba08a9bc864eb20df9b17f109c0b1a89226e))\r\n* **ui:** Fix map management not using unique keys for all options ([2305b52](https://github.com/Hypfer/Valetudo/commit/2305b528be28351e3e02f6197ca88135dc95e64c))\r\n* **ui:** Fix menu drawer scrollbars ([4a6c9fa](https://github.com/Hypfer/Valetudo/commit/4a6c9faffcefba07277372a9172aa6f899d795ad))\r\n* **ui:** fix minor typo ([#1341](https://github.com/Hypfer/Valetudo/issues/1341)) ([77e07ec](https://github.com/Hypfer/Valetudo/commit/77e07ec04bb32407176ff184e706a4229cdffced))\r\n* **ui:** Properly implement newlines in ConfirmationDialog ([b8f8eb0](https://github.com/Hypfer/Valetudo/commit/b8f8eb0163b8b3c13b5a2e1bab27837b8ff90811))\r\n* **ui:** Sort total statistics data points ([a568c03](https://github.com/Hypfer/Valetudo/commit/a568c03afa0521779f40c4933935b5315a81bd24))\r\n* **ui:** use relativ paths to allow hosting in a subdirectory .. again ([3007dbb](https://github.com/Hypfer/Valetudo/commit/3007dbb1460596591199ece1d974c3b4e1db58e3))\r\n* **updater:** Add missing return statement ([f5e7451](https://github.com/Hypfer/Valetudo/commit/f5e7451a5877815a8871cdccdbf997f09b4b78ca))\r\n* **vendor.viomi:** Fix Viomi consumables ([#1367](https://github.com/Hypfer/Valetudo/issues/1367)) ([ccfe175](https://github.com/Hypfer/Valetudo/commit/ccfe175886ac41ff58f900de54657967a8f17337))\r\n* **webserver:** Fix missing doctype for error pages ([3d48611](https://github.com/Hypfer/Valetudo/commit/3d486114830eb69ba2f414aa67fdf4494cfefe3c))\r\n* **webserver:** Fix some endpoints never returning anything ([32c0f6a](https://github.com/Hypfer/Valetudo/commit/32c0f6ae922f71a8fd7ac5b035b9f5fffd1cdc8f))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1379", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/58174812/reactions", + "total_count": 8, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 3, + "confused": 0, + "heart": 1, + "rocket": 4, + "eyes": 0 + }, + "mentions_count": 3 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/56229531/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2022.01.0", + "id": 56229531, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DWf6b", + "tag_name": "2022.01.0", + "target_commitish": "master", + "name": "Valetudo 2022.01.0", + "draft": false, + "prerelease": false, + "created_at": "2021-12-31T12:47:26Z", + "published_at": "2021-12-31T12:50:40Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919159", + "id": 52919159, + "node_id": "RA_kwDOCGKICM4DJ3t3", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34238322, + "download_count": 563, + "created_at": "2021-12-31T12:57:20Z", + "updated_at": "2021-12-31T12:57:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919489", + "id": 52919489, + "node_id": "RA_kwDOCGKICM4DJ3zB", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13918386, + "download_count": 10, + "created_at": "2021-12-31T13:05:24Z", + "updated_at": "2021-12-31T13:05:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919155", + "id": 52919155, + "node_id": "RA_kwDOCGKICM4DJ3tz", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32080294, + "download_count": 1527, + "created_at": "2021-12-31T12:57:17Z", + "updated_at": "2021-12-31T12:57:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919157", + "id": 52919157, + "node_id": "RA_kwDOCGKICM4DJ3t1", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32080294, + "download_count": 481, + "created_at": "2021-12-31T12:57:18Z", + "updated_at": "2021-12-31T12:57:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919485", + "id": 52919485, + "node_id": "RA_kwDOCGKICM4DJ3y9", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13334790, + "download_count": 19, + "created_at": "2021-12-31T13:05:23Z", + "updated_at": "2021-12-31T13:05:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919483", + "id": 52919483, + "node_id": "RA_kwDOCGKICM4DJ3y7", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13334414, + "download_count": 19, + "created_at": "2021-12-31T13:05:22Z", + "updated_at": "2021-12-31T13:05:23Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/52919492", + "id": 52919492, + "node_id": "RA_kwDOCGKICM4DJ3zE", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1842, + "created_at": "2021-12-31T13:05:27Z", + "updated_at": "2021-12-31T13:05:27Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2022.01.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2022.01.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2022.01.0", + "body": "
\r\n \"valetudo\"\r\n

2022.01.0

\r\n
\r\n\r\nQuality of life improvements, bugfixes and more polishing. Also, Happy New Year :)\r\n\r\n## UI/UX Changes\r\n\r\n### Map Management\r\n\r\nThe map management feature has been restructured to be easier to understand especially for newcomers.\r\nFurthermore, there are now help texts available in the editor, which should answer common questions.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824285-2d9337b3-3a50-478a-ae2b-9f216fbcd544.png)\r\n![image](https://user-images.githubusercontent.com/974410/147824293-0c03affb-d343-4f6f-a5ba-4f939c56ec0b.png)\r\n![image](https://user-images.githubusercontent.com/974410/147824290-d1b5f4d2-e4aa-403a-b5a7-82461ec1a6ed.png)\r\n\r\n\r\n### Updater\r\n\r\nThe updater now auto-refreshes its state and provides more feedback.\r\nIt will also display the latest changelog if there's no update available.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824299-49d9aa54-b571-4544-84e9-143a30e5c545.png)\r\n\r\n\r\n### Misc\r\n\r\n- The UI now auto-refreshes if the backend version changed\r\n- Visual consistency has been improved\r\n- The title is now updated based on the page you're on which makes your browser history actually useful\r\n- Hovering over some unlabelled buttons/icons should now give you a tooltip clearing things up\r\n- You can now hover over the progress bars in the about page to get a tooltip for the value as well\r\n- Info boxes answering common questions have been added to the connectivity page\r\n- It should now be possible to use Valetudo in a sub folder of a reverse proxy again\r\n\r\n\r\n## MQTT Changes\r\n\r\n### Home Assistant 2021.12\r\n\r\nValetudo now **requires Home Assistant 2021.12 or newer** as that release introduced the `object_id` field for\r\nMQTT autodiscovery. This allows us to influence the `entity_id` so that the days of `camera.map_data_3` are gone.\r\n\r\nYou might have to delete the device in HA and let it be rediscovered for these changes to be applied.\r\n\r\nIt is worth it though:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/147824304-96a6d2c9-3ff8-4b6a-965a-dc3ff599ab9f.png)\r\n\r\n\r\n### Bugfixes\r\n\r\nMultiple issues regarding MQTT stability and reliability have been identified and fixed with this release, hopefully\r\nsolving connectivity issues in situations with bad Wi-Fi signal coverage.\r\n\r\n\r\n## External Access\r\n\r\nValetudo now attempts to block access from public-routable IPs to its REST-Interface by default.\r\nThis was necessary, because publicly-accessible Valetudo instances kept appearing \r\non Shodan.io.\r\n\r\nIt is certainly no foolproof solution, but it might at least help a little.\r\nYou can also disable the filter if you absolutely have to, however I'd strongly recommend not doing that.\r\n\r\n## Misc\r\n\r\nAs it turns out, nodes `os.getNetworkInterfaces()` does not return all network interfaces, which led to the unique\r\nsystem identifier randomly changing depending on whether or not the robot had an IP address.\r\nThis has been fixed by the use of the mighty `sysfs`.\r\n\r\nMoreover, Valetudo now polls the network state every 30s in an attempt to catch network changes and restart\r\nthe network advertisement so that the companion app doesn't display `192.168.5.1` right after provisioning.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Remove DebugCapability ([78c84de](https://github.com/Hypfer/Valetudo/commit/78c84ded4eef1ac3b9a3e0d66ef88ebd5d44c19f))\r\n* **ui:** Add hover labels to system ram and load information ([62ed252](https://github.com/Hypfer/Valetudo/commit/62ed252968b97b72662a4a6622f2c0c75bdf2b5b))\r\n* **ui:** Add info boxes answering common questions to the connectivity settings page ([9eae3e3](https://github.com/Hypfer/Valetudo/commit/9eae3e393dda0a7376be79b5b6cdc81c9fc0b27e))\r\n* **ui:** Add link to the docs ([88b810c](https://github.com/Hypfer/Valetudo/commit/88b810c1b454c637c72aa51ab5015f7162e9812a))\r\n* **ui:** Automatically refresh the page when the backend version changed ([905ada1](https://github.com/Hypfer/Valetudo/commit/905ada104441c2283038c4a963a2e197bf511af1))\r\n* **ui:** Change infobox icon ([a82e1df](https://github.com/Hypfer/Valetudo/commit/a82e1df022395e109ddb5ea207be652ce93565e0))\r\n* **ui:** Consolidate paths to a single svg ([82bc46b](https://github.com/Hypfer/Valetudo/commit/82bc46b9e157df21490ad5009beae6277520b564))\r\n* **ui:** Improve first-time usability by adding titles to buttons and more minor changes ([6126718](https://github.com/Hypfer/Valetudo/commit/612671809d2f8ce8018866b2ca8257b34b1d1bbf))\r\n* **ui:** Improve segment edit help ([17e1d5f](https://github.com/Hypfer/Valetudo/commit/17e1d5ffaa0d938317699b89a2244541dd9dad14))\r\n* **ui:** Improve visual consistency ([006b94b](https://github.com/Hypfer/Valetudo/commit/006b94b1c47cbe6376d0340d2c7c0ae82fc26341))\r\n* **ui:** More space for mobile ([6a6ba65](https://github.com/Hypfer/Valetudo/commit/6a6ba65ce7d7d9c4629d39ef9c61ee6e685679bc))\r\n* **ui:** Rework map management ([4f51935](https://github.com/Hypfer/Valetudo/commit/4f51935fe1ea55921c81080c33918355807e23fe))\r\n* **ui:** Use non-swipable drawer for better performance ([25298a0](https://github.com/Hypfer/Valetudo/commit/25298a05ead114dca93c8e4e3b4b39e623838f8d))\r\n* **updater:** Display changelog of latest release when in noUpdateRequired state ([ce0c675](https://github.com/Hypfer/Valetudo/commit/ce0c675eca5548b7bb1fc55a9e2fc40290ce1bb3))\r\n* **updater:** Introduce busy state to provide better user feedback ([4e9ed3d](https://github.com/Hypfer/Valetudo/commit/4e9ed3d0b38a225bb1a93a5d32dee4686b04382b))\r\n* **webserver:** Attempt to block external access to valetudo ([10b1662](https://github.com/Hypfer/Valetudo/commit/10b1662f94d719d03b59c29bd51ab440b7d616dc))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **updater:** fix(updater): Use busy state flag instead of busy state ([d122efcb](https://github.com/Hypfer/Valetudo/commit/d122efcb53f301b124f182ef471e3f9e23c5771b))\r\n* **core:** Use sysfs to reliably determine the unique system identifier in all network conditions ([8d74825](https://github.com/Hypfer/Valetudo/commit/8d74825f4dd8ec3a8414259c3da8671efc694f36))\r\n* **mqtt:** Don't try to publish anything if there is no mqtt connection ([9051ac0](https://github.com/Hypfer/Valetudo/commit/9051ac04156c061f84e50e5e741ab7e65fc8431c))\r\n* **mqtt:** Fix mqtt getting stuck forever requiring a restart ([42a5613](https://github.com/Hypfer/Valetudo/commit/42a5613d19cd46bba0e5243f656d062f8a4d4415))\r\n* **mqtt:** Force disconnect if it takes longer than 1500ms ([ced9ee1](https://github.com/Hypfer/Valetudo/commit/ced9ee1b3312489c0c937723ba8744c21264f540))\r\n* **mqtt:** More .disconnect() fixes ([322efcc](https://github.com/Hypfer/Valetudo/commit/322efcc7cad8e1ae67126ded81b2d327c50bea8d))\r\n* **networkadvertisement:** Attempt to watch for network state changes to fix advertisement after initial provisioning ([7a2c3d1](https://github.com/Hypfer/Valetudo/commit/7a2c3d1a8c32d88562bc2dacec9671e1e756947a))\r\n* **ui:** Redraw map on visibilityState change to fix map not being updated if the tab was invisible for too long ([1c86152](https://github.com/Hypfer/Valetudo/commit/1c861521430e5df4640d614d75dcaa6def09124c))\r\n* **ui:** use relativ paths to allow hosting in a subdirectory ([1e73947](https://github.com/Hypfer/Valetudo/commit/1e73947d2a16bb831bc14d85ebeedb242b7714ef))\r\n* **vendor.dreame:** Ignore more irrelevant property updates ([9e4e202](https://github.com/Hypfer/Valetudo/commit/9e4e2028c69c9a37f661a4c90904311d65c9e90e))\r\n* **webserver:** Handle aborted connections gracefully ([b3e8024](https://github.com/Hypfer/Valetudo/commit/b3e802479e5068df25c951b2e148655c8f7448fa))\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1316", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/56229531/reactions", + "total_count": 10, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 10, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/54959037/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.12.1", + "id": 54959037, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DRpu9", + "tag_name": "2021.12.1", + "target_commitish": "master", + "name": "Valetudo 2021.12.1", + "draft": false, + "prerelease": false, + "created_at": "2021-12-09T13:05:00Z", + "published_at": "2021-12-09T13:08:53Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51390567", + "id": 51390567, + "node_id": "RA_kwDOCGKICM4DEChn", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34173424, + "download_count": 415, + "created_at": "2021-12-09T13:16:24Z", + "updated_at": "2021-12-09T13:16:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391087", + "id": 51391087, + "node_id": "RA_kwDOCGKICM4DECpv", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13854816, + "download_count": 7, + "created_at": "2021-12-09T13:25:45Z", + "updated_at": "2021-12-09T13:25:46Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51390565", + "id": 51390565, + "node_id": "RA_kwDOCGKICM4DEChl", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015396, + "download_count": 1099, + "created_at": "2021-12-09T13:16:20Z", + "updated_at": "2021-12-09T13:16:22Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51390566", + "id": 51390566, + "node_id": "RA_kwDOCGKICM4DEChm", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015396, + "download_count": 353, + "created_at": "2021-12-09T13:16:22Z", + "updated_at": "2021-12-09T13:16:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391086", + "id": 51391086, + "node_id": "RA_kwDOCGKICM4DECpu", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13270228, + "download_count": 12, + "created_at": "2021-12-09T13:25:44Z", + "updated_at": "2021-12-09T13:25:45Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391085", + "id": 51391085, + "node_id": "RA_kwDOCGKICM4DECpt", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13269756, + "download_count": 21, + "created_at": "2021-12-09T13:25:43Z", + "updated_at": "2021-12-09T13:25:44Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51391091", + "id": 51391091, + "node_id": "RA_kwDOCGKICM4DECpz", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1420, + "created_at": "2021-12-09T13:25:48Z", + "updated_at": "2021-12-09T13:25:48Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.12.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.12.1", + "body": "
\r\n \"valetudo\"\r\n

2021.12.1

\r\n
\r\n\r\nMap data format changes, quality of life improvements and bugfixes.\r\n\r\n## Changes in 2021.12.1\r\n\r\nAs expected, something would go wrong with the map data format change.\r\nThis is a bugfix release, so 98% of the previous changelog still apply.\r\n\r\n\r\nIn 2021.12.0, if you have rooms that aren't rectangular, it might happen that the triangle to select it vanishes, leading to you being unable to trigger a segment cleanup using the UI.\r\nThis happened because in those cases, the UI calculates the median pixel coordinates to properly place the triangle.\r\nThis value isn't calculated by the backend, because it is an expensive operation, and we're both RAM and CPU-limited there.\r\n\r\nTo calculate the median, the UI needs the decompressed pixel coordinate format.\r\nThis works exactly once during the initial render, because of the MapLayerRenderer doing the pixel decompression on the map passed by reference to it.\r\n\r\nAs soon as the WebWorker is available however, this doesn't happen anymore, as the worker only receives a copy of the data.\r\nThis means that there are now 0 pixels as far as the SegmentLabel is concerned, leading it to be placed at coordinates `[NaN,NaN]`.\r\nSince testing is done locally without constant map updates, everything seemed fine during development.\r\n\r\n\r\nAnother thing discovered due to this bug was that the GithubValetudoUpdateProvider did not filter out pre-releases or drafts.\r\nNot a big issue though as it just requires you to update twice in a row.\r\n\r\nAnyways, on with the 2021.12.0 changelog:\r\n\r\n## Map data format changes\r\n\r\nThis release features the first version increment of the ValetudoMap data format.\r\nInitially, in version 1, pixel data such as walls or floor were stored as a huge array of coordinate pairs:\r\n`[x0, y0, x1, y1, ...]`. This was not a very efficient way of storing that data as most of it is redundant.\r\n\r\nThis resulted in map files that were over 1 MiB in size being pushed to your browser every 3 seconds.\r\n\r\nTo combat this, some thought was put into how the data is stored.\r\nIf you have a row of pixels, all of them will have the same y-coordinate, meaning that you only have to store that once.\r\nPeople already figured that out [in the 60s](https://en.wikipedia.org/wiki/Run-length_encoding).\r\n\r\nWith Map V2, pixels are stored as `[xStart0, y0, count0, xStart1, y1, count1, ...]` where `[xStart, y]` is the starting point and `count` represents additional pixels with the same y-coordinate to the right.\r\n\r\nThis resulted in V2 map files using between 5% and 15% of the size of the equivalent V1 map.\r\nThe huge testfile map for example was compressed from 847 kB to 75 kB.\r\n\r\n\r\nWhile this is a **breaking change**, the breakage actually isn't that big of a change as V2 can easily be converted back to V1.\r\nIn fact, running `JSON.parse()` on a V2 map and then converting it to a V1 one in memory is more than twice as fast as running `JSON.parse()` on a V1 map.\r\n\r\nSince this change drastically reduces the traffic caused by live maps, I expect to see general usability and reliability\r\nimprovements in situations where the Wi-Fi reception isn't that great.\r\n\r\n\r\n## LogViewer\r\n\r\nThe LogViewer has been greatly improved and now features a structured and color-coded view of your log.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744519-5ba963b9-6409-4e04-95d9-e73caf55021c.png)\r\n\r\nYou can use the text filter at the top to either filter for the loglevel or the message contents.\r\nJust start typing.\r\n\r\n## UI Help\r\n\r\nBoth consumables and timers now feature a help button, which shall explain how to use these features.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744625-d113d697-e4e1-4f77-a3a2-596ad88131a5.png)\r\n\r\n\r\n## Misc\r\n\r\n- Map reset on newer roborock models should now be fixed thanks to @supersmile2009\r\n- Zooming the map should now work much better if you zoom via a touchpad or trackpoint instead of a mousewheel\r\n- MQTT current statistics now have a unit_of_measurement in HA\r\n- Lowmem builds now have a reduced map poll rate to reduce memory pressure\r\n- Valetudo now manages its logfile size to prevent it from growing indefinitely\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Automatically clear the logfile when it gets too large ([c0698b4](https://github.com/Hypfer/Valetudo/commit/c0698b43dda5144d7d0c2c58d9336a1c0662cc65))\r\n* Reduce map polling interval for lowmem hosts ([fcf94ce](https://github.com/Hypfer/Valetudo/commit/fcf94ceeb60f9b46e25bfa04d2e4e88ac2a25926))\r\n* **ntpClient:** Improve log messages ([8880bbf](https://github.com/Hypfer/Valetudo/commit/8880bbfc7ed79969a61c6d6e51f7023c23d7561e))\r\n* **ui:** Add help button + modal to consumables view ([d1388f1](https://github.com/Hypfer/Valetudo/commit/d1388f124dae0046d2bee49345d0513441926f21))\r\n* **ui:** Add timers help ([c864170](https://github.com/Hypfer/Valetudo/commit/c864170d44c2b686394bb6d770cff937e8a9de43))\r\n* **ui:** Implement LogViewer component ([1b96ae0](https://github.com/Hypfer/Valetudo/commit/1b96ae06c8a74acbc9a6fa03cf941736520e30d0))\r\n* **ui:** Remove obsolete about > github release info ([253d9f9](https://github.com/Hypfer/Valetudo/commit/253d9f99b0965859705c52ffae9483c381d49ad7))\r\n* **ui:** Swap Manual control cw & ccw rotation button ([44eab06](https://github.com/Hypfer/Valetudo/commit/44eab06eadcd57c8c9b3784bc6f4c7a6dbea58e8))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Automatically refresh the updater state ([596dc06](https://github.com/Hypfer/Valetudo/commit/596dc067a6e77d908e3dc11b3e60aeab1e72bd07))\r\n* **ui:** Transparently decompress the v2 map data in the api client ([0bcb974](https://github.com/Hypfer/Valetudo/commit/0bcb974fd9c1ffa8c164b494899ef9c9e1735091)), closes [#1262](https://github.com/Hypfer/Valetudo/issues/1262)\r\n* **updater:** Ignore github release drafts and prereleases ([ad97a14](https://github.com/Hypfer/Valetudo/commit/ad97a146b0989f7caf21c3b834849aca75b9bdc3))\r\n* **ui:** Try avoiding bright flashes on initial loading ([f84a51d](https://github.com/Hypfer/Valetudo/commit/f84a51dc7c09ec4a7cb19e40e3889544375af58a))\r\n* Fix log sse endpoint ([fd6f0e2](https://github.com/Hypfer/Valetudo/commit/fd6f0e2d34ebc2f9de4aa5b23da2fa8ec2e4d630)), closes [#1256](https://github.com/Hypfer/Valetudo/issues/1256)\r\n* **mqtt:** Fix unit_of_measurement for current statistics and consumables ([7f052dc](https://github.com/Hypfer/Valetudo/commit/7f052dc3f64905afd69e35de217cd390377e6ce2))\r\n* **ntpClient:** Delay initial ntp sync to wait for valetudo to start up properly ([727af04](https://github.com/Hypfer/Valetudo/commit/727af04ab54d007c21a3c6ac270036611280e112))\r\n* **ui:** AppBar and menu should not be user-selectable ([69754b7](https://github.com/Hypfer/Valetudo/commit/69754b7204efe81ba147539a04630d644d0e07f4))\r\n* **ui:** Cleanup unused code ([c050940](https://github.com/Hypfer/Valetudo/commit/c05094011540c46737e7829532a319756255b2f3))\r\n* **ui:** Fix map zoom behavior for trackpoint and trackpad scroll zoom ([ca94600](https://github.com/Hypfer/Valetudo/commit/ca9460095eb6e4946f7653328667e8df60c678dc))\r\n* **ui:** Updater changelog should stay in its constraints ([5d815bf](https://github.com/Hypfer/Valetudo/commit/5d815bf98f334b9f40faecaf00f918bb6fecaacb))\r\n* **updater:** Ensure that there is enough space besides process.argv0 to store the new binary ([c298e98](https://github.com/Hypfer/Valetudo/commit/c298e9833cc6dcb2457a52b986daa8f2e81a8850))\r\n* **vendor.dreame:** Fix wrong segment iteration count ([9fd9c17](https://github.com/Hypfer/Valetudo/commit/9fd9c1723e0329b76b89e84cca108cc117a2a736))\r\n* **vendor.dreame:** There are actually no firmware limits for virtual restrictions ([8a8b536](https://github.com/Hypfer/Valetudo/commit/8a8b536b2eb126b9604b58e58cf196824da63be1))\r\n* **vendor.roborock:** Fix resetting incomplete map on Roborock. Detect and reset current map slot. ([#1252](https://github.com/Hypfer/Valetudo/issues/1252)) ([ba86057](https://github.com/Hypfer/Valetudo/commit/ba86057ba7946ee90c6ee7408ca446de56d23136))\r\n* Fix CurrentStatistics UI refresh ([93249ad](https://github.com/Hypfer/Valetudo/commit/93249ad142d4879ea967898f26905645af1c4f2b))\r\n* **ui:** Fix LogViewer overflow-wrap ([4799027](https://github.com/Hypfer/Valetudo/commit/4799027a42e6f5216cb748c75b88b1291a863335))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1267", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54959037/reactions", + "total_count": 5, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 4, + "rocket": 1, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54654293", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54654293/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/54654293/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.12.0", + "id": 54654293, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DQfVV", + "tag_name": "2021.12.0", + "target_commitish": "master", + "name": "Valetudo 2021.12.0", + "draft": false, + "prerelease": true, + "created_at": "2021-12-05T11:20:47Z", + "published_at": "2021-12-05T11:33:26Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51048888", + "id": 51048888, + "node_id": "RA_kwDOCGKICM4DCvG4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34173355, + "download_count": 311, + "created_at": "2021-12-05T11:39:58Z", + "updated_at": "2021-12-05T11:39:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049177", + "id": 51049177, + "node_id": "RA_kwDOCGKICM4DCvLZ", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13854315, + "download_count": 5, + "created_at": "2021-12-05T11:47:57Z", + "updated_at": "2021-12-05T11:47:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51048882", + "id": 51048882, + "node_id": "RA_kwDOCGKICM4DCvGy", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015327, + "download_count": 1286, + "created_at": "2021-12-05T11:39:55Z", + "updated_at": "2021-12-05T11:39:56Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51048887", + "id": 51048887, + "node_id": "RA_kwDOCGKICM4DCvG3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32015327, + "download_count": 290, + "created_at": "2021-12-05T11:39:57Z", + "updated_at": "2021-12-05T11:39:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049176", + "id": 51049176, + "node_id": "RA_kwDOCGKICM4DCvLY", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13270047, + "download_count": 15, + "created_at": "2021-12-05T11:47:56Z", + "updated_at": "2021-12-05T11:47:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049175", + "id": 51049175, + "node_id": "RA_kwDOCGKICM4DCvLX", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13269623, + "download_count": 18, + "created_at": "2021-12-05T11:47:55Z", + "updated_at": "2021-12-05T11:47:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/51049178", + "id": 51049178, + "node_id": "RA_kwDOCGKICM4DCvLa", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1802, + "created_at": "2021-12-05T11:47:59Z", + "updated_at": "2021-12-05T11:47:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.12.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.12.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.12.0", + "body": "
\r\n \"valetudo\"\r\n

2021.12.0

\r\n
\r\n\r\nMap data format changes, quality of life improvements and bugfixes.\r\n\r\n## Map data format changes\r\n\r\nThis release features the first version increment of the ValetudoMap data format.\r\nInitially, in version 1, pixel data such as walls or floor were stored as a huge array of coordinate pairs: \r\n`[x0, y0, x1, y1, ...]`. This was not a very efficient way of storing that data as most of it is redundant.\r\n\r\nThis resulted in map files that were over 1 MiB in size being pushed to your browser every 3 seconds.\r\n\r\nTo combat this, some thought was put into how the data is stored.\r\nIf you have a row of pixels, all of them will have the same y-coordinate, meaning that you only have to store that once.\r\nPeople already figured that out [in the 60s](https://en.wikipedia.org/wiki/Run-length_encoding).\r\n\r\nWith Map V2, pixels are stored as `[xStart0, y0, count0, xStart1, y1, count1, ...]` where `[xStart, y]` is the starting point and `count` represents additional pixels with the same y-coordinate to the right.\r\n\r\nThis resulted in V2 map files using between 5% and 15% of the size of the equivalent V1 map.\r\nThe huge testfile map for example was compressed from 847 kB to 75 kB.\r\n\r\n\r\nWhile this is a **breaking change**, the breakage actually isn't that big of a change as V2 can easily be converted back to V1.\r\nIn fact, running `JSON.parse()` on a V2 map and then converting it to a V1 one in memory is more than twice as fast as running `JSON.parse()` on a V1 map.\r\n\r\nSince this change drastically reduces the traffic caused by live maps, I expect to see general usability and reliability\r\nimprovements in situations where the Wi-Fi reception isn't that great.\r\n\r\n\r\n## LogViewer\r\n\r\nThe LogViewer has been greatly improved and now features a structured and color-coded view of your log.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744519-5ba963b9-6409-4e04-95d9-e73caf55021c.png)\r\n\r\nYou can use the text filter at the top to either filter for the loglevel or the message contents.\r\nJust start typing.\r\n\r\n## UI Help\r\n\r\nBoth consumables and timers now feature a help button, which shall explain how to use these features.\r\n\r\n[](https://user-images.githubusercontent.com/974410/144744625-d113d697-e4e1-4f77-a3a2-596ad88131a5.png)\r\n\r\n\r\n## Misc\r\n\r\n- Map reset on newer roborock models should now be fixed thanks to @supersmile2009\r\n- Zooming the map should now work much better if you zoom via a touchpad or trackpoint instead of a mousewheel\r\n- MQTT current statistics now have a unit_of_measurement in HA\r\n- Lowmem builds now have a reduced map poll rate to reduce memory pressure\r\n- Valetudo now manages its logfile size to prevent it from growing indefinitely\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Automatically clear the logfile when it gets too large ([c0698b4](https://github.com/Hypfer/Valetudo/commit/c0698b43dda5144d7d0c2c58d9336a1c0662cc65))\r\n* Reduce map polling interval for lowmem hosts ([fcf94ce](https://github.com/Hypfer/Valetudo/commit/fcf94ceeb60f9b46e25bfa04d2e4e88ac2a25926))\r\n* **ntpClient:** Improve log messages ([8880bbf](https://github.com/Hypfer/Valetudo/commit/8880bbfc7ed79969a61c6d6e51f7023c23d7561e))\r\n* **ui:** Add help button + modal to consumables view ([d1388f1](https://github.com/Hypfer/Valetudo/commit/d1388f124dae0046d2bee49345d0513441926f21))\r\n* **ui:** Add timers help ([c864170](https://github.com/Hypfer/Valetudo/commit/c864170d44c2b686394bb6d770cff937e8a9de43))\r\n* **ui:** Implement LogViewer component ([1b96ae0](https://github.com/Hypfer/Valetudo/commit/1b96ae06c8a74acbc9a6fa03cf941736520e30d0))\r\n* **ui:** Remove obsolete about > github release info ([253d9f9](https://github.com/Hypfer/Valetudo/commit/253d9f99b0965859705c52ffae9483c381d49ad7))\r\n* **ui:** Swap Manual control cw & ccw rotation button ([44eab06](https://github.com/Hypfer/Valetudo/commit/44eab06eadcd57c8c9b3784bc6f4c7a6dbea58e8))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Try avoiding bright flashes on initial loading ([f84a51d](https://github.com/Hypfer/Valetudo/commit/f84a51dc7c09ec4a7cb19e40e3889544375af58a))\r\n* Fix log sse endpoint ([fd6f0e2](https://github.com/Hypfer/Valetudo/commit/fd6f0e2d34ebc2f9de4aa5b23da2fa8ec2e4d630)), closes [#1256](https://github.com/Hypfer/Valetudo/issues/1256)\r\n* **mqtt:** Fix unit_of_measurement for current statistics and consumables ([7f052dc](https://github.com/Hypfer/Valetudo/commit/7f052dc3f64905afd69e35de217cd390377e6ce2))\r\n* **ntpClient:** Delay initial ntp sync to wait for valetudo to start up properly ([727af04](https://github.com/Hypfer/Valetudo/commit/727af04ab54d007c21a3c6ac270036611280e112))\r\n* **ui:** AppBar and menu should not be user-selectable ([69754b7](https://github.com/Hypfer/Valetudo/commit/69754b7204efe81ba147539a04630d644d0e07f4))\r\n* **ui:** Cleanup unused code ([c050940](https://github.com/Hypfer/Valetudo/commit/c05094011540c46737e7829532a319756255b2f3))\r\n* **ui:** Fix map zoom behavior for trackpoint and trackpad scroll zoom ([ca94600](https://github.com/Hypfer/Valetudo/commit/ca9460095eb6e4946f7653328667e8df60c678dc))\r\n* **ui:** Updater changelog should stay in its constraints ([5d815bf](https://github.com/Hypfer/Valetudo/commit/5d815bf98f334b9f40faecaf00f918bb6fecaacb))\r\n* **updater:** Ensure that there is enough space besides process.argv0 to store the new binary ([c298e98](https://github.com/Hypfer/Valetudo/commit/c298e9833cc6dcb2457a52b986daa8f2e81a8850))\r\n* **vendor.dreame:** Fix wrong segment iteration count ([9fd9c17](https://github.com/Hypfer/Valetudo/commit/9fd9c1723e0329b76b89e84cca108cc117a2a736))\r\n* **vendor.dreame:** There are actually no firmware limits for virtual restrictions ([8a8b536](https://github.com/Hypfer/Valetudo/commit/8a8b536b2eb126b9604b58e58cf196824da63be1))\r\n* **vendor.roborock:** Fix resetting incomplete map on Roborock. Detect and reset current map slot. ([#1252](https://github.com/Hypfer/Valetudo/issues/1252)) ([ba86057](https://github.com/Hypfer/Valetudo/commit/ba86057ba7946ee90c6ee7408ca446de56d23136))\r\n* Fix CurrentStatistics UI refresh ([93249ad](https://github.com/Hypfer/Valetudo/commit/93249ad142d4879ea967898f26905645af1c4f2b))\r\n* **ui:** Fix LogViewer overflow-wrap ([4799027](https://github.com/Hypfer/Valetudo/commit/4799027a42e6f5216cb748c75b88b1291a863335))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1259", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/54654293/reactions", + "total_count": 7, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 7, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/53791376/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.11.1", + "id": 53791376, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DNMqQ", + "tag_name": "2021.11.1", + "target_commitish": "master", + "name": "Valetudo 2021.11.1", + "draft": false, + "prerelease": false, + "created_at": "2021-11-21T11:30:14Z", + "published_at": "2021-11-21T11:43:51Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49967993", + "id": 49967993, + "node_id": "RA_kwDOCGKICM4C-nN5", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34299417, + "download_count": 284, + "created_at": "2021-11-21T11:50:24Z", + "updated_at": "2021-11-21T11:50:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968319", + "id": 49968319, + "node_id": "RA_kwDOCGKICM4C-nS_", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13979369, + "download_count": 8, + "created_at": "2021-11-21T11:58:19Z", + "updated_at": "2021-11-21T11:58:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49967989", + "id": 49967989, + "node_id": "RA_kwDOCGKICM4C-nN1", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32141389, + "download_count": 1274, + "created_at": "2021-11-21T11:50:18Z", + "updated_at": "2021-11-21T11:50:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49967991", + "id": 49967991, + "node_id": "RA_kwDOCGKICM4C-nN3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32141389, + "download_count": 322, + "created_at": "2021-11-21T11:50:20Z", + "updated_at": "2021-11-21T11:50:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968318", + "id": 49968318, + "node_id": "RA_kwDOCGKICM4C-nS-", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13396701, + "download_count": 15, + "created_at": "2021-11-21T11:58:18Z", + "updated_at": "2021-11-21T11:58:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968317", + "id": 49968317, + "node_id": "RA_kwDOCGKICM4C-nS9", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13396869, + "download_count": 14, + "created_at": "2021-11-21T11:58:17Z", + "updated_at": "2021-11-21T11:58:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/49968320", + "id": 49968320, + "node_id": "RA_kwDOCGKICM4C-nTA", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 1654, + "created_at": "2021-11-21T11:58:21Z", + "updated_at": "2021-11-21T11:58:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.1/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.11.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.11.1", + "body": "
\r\n \"valetudo\"\r\n

2021.11.1

\r\n
\r\n\r\nBugfixes, polishing, two minor breaking changes and new features.\r\nDon't forget: If you're running Valetudo 2021.11.0, you can now use the integrated updater :)\r\n\r\n## UI\r\n\r\n### Polishing\r\n\r\n- Controls in the UI were slightly rearranged/reworked.\r\n- The mobile controls drawer now works slightly different and more importantly more reliably with better performance (+ 50kb less bundle size).\r\n- There's a neat loading splashscreen, which you should only see for longer than a second if your Wi-Fi sucks\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760316-4af4fd83-79dd-4c42-857f-fa71ef2d2bc2.png) ![image](https://user-images.githubusercontent.com/974410/142760318-2b74c894-0572-4a55-8c71-6a655660f081.png)\r\n\r\n\r\n### Provisioning\r\n\r\nThe UI now checks if the robot is connected to a Wi-Fi network and if not opens a special provisioning page.\r\nIt's pretty neat and also fixes the issue of Dreames not being provisionable with the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760331-ee5a4031-c692-49be-9ad8-4144f35bb5e0.png)\r\n\r\n\r\n## Backend\r\n\r\n### CurrentStatisticsCapability\r\n\r\nStatistics related to the current (or most recent) operation of the robot are now back.\r\nYes, they are also being published to MQTT. Stop asking.\r\n\r\nData is published to MQTT as machine-readable (seconds for runtime, cm² for the area) as it is meant to build automations with it.\r\nUsing cm² instead of m² saves us from having to deal with floats.\r\n\r\n### TotalStatisticsCapability\r\n\r\nMore importantly, you can now get total statistics from your robot. \r\n\r\nDepending on your model those can be\r\n\r\n- Total operation count\r\n- Total runtime\r\n- Total area\r\n\r\nThis isn't available via the UI yet as it is yet TBD how to do that.\r\nMaybe have like badges, achievements or a rank system?\r\nMaybe have random trivia related to the numbers? (e.g. having cleaned 0.0001% of the Saarland)\r\n\r\nFeel free to leave your input in the comments. ~~Like, subscribe and click the bell icon~~\r\nIf you're good with graphics design, something like e.g. a Corporal IV vacuum robot badge would be a great contribution.\r\n\r\n## Zeroconf hostname changes\r\n\r\nBy actually reading the relevant RFCs, we've discovered that `valetudo_something.local` is not a valid bonjour hostname as the `_` is illegal.\r\nWhile it does seem to work in most setups, it might cause problems in some, which is why starting with this release, Valetudo will use an RFC-compliant hostname: `valetudo-something.local`.\r\n\r\nPlease **update your bookmarks** if you were using any.\r\n\r\n\r\n## MQTT\r\n\r\n### Home Assistant 2021.11 MQTT Changes\r\n\r\nValetudo 2021.11.1 makes use of new features introduced in Home Assistant 2021.11 (namely `configuration_url` and `entity_category`).\r\nThis means that **Home Assistant >= 2021.11 is now required** if you want to use it with Valetudo.\r\n\r\nYou might also have to delete your Valetudo device in HA and let it get rediscovered so that the changes are applied properly.\r\n\r\nIt now looks like this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/142760339-aa5b2314-692d-4167-9689-cec21f718924.png)\r\n\r\n\r\n### Possible MQTT OOM fixes\r\n\r\nWe have received unconfirmed, unsubstantiated and possibly falsified reports of Valetudo going OOM related to Wi-Fi connectivity issues and the MQTT interface.\r\n\r\nTo combat this, Valetudo now drops any outgoing MQTT message if there are more than 1 MiB of outgoing messages buffered. This may or may not ever happen.\r\nIf you see a warning in your log related to this, please report back. I have not been able to reproduce this.\r\n\r\n### Homie Consumables\r\n\r\nHome consumable durations are now reported as an int. This should fix issues with OpenHab.\r\n\r\n## Bugfixes\r\n\r\n### Dreame paths\r\n\r\nDreame paths now parse to multiple path map entities instead of a single one, which fixes the visual with lines going straight across the map connecting the previous path to the next one.\r\nConsumers of the Valetudo map data might have to be updated to properly display multiple path entities.\r\n\r\n### 1C-related fixes\r\n\r\nI've bought a Dreame 1C to do some QA, which led to a few fixes.\r\nI'm now quite happy with the current state of its implementation in Valetudo.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** CurrentStatisticsCapability ([8e4e183](https://github.com/Hypfer/Valetudo/commit/8e4e1839c217cc081f3172f227e935c2dc616bf1))\r\n* **core:** CurrentStatisticsCapability & TotalStatisticsCapability properties ([4fc9df2](https://github.com/Hypfer/Valetudo/commit/4fc9df271af4dbb9a9c1841d5f23a292d8cd0af3))\r\n* **core:** Introduce ConsumableMonitoringCapability properties and remove mqtt consumables hack ([a998ee1](https://github.com/Hypfer/Valetudo/commit/a998ee1eeeba2fd808c797bed719933d85922252))\r\n* **core:** TotalStatisticsCapability ([55b6696](https://github.com/Hypfer/Valetudo/commit/55b6696ecfb7f6d86b34da2e9e37b07287f8ef68))\r\n* **MockRobot:** Add MockCurrentStatisticsCapability + fix MockConsumableMonitoringCapability ([bda0b1a](https://github.com/Hypfer/Valetudo/commit/bda0b1adc54c8b651a3d23db8a4dc4638b460e48))\r\n* **mqtt:** Homie consumables should always be int ([c39ad93](https://github.com/Hypfer/Valetudo/commit/c39ad9380fc1d4cf752a3d95f0f57512e608c64f))\r\n* **mqtt:** Limit outgoing message buffer size to prevent OOM situations ([1a74f91](https://github.com/Hypfer/Valetudo/commit/1a74f9114de877f01b728e281b843e8459100b0f))\r\n* **mqtt:** Publish current statistics to mqtt ([102a078](https://github.com/Hypfer/Valetudo/commit/102a07890fe0a13efbda8b568b177fa4940478be))\r\n* **ui:** Add Valetudo loading splash ([a7ca33c](https://github.com/Hypfer/Valetudo/commit/a7ca33c845fa1e32d1a217115e48cd534c38b7bb))\r\n* **ui:** Collapse preset selection controls ([4f8aaec](https://github.com/Hypfer/Valetudo/commit/4f8aaec2f43b9e1a3bb21df88083b80509652fde))\r\n* **ui:** Display current statistics ([0fbc182](https://github.com/Hypfer/Valetudo/commit/0fbc182b0998cf1b3804b52ef24ee5d2d14c1b21))\r\n* **ui:** Slightly decrease required zoom level for segment label text ([08209a3](https://github.com/Hypfer/Valetudo/commit/08209a3164156db6e5e3ba340342bfbbf75bd7e3))\r\n* **vendor.dreame:** Total and current statistics for the 1C ([c1a51e9](https://github.com/Hypfer/Valetudo/commit/c1a51e916a9d123fcd6f9621eff02b645f79d702))\r\n* Provision Wizard thingy ([a6f6ded](https://github.com/Hypfer/Valetudo/commit/a6f6dedc851d6852e7b25ba1dc5222f3130ef210))\r\n* **ui:** Reorder state display ([828e54d](https://github.com/Hypfer/Valetudo/commit/828e54da624d2e00f500499e3497867fdb2ad6eb))\r\n* **ui:** Replace bottom sheet with simpler mobile controls ([17ff7ec](https://github.com/Hypfer/Valetudo/commit/17ff7ecb1105d9904f382a15b92dd5a6b988dd1f))\r\n* **vendor.dreame:** DreameCurrentStatisticsCapability ([656a19e](https://github.com/Hypfer/Valetudo/commit/656a19ee39f1411bb962e61077486d9336dd79b5))\r\n* **vendor.dreame:** DreameTotalStatisticsCapability ([4bb9342](https://github.com/Hypfer/Valetudo/commit/4bb934208ff52ad7fc1f42b82e5046362353ab6a))\r\n* **vendor.roborock:** RoborockCurrentStatisticsCapability ([93aa77b](https://github.com/Hypfer/Valetudo/commit/93aa77b09b7924baf5fce594d6455f4a5f51837e))\r\n* **vendor.roborock:** RoborockKeyLockCapability ([#1222](https://github.com/Hypfer/Valetudo/issues/1222)) ([02e155c](https://github.com/Hypfer/Valetudo/commit/02e155cec954cc75e41c5fcbf8ebe37acffb4c37))\r\n* **vendor.roborock:** RoborockTotalStatisticsCapability ([e0cbbff](https://github.com/Hypfer/Valetudo/commit/e0cbbff7470426119dd1eff6bde064a9387209b5))\r\n* **vendor.viomi:** ViomiCurrentStatisticsCapability ([9dd1091](https://github.com/Hypfer/Valetudo/commit/9dd1091cbc7a63ac7c0f61b40bc73abd026572bc))\r\n* **webserver:** Add 404 page ([8f5095c](https://github.com/Hypfer/Valetudo/commit/8f5095cac124c0ee0a6b8cdece07223c3374c51f))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Attempt to mitigate problems related to connectivity issues ([cf0f2d6](https://github.com/Hypfer/Valetudo/commit/cf0f2d691017ac69635d17f04062c260ebf62091))\r\n* **mqtt:** homie.durationsAsInteger should not be a breaking change ([bbd918a](https://github.com/Hypfer/Valetudo/commit/bbd918ac35530c0a7a8e8b684ebbe05967506bfc))\r\n* **ui:** Align preset selection labels with icons ([c6803f6](https://github.com/Hypfer/Valetudo/commit/c6803f6e2d5a60172d945bd62ab47badd679d234))\r\n* **ui:** Attachment buttons should be disabled ([922572a](https://github.com/Hypfer/Valetudo/commit/922572a779e0e1402ca53bb3e9b8a1c82605ea70))\r\n* **ui:** Fix CurrentStatistics trying to map something that isn't an array ([4d6f3d8](https://github.com/Hypfer/Valetudo/commit/4d6f3d869202288fb48bc50ee38d124c611fac78))\r\n* **ui:** Fix mobile control scrolling ([6264400](https://github.com/Hypfer/Valetudo/commit/6264400a473b36aff9f5409a5e157de536389e6d))\r\n* **ui:** Only check for provisioning once ([6bd0480](https://github.com/Hypfer/Valetudo/commit/6bd0480d8d40600aa5f438d060a21b2ba775925a))\r\n* **ui:** Only regular mouse clicks should interact with the map ([d452d88](https://github.com/Hypfer/Valetudo/commit/d452d88206afafbf4017138fa8b52edd38f1f70d))\r\n* **ui:** Preset selection labels should not be user selectable ([965a061](https://github.com/Hypfer/Valetudo/commit/965a0610c2dd73e028f944ed3a49a5e3c507d7e6))\r\n* **ui:** Swap presetSelection open/close icons ([380109b](https://github.com/Hypfer/Valetudo/commit/380109baa7bc6abfb06169eaeac036a7235af005))\r\n* **ui:** The whole controls body should not be user-selectable ([861f15f](https://github.com/Hypfer/Valetudo/commit/861f15f6da3633c266f0fbca8471193642b8ae57))\r\n* **vendor.dreame:** 1C shall ignore persistent map property updates ([5744346](https://github.com/Hypfer/Valetudo/commit/5744346272bf443ca734da77c5af938a559d314b))\r\n* **vendor.dreame:** Assume that we're in the docked state if we're charging on the 1C ([c73e062](https://github.com/Hypfer/Valetudo/commit/c73e06207c098deae3e596de135c5e2cbf50f4da))\r\n* **vendor.dreame:** Fine-tune 1C manual control ([72614e2](https://github.com/Hypfer/Valetudo/commit/72614e29977297078cf37425be361ad5310aad07))\r\n* **vendor.dreame:** Fine-tune manual control ([cc267c7](https://github.com/Hypfer/Valetudo/commit/cc267c75fe02178343cbddd43099ff59cfe8b16f))\r\n* **vendor.dreame:** Fix Dreame1CManualControlCapability ([9c85ca5](https://github.com/Hypfer/Valetudo/commit/9c85ca5f8c09dc5e1371f4b805767a6bec54175c))\r\n* **vendor.dreame:** Properly parse path data to multiple paths ([e083af2](https://github.com/Hypfer/Valetudo/commit/e083af2759f37706cda1e45a0b083b0782112f3b))\r\n* **vendor.dreame:** Remove capabilities for models that don't support them ([0d6d6ad](https://github.com/Hypfer/Valetudo/commit/0d6d6ad3ad44bdadb9ceea830652e8e742487776))\r\n* **vendor.dreame:** The 1C does not support multiple iterations for segment cleanups ([2d35bd9](https://github.com/Hypfer/Valetudo/commit/2d35bd9a0f00f52f9e0a67dae5f31d50e7a87cb3))\r\n* **vendor.viomi:** Fix ViomiPersistentMapControlCapability ([#1218](https://github.com/Hypfer/Valetudo/issues/1218)) ([80d7bb2](https://github.com/Hypfer/Valetudo/commit/80d7bb2bd91377d1c06a0c6afa4a262d0b7511e7))\r\n* Fix LinuxWifiConfigurationCapability not_connected state reporting ([25271f2](https://github.com/Hypfer/Valetudo/commit/25271f24c95976bae9b201ff1a6d2625c3e643a1))\r\n* **vendor.roborock:** RoborockSpeakerVolumeControlCapability.getVolume() should return a number ([32898d1](https://github.com/Hypfer/Valetudo/commit/32898d1cd27b3498f00e6dd4d67c2de09d0ec1ed))\r\n* **vendor.viomi:** Fix volume control ([0269182](https://github.com/Hypfer/Valetudo/commit/0269182f5e94d055d908b9c16e1524ef5a9f949d))\r\n* **webserver:** try/catch for SpeakerVolumeControlCapabilityRouter ([5cb7c5a](https://github.com/Hypfer/Valetudo/commit/5cb7c5ac3c09c9138ac11316aff3c7dcfa22fde1))\r\n* Nested assign configuration defaults + don't persist if there are no changes to persist ([b12c452](https://github.com/Hypfer/Valetudo/commit/b12c452b4d693326d0ebec81bf6b1145c8ca9de5))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1223", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/53791376/reactions", + "total_count": 11, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 10, + "confused": 0, + "heart": 1, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/51929111/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.11.0", + "id": 51929111, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DGGAX", + "tag_name": "2021.11.0", + "target_commitish": "master", + "name": "Valetudo 2021.11.0", + "draft": false, + "prerelease": false, + "created_at": "2021-10-24T11:34:45Z", + "published_at": "2021-10-24T11:41:55Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47746670", + "id": 47746670, + "node_id": "RA_kwDOCGKICM4C2I5u", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34461299, + "download_count": 254, + "created_at": "2021-10-24T11:48:38Z", + "updated_at": "2021-10-24T11:48:38Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747076", + "id": 47747076, + "node_id": "RA_kwDOCGKICM4C2JAE", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14141395, + "download_count": 12, + "created_at": "2021-10-24T11:56:41Z", + "updated_at": "2021-10-24T11:56:41Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47746666", + "id": 47746666, + "node_id": "RA_kwDOCGKICM4C2I5q", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32303271, + "download_count": 578, + "created_at": "2021-10-24T11:48:35Z", + "updated_at": "2021-10-24T11:48:36Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47746669", + "id": 47746669, + "node_id": "RA_kwDOCGKICM4C2I5t", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32303271, + "download_count": 346, + "created_at": "2021-10-24T11:48:36Z", + "updated_at": "2021-10-24T11:48:37Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747075", + "id": 47747075, + "node_id": "RA_kwDOCGKICM4C2JAD", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13557831, + "download_count": 19, + "created_at": "2021-10-24T11:56:40Z", + "updated_at": "2021-10-24T11:56:40Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747073", + "id": 47747073, + "node_id": "RA_kwDOCGKICM4C2JAB", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13558111, + "download_count": 17, + "created_at": "2021-10-24T11:56:39Z", + "updated_at": "2021-10-24T11:56:39Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47747077", + "id": 47747077, + "node_id": "RA_kwDOCGKICM4C2JAF", + "name": "valetudo_release_manifest.json", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 663, + "download_count": 46, + "created_at": "2021-10-24T11:56:43Z", + "updated_at": "2021-10-24T11:56:43Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.11.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.11.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.11.0", + "body": "
\r\n \"valetudo\"\r\n

2021.11.0

\r\n
\r\n\r\nLikely the most important release of the year.\r\n\r\n## Recap 0.6.1 to 2021.11.0\r\nApparently, Valetudo 0.6.1 was released only a bit more than a year ago, but tbh it feels like an eternity.\r\nSo much has changed since then. The iteration speed of the project has been insane in the last months.\r\nAs we've now finished most if not all of the huge tasks, I expect things to slow down a little.\r\n\r\nHere's a quick recap of what happened since 0.6.1:\r\n\r\n- Complete core rewrite to easily support multiple vendors and different robots\r\n- A proper REST-API documented with Swagger UI\r\n- Complete MQTT rewrite to support Home Assistant as well as Homie\r\n- Easy map display in Home Assistant via MQTT and the custom lovelace valetudo map card\r\n- Complete UI rewrite based on a proper UI framework\r\n- Support for all relevant features of the robots\r\n- Support for autodiscovery of Valetudo-enabled robots via mDNS and SSDP\r\n- Support for Dreame-made robots\r\n- An [android companion app](https://valetudo.cloud/pages/companion_apps/valetudo_companion.html) that makes use of said autodiscovery feature\r\n- [Valeronoi](https://valetudo.cloud/pages/companion_apps/valeronoi.html): A companion app that generates Wi-Fi signal strength maps using Valetudo\r\n- An updater functionality\r\n- [Proper docs](https://valetudo.cloud/)\r\n- General polishing. A lot of it\r\n\r\n\r\n## Default new UI\r\n\r\nStarting with this release, the new react-based UI introduced by @jomik with large contributions by @ccoors is now the default.\r\n\r\nThe existing map renderer was ported to react with a few quality of life improvements:\r\n\r\n- You can now specify an iteration count when cleaning segments or zones\r\n- Layers are now sorted, meaning that walls will always be on top. This solves some visual issues of vSlam-based devices\r\n- Adding a new zone/virtual wall/etc. will now spawn it in the middle of your viewport \r\n- Map segment labels now attempt to actually be inside the segment they're for. This fixes issues with cornered hallways. No more stray triangles\r\n- Editing the map will now refresh your current view instead of navigating back\r\n- Rendering has been partly moved to a webworker for improved performance\r\n\r\nSpeaking of navigating back: Given that the new UI is based on a frontend framework including proper routing,\r\nwe now have a working back button. Amazing!\r\n\r\nThe only thing not yet available in the new UI is management of Zone and GoTo presets. This will be added later.\r\nFor now, please navigate to the old UI via the menu and use that.\r\n\r\n\r\n### Screenshots\r\n\r\n#### Phone/Mobile\r\n![image](https://user-images.githubusercontent.com/974410/138561830-e0a3edf7-1974-49cf-90a8-31e677b482d2.png) ![image](https://user-images.githubusercontent.com/974410/138561931-41b68344-f260-4343-9c79-ef85e56d9786.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138561874-f5e5fee9-81dd-43fb-9de0-75263169a0e6.png) ![image](https://user-images.githubusercontent.com/974410/138561884-9633600b-3362-454b-b95d-90f8e5951971.png)\r\n\r\n\r\n#### Tablet/Desktop\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138562037-05bc5140-d7af-488b-8734-72e66b820192.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138561911-77aa8d10-3918-4eb7-96ff-8a6d0440dfce.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138562111-3cbfe03c-7a19-4e57-9bfb-6b872239f432.png)\r\n\r\n\r\n## Updater\r\n\r\nStarting with this release, Valetudo will be capable of updating itself with the press of a button.\r\n\r\nThis has been a long-requested feature and considering how mature this whole project has become, I decided that\r\nit was finally time to actually implement that.\r\nAs it is implemented now, it uses the GitHub API by default, meaning that I am not able to track you.\r\n\r\nThere's also no automatic update check, because periodical pings to some cloud service are obviously problematic.
\r\nYou will decide when to press the \"Check for Updates\" button and also when to update.\r\n\r\n## More stickers\r\n\r\nI've decided to get a few more stickers printed because merch\r\n\r\n![image](https://user-images.githubusercontent.com/974410/138592502-4c6d150e-ecde-46ea-9ce4-7da8fdb77431.png)\r\n\r\n## Misc\r\n\r\nI'm currently looking for a job that isn't a corporate hellhole with nice people doing interesting stuff.\r\nIf you're a likeminded hacker looking for a new colleague or know someone who does feel free to ping me\r\n\r\nThanks :)\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Add Valetudo logo to bottom sheet ([76eeaff](https://github.com/Hypfer/Valetudo/commit/76eeaffd4aa273e351d9306d4660df196380b275))\r\n* **ui:** Bring back the old map renderer ([7aa6822](https://github.com/Hypfer/Valetudo/commit/7aa6822e20ef026a73bcfebcf76c9bbd49ce2a94))\r\n* **ui:** Change map colors according to theme in use ([b17745e](https://github.com/Hypfer/Valetudo/commit/b17745e2ca70a9b24982f70cfc2272130cd1e9a4))\r\n* **ui:** Fan speed icon and battery level bar improvements ([d0a0671](https://github.com/Hypfer/Valetudo/commit/d0a06712315f0dc7b93fc35ee9f9270a9204df7e))\r\n* **ui:** Improve controls ([b678cda](https://github.com/Hypfer/Valetudo/commit/b678cdac0f2a15e1a3191f2125fbbaabbc7af833))\r\n* **ui:** Map Editing ([35feb65](https://github.com/Hypfer/Valetudo/commit/35feb654e76599d0c267ed118453f3c25e4b8fbd))\r\n* **ui:** Move locate to the map view ([32de2b8](https://github.com/Hypfer/Valetudo/commit/32de2b83daf1e03fa16b1115713a9290abc05029))\r\n* **ui:** Place new client structures in the middle of the viewport ([d9d2a64](https://github.com/Hypfer/Valetudo/commit/d9d2a6436bd6ea24dd431b24776c93587114cfba))\r\n* **ui:** Remove map transparency ([ace000b](https://github.com/Hypfer/Valetudo/commit/ace000b922a426076db49aaa25e1cbf4207b0ad8))\r\n* **ui:** Remove obsolete segment controls ([9912cf5](https://github.com/Hypfer/Valetudo/commit/9912cf58f60a6ca88517786bb9fc6afccf9a5cf0))\r\n* **updater:** Introduce ValetudoUpdaterNoUpdateRequiredState ([354028e](https://github.com/Hypfer/Valetudo/commit/354028e6f4f23e8c61a9f2e302edcaecf7807fe6))\r\n* Updater ([5db2c55](https://github.com/Hypfer/Valetudo/commit/5db2c554dc9905352c310f4be7d6130a26f7730c))\r\n* **ui:** Remove Accordion from interface settings ([c4c31bb](https://github.com/Hypfer/Valetudo/commit/c4c31bb5a68757a6ec687c3dde436f26374a2fdc))\r\n* **ui:** Set the new UI as the default ([c0f90fb](https://github.com/Hypfer/Valetudo/commit/c0f90fb90f44d7020db016cfe9129d80f8df7d56))\r\n* **ui:** Use a WebWorker for rendering the map layers when possible ([3eafded](https://github.com/Hypfer/Valetudo/commit/3eafded6c62a420795f6f910ca5b933f29a7e5f6))\r\n* **ui:** Use real swagger icon in sidebar ([#1160](https://github.com/Hypfer/Valetudo/issues/1160)) ([f4c0093](https://github.com/Hypfer/Valetudo/commit/f4c0093527be1ae3ce6fa298bd878b3cc5b1283c))\r\n* **ValetudoEvents:** Add Mop Attachment Reminder event ([ac268d7](https://github.com/Hypfer/Valetudo/commit/ac268d765f93c33aba14ad7ffd8602d00a02985e))\r\n* Add nonce to every instance of a Valetudo map ([f0489f1](https://github.com/Hypfer/Valetudo/commit/f0489f15260f8eb368bc6b759029a022781bebf9))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* Fix MopAttachmentReminderValetudoEvent not being a DismissibleValetudoEvent ([302f6ce](https://github.com/Hypfer/Valetudo/commit/302f6cefc3f155d45589ea1cf50ed39fc983b5d3))\r\n* **mqtt:** Fix consumable state attribute data being published multiple times ([894bba9](https://github.com/Hypfer/Valetudo/commit/894bba9c9b99a5b67f584dbaa9e1571ffa18812c))\r\n* **mqtt:** Fix zone cleanup ([#1130](https://github.com/Hypfer/Valetudo/issues/1130)) ([bb951b2](https://github.com/Hypfer/Valetudo/commit/bb951b2fcddb6435bfe6b838044cc2af7b0c235f))\r\n* **mqtt:** Hopefully avoid a deadlock ([c3313ea](https://github.com/Hypfer/Valetudo/commit/c3313eac738cf8d5dc1a05f3c60308e4b002dd3a))\r\n* **ui:** Allow more states for zone/segment cleanup and goto ([c738938](https://github.com/Hypfer/Valetudo/commit/c738938cc0d8140ce91011db8420df7a6768c893))\r\n* **ui:** Better placement of segment labels ([ba788a0](https://github.com/Hypfer/Valetudo/commit/ba788a0da1042106cac698e5de9f20d6e7bb89f5))\r\n* **ui:** Combinations of scrolling and touch events also should not cause any jank ([e36c40f](https://github.com/Hypfer/Valetudo/commit/e36c40f2a66a67baebd75da13ed8bb84cd26d371))\r\n* **ui:** Fix controls jumping around when there is a status flag ([c641fb1](https://github.com/Hypfer/Valetudo/commit/c641fb10e3bc2a7e56a9e6a388be1d479fb6c91b))\r\n* **ui:** Fix draw order for ControlsBottomSheet ([c46ef10](https://github.com/Hypfer/Valetudo/commit/c46ef10981298570bc14a7e9094698b70dd30e94))\r\n* **ui:** Fix SSE not reconnecting after having closed the connection once ([6feaaf8](https://github.com/Hypfer/Valetudo/commit/6feaaf807065f3e5d585c9f723e8b48f9aa32621))\r\n* **ui:** Further improve segment label placement using the median ([6545cc7](https://github.com/Hypfer/Valetudo/commit/6545cc7fb4077247b08675f8ea10895062996401))\r\n* **ui:** Ignore map updates if the tab is invisible ([370753d](https://github.com/Hypfer/Valetudo/commit/370753dcd5bb2dd1803d8dac67d3b96759dd94c3))\r\n* **ui:** MQTT port is an integer ([#1159](https://github.com/Hypfer/Valetudo/issues/1159)) ([5b91c96](https://github.com/Hypfer/Valetudo/commit/5b91c96eb8e2928be48b4ef63abbb7c043b34aa9))\r\n* **ui:** Postpone map data updates during pan/zoom to prevent jank ([92a9147](https://github.com/Hypfer/Valetudo/commit/92a9147191981b15d48e4817f7200875470a13fe))\r\n* **ui:** Postpone map data updates during scroll to prevent jank ([adcd117](https://github.com/Hypfer/Valetudo/commit/adcd1174a50b4bce4805da5a36bcf80646eb9979))\r\n* **ui:** Prevent issues with zooming on mobile ([a5057fd](https://github.com/Hypfer/Valetudo/commit/a5057fd7f4dd58b38628f5bbdd4ade951ca6b6fc))\r\n* **ui:** Use the correct canvas size for the map layer renderer ([b55ffa6](https://github.com/Hypfer/Valetudo/commit/b55ffa6cc56d7c7d6bb0c8459ccd1d35252c3b63))\r\n* **ui:** Zone dimensions should be based on the pixelSize ([b317c85](https://github.com/Hypfer/Valetudo/commit/b317c856dbdfe95ab45ea639223d23fca093c464))\r\n* **updater:** Fix fallback download location for roborock ([d515f04](https://github.com/Hypfer/Valetudo/commit/d515f04e5f6695b71567f6818ba2734553c75d03))\r\n* **vendor.dreame:** Fix virtual restriction coordinates being not sorted properly ([17cc303](https://github.com/Hypfer/Valetudo/commit/17cc303cf4726cf4bcbb9597c268273896b52c78))\r\n* **vendor.dreame:** Ignore error 68 ([dd44320](https://github.com/Hypfer/Valetudo/commit/dd44320a390c42f6e36a301931e5006e103a4684))\r\n* **webserver:** Allow unsetting names of segments ([f992e5a](https://github.com/Hypfer/Valetudo/commit/f992e5adce4c4fd997ff4a6c868f95d32a5e214b))\r\n* Use shorter model names ([d268013](https://github.com/Hypfer/Valetudo/commit/d268013b9c93b4dc610cb8374a3316d9e2a842a9))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1175", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/51929111/reactions", + "total_count": 47, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 29, + "confused": 0, + "heart": 18, + "rocket": 0, + "eyes": 0 + }, + "mentions_count": 2 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/50662403/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.10.0", + "id": 50662403, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4DBQwD", + "tag_name": "2021.10.0", + "target_commitish": "master", + "name": "Valetudo 2021.10.0", + "draft": false, + "prerelease": false, + "created_at": "2021-10-01T21:19:25Z", + "published_at": "2021-10-01T21:25:10Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46053587", + "id": 46053587, + "node_id": "RA_kwDOCGKICM4CvrjT", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34522555, + "download_count": 269, + "created_at": "2021-10-01T21:33:32Z", + "updated_at": "2021-10-01T21:33:34Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46054033", + "id": 46054033, + "node_id": "RA_kwDOCGKICM4CvrqR", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 14203219, + "download_count": 12, + "created_at": "2021-10-01T21:42:35Z", + "updated_at": "2021-10-01T21:42:37Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46053583", + "id": 46053583, + "node_id": "RA_kwDOCGKICM4CvrjP", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32364527, + "download_count": 420, + "created_at": "2021-10-01T21:33:27Z", + "updated_at": "2021-10-01T21:33:29Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46053586", + "id": 46053586, + "node_id": "RA_kwDOCGKICM4CvrjS", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32364527, + "download_count": 278, + "created_at": "2021-10-01T21:33:30Z", + "updated_at": "2021-10-01T21:33:31Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46054032", + "id": 46054032, + "node_id": "RA_kwDOCGKICM4CvrqQ", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13619079, + "download_count": 23, + "created_at": "2021-10-01T21:42:34Z", + "updated_at": "2021-10-01T21:42:35Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/46054031", + "id": 46054031, + "node_id": "RA_kwDOCGKICM4CvrqP", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13619623, + "download_count": 20, + "created_at": "2021-10-01T21:42:32Z", + "updated_at": "2021-10-01T21:42:33Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo-armv7.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/47462841", + "id": 47462841, + "node_id": "RA_kwDOCGKICM4C1Dm5", + "name": "valetudo_release_manifest.json", + "label": null, + "uploader": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "content_type": "application/json", + "state": "uploaded", + "size": 559, + "download_count": 14, + "created_at": "2021-10-20T17:57:24Z", + "updated_at": "2021-10-20T17:57:32Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.10.0/valetudo_release_manifest.json" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.10.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.10.0", + "body": "
\r\n \"valetudo\"\r\n

2021.10.0

\r\n
\r\n\r\nAnother release with a lot of UI changes by @ccoors. Also, there's an Android companion App now.\r\n\r\n## Android Companion App\r\n\r\nThanks to the help of @TheLastProject who had built the first prototype in less than 18h after initially mentioning the idea on the telegram group, there's now an Android Companion App for Valetudo.\r\n\r\nDon't worry, it is completely optional. All it does and aims to do is to find Valetudo instances on your network via Bonjour and help you with the provisioning (configuring Wi-Fi) process of new robots with Valetudo installed.\r\nThis can be helpful for example if you were to give your non-linux-skilled parents a rooted robot for Christmas or whatever.\r\n\r\nIt's available on F-Droid and Google Play and of course open source.\r\n\r\nFor more information, please check out [the docs](https://valetudo.cloud/pages/companion_apps/valetudo_companion.html).\r\n\r\n[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-02.png)[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-03.png)[](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png)\r\n\r\n\r\n## UI Changes\r\n\r\n@ccoors provided very nice previews displaying their changes in each PR, which is why I will just copy-paste them here for your convenience.\r\nAlso, I'm lazy\r\n\r\n\"wifi\r\n\r\n\"voice\"manual\r\n\r\n\"more\r\n\r\n\r\n## Logo Cleanup\r\n\r\nAs you might've noticed, the logo slightly changed.\r\nThis avoids the bug in some people, which made them read it as *aletudo* when looking at it.\r\n\r\n## Valetudog\r\n\r\nThe thing from the telegram group finally got a name: Valetudog\r\nIt's now some kind of mascot I guess.\r\n\r\n\"valetudog\"\r\n\r\nI also bought a lot of stickers of it\r\n\r\n![image](https://user-images.githubusercontent.com/974410/135687512-e49f8bae-97ab-4d5c-bb8b-ba989eea1518.png)\r\n\r\nUnfortunately, I have no idea what to do with them.\r\nThey did turn out quite nice though.\r\n\r\n## Zoned Cleanup MQTT changes\r\n\r\nStarting with this release, it's no longer possible to clean multiple zone presets at once via MQTT.\r\nThat should've never been possible in the first place since it's conceptually wrong as you can only call a single preset at a time. Sorry about that.\r\n\r\nNote that this is a **breaking change** and will require updating of e.g. your Home Assistant automations.\r\nInstead of an array, you now have to send just the preset ID as a string.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Consumables bottom view sensors ([#1104](https://github.com/Hypfer/Valetudo/issues/1104)) ([2f83d8e](https://github.com/Hypfer/Valetudo/commit/2f83d8ea02aaefde8f132909071ca9bf7367de74))\r\n* **ui:** DoNotDisturb configuration & Masonry on large screens ([#1112](https://github.com/Hypfer/Valetudo/issues/1112)) ([935f903](https://github.com/Hypfer/Valetudo/commit/935f903981ad5f98e9224cae143396b353a195db))\r\n* **ui:** HTTP Basic Auth and NTP client config ([#1118](https://github.com/Hypfer/Valetudo/issues/1118)) ([2371878](https://github.com/Hypfer/Valetudo/commit/2371878cd48e19b57fce61b4200d76a1cc30257b))\r\n* **ui:** Manage voice packs ([#1108](https://github.com/Hypfer/Valetudo/issues/1108)) ([0d02c27](https://github.com/Hypfer/Valetudo/commit/0d02c278edaf1ea60810990455b33175b957acc7))\r\n* **ui:** Manual control ([#1114](https://github.com/Hypfer/Valetudo/issues/1114)) ([7e9ef04](https://github.com/Hypfer/Valetudo/commit/7e9ef04b2fa5d8fb4d5f7e8d3fa88366592873ea))\r\n* **ui:** Robot settings ([#1097](https://github.com/Hypfer/Valetudo/issues/1097)) ([4b43b37](https://github.com/Hypfer/Valetudo/commit/4b43b370663ca44f03d82ba828026169075d670c))\r\n* **ui:** Wifi configuration ([#1116](https://github.com/Hypfer/Valetudo/issues/1116)) ([3e71184](https://github.com/Hypfer/Valetudo/commit/3e7118414b6b190750e3f606c93e1b052d78b898))\r\n* **vendor.dreame:** Add Dreame D9 Pro ([cc50a8c](https://github.com/Hypfer/Valetudo/commit/cc50a8c6e4cab7a04c68ca61d21e59e15a3a59cb))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix MQTT Zone cleanup ([fdabcc5](https://github.com/Hypfer/Valetudo/commit/fdabcc52be3553f01648997ec714133e27a6e7cc))\r\n* **ui:** Allow start and home basic commands on error state ([5fd0354](https://github.com/Hypfer/Valetudo/commit/5fd0354eabd91aa50cc42120bdabdf6947aaf604))\r\n* **ui:** Blue line between buttons in PendingMapChangeEventControl ([196a29e](https://github.com/Hypfer/Valetudo/commit/196a29e1549ffd46fddcd78c7c8bee9b2d1e8c21))\r\n* **ui:** Fix mobile Icons in new frontend ([#1113](https://github.com/Hypfer/Valetudo/issues/1113)) ([313caa1](https://github.com/Hypfer/Valetudo/commit/313caa10ea0a246ea05dd4ba3fca83e374e75cdc))\r\n* **ui:** Import ToggleButton from core ([da0cce5](https://github.com/Hypfer/Valetudo/commit/da0cce588eee9c6065bb2ad4f2890b19cd8c5e59))\r\n* **ui:** RatioBar background color ([c00d174](https://github.com/Hypfer/Valetudo/commit/c00d1749c26bec217a60a529166c5f8bf6de3dba))\r\n* **ui:** Remove persistent data hint ([6777f3a](https://github.com/Hypfer/Valetudo/commit/6777f3aa7bbf4ef5afea5a3ba8fdecd2aa8f150e))\r\n* **ui:** repair light mode ([#1103](https://github.com/Hypfer/Valetudo/issues/1103)) ([842aea1](https://github.com/Hypfer/Valetudo/commit/842aea125b97a33adbf28c3b0c9d1cf84c069943))\r\n* **ui:** Root grid height ([957463a](https://github.com/Hypfer/Valetudo/commit/957463a9de34e4e7c3fafe5d94fdd6360b4a2f88))\r\n* **ui:** Root grid height ([1d9a244](https://github.com/Hypfer/Valetudo/commit/1d9a244412b235ed2da71d594cb77d00fd9eae45))\r\n* **ui:** Stop events badge flashing when it reloads ([#1115](https://github.com/Hypfer/Valetudo/issues/1115)) ([007926b](https://github.com/Hypfer/Valetudo/commit/007926b90881664e9b0c718e7c3ef21ad306e233))\r\n* **webserver:** Fix reflected xss vulnerability ([36a3bae](https://github.com/Hypfer/Valetudo/commit/36a3bae630dfc84c6a2e610ef35e93a002470857))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1119", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/50662403/reactions", + "total_count": 16, + "+1": 0, + "-1": 0, + "laugh": 5, + "hooray": 2, + "confused": 0, + "heart": 0, + "rocket": 9, + "eyes": 0 + }, + "mentions_count": 2 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/49812967/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.09.1", + "id": 49812967, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4C-BXn", + "tag_name": "2021.09.1", + "target_commitish": "master", + "name": "Valetudo 2021.09.1", + "draft": false, + "prerelease": false, + "created_at": "2021-09-19T12:08:23Z", + "published_at": "2021-09-19T12:23:58Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138012", + "id": 45138012, + "node_id": "RA_kwDOCGKICM4CsMBc", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33923724, + "download_count": 145, + "created_at": "2021-09-19T12:31:14Z", + "updated_at": "2021-09-19T12:31:16Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138227", + "id": 45138227, + "node_id": "RA_kwDOCGKICM4CsMEz", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13400596, + "download_count": 7, + "created_at": "2021-09-19T12:39:08Z", + "updated_at": "2021-09-19T12:39:09Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138010", + "id": 45138010, + "node_id": "RA_kwDOCGKICM4CsMBa", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31676240, + "download_count": 287, + "created_at": "2021-09-19T12:31:09Z", + "updated_at": "2021-09-19T12:31:11Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138011", + "id": 45138011, + "node_id": "RA_kwDOCGKICM4CsMBb", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31676240, + "download_count": 206, + "created_at": "2021-09-19T12:31:12Z", + "updated_at": "2021-09-19T12:31:13Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138226", + "id": 45138226, + "node_id": "RA_kwDOCGKICM4CsMEy", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12774444, + "download_count": 9, + "created_at": "2021-09-19T12:39:06Z", + "updated_at": "2021-09-19T12:39:07Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/45138225", + "id": 45138225, + "node_id": "RA_kwDOCGKICM4CsMEx", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12773924, + "download_count": 9, + "created_at": "2021-09-19T12:39:05Z", + "updated_at": "2021-09-19T12:39:06Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.1/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.09.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.09.1", + "body": "
\r\n \"valetudo\"\r\n

2021.09.1

\r\n
\r\n\r\nThis release is packed with UI improvements thanks to @ccoors\r\n\r\n## Event UI\r\n\r\nThe new UI now subscribes to the ValetudoEvents endpoint and allows for interaction with them.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927122-054ed31b-7a47-447f-9193-6e92ca64757b.png)\r\n\r\nThis is helpful as they might contain errors that you've missed.\r\nAlso, your robot might require confirmation from you to store a new map so make sure to keep an eye on that.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927125-d069022e-8a18-4bd3-b879-734a4f9aba96.png)\r\n\r\n\r\n## Timer UI\r\n\r\nYou can now use the new UI to set up ValetudoTimers.\r\n\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927153-e109c4a5-2bff-45e7-af07-2ae7a4eb9ace.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927151-76b2daa1-9e26-4b6d-a2e1-ba20c97e9829.png)\r\n\r\nNote that timers are always stored and evaluated as UTC. The local time display is simply a convenience feature.\r\n\r\n## MQTT config UI\r\n\r\nMQTT configuration can now also be done via the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927206-8a4188a8-d178-46fb-9c2d-32907322f5f9.png)\r\n\r\nIt features a nice topic preview to make it easier for newcomers to interact with Valetudo via MQTT.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927215-e359d45a-c76e-47bb-a178-d1118cca25bc.png)\r\n\r\nAlso, the API will no longer return any MQTT credentials but instead replace them with `` for security reasons.\r\n\r\n## Logviewer UI\r\n\r\nA basic log viewer has been added to the new UI. While still WIP, it already allows for live updates as well as filtering, which is a neat improvement.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927245-d4f98b09-0cc4-448d-9752-f939987f9e3c.png)\r\n\r\n\r\n## Auto-empty Dock related features\r\n\r\nIf you own a Dreame Z10, you're now able to enable/disable the automatic dust collection via the Swagger UI.\r\nFurthermore, you can also trigger it manually via either the UI, the REST API or MQTT, meaning that you can now fully customize the collection interval by using e.g. Home Assistant automations.\r\n\r\n## Misc\r\n\r\n### Obstacle Avoidance\r\n\r\nYou can now disable the Obstacle Avoidance Feature of your Dreame L10/Z10 via the Swagger UI if you experience issues such as the robot refusing to drive onto a carpet.\r\n\r\n### Consumables UI\r\n\r\nThe new UI now also features a consumables section with a neat hover feature hopefully helping newcomers better understand the consumables.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927281-cd81083a-be3f-415f-bf78-81818a0c26af.png)\r\n\r\n\r\n### Runtime Information UI\r\n\r\nThe new UI about section has been extended to display data returned by the runtime information endpoint.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/133927292-91c520e9-210e-40c4-89a1-3c0fce037ad9.png)\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** AutoEmptyDockAutoEmptyControlCapability ([eeeb46c](https://github.com/Hypfer/Valetudo/commit/eeeb46c8a2152049392b7df06c952dc44b101d98))\r\n* **core:** AutoEmptyDockManualTriggerCapability ([5678d4f](https://github.com/Hypfer/Valetudo/commit/5678d4fd8e3dab9364182fa8f40fa09465bc77eb))\r\n* **core:** ObstacleAvoidanceControlCapability ([e5fab92](https://github.com/Hypfer/Valetudo/commit/e5fab92172dd6c024201218bbe4889a770c3f7c2))\r\n* **core:** Robot properties ([b1713df](https://github.com/Hypfer/Valetudo/commit/b1713dff26a2bcfd707bd88fa0dcf3acbde4faa1))\r\n* **MockRobot:** MockAutoEmptyDockManualTriggerCapability ([31cb972](https://github.com/Hypfer/Valetudo/commit/31cb972d89cba474c3c8732e969015a5bb5d9851))\r\n* **ui:** Add button to trigger dock auto empty manually ([#1087](https://github.com/Hypfer/Valetudo/issues/1087)) ([fa2def7](https://github.com/Hypfer/Valetudo/commit/fa2def7c65a2641ec6321fcdfb4c3975e607867d))\r\n* **ui:** Consumables in new UI ([#1093](https://github.com/Hypfer/Valetudo/issues/1093)) ([144d6ed](https://github.com/Hypfer/Valetudo/commit/144d6edacdf264b5a835ee184c1639f982231d25))\r\n* **ui:** Implement MQTT config ui ([#1080](https://github.com/Hypfer/Valetudo/issues/1080)) ([2dd83e3](https://github.com/Hypfer/Valetudo/commit/2dd83e3a8c8e8c1629f873b9d20a52f7337fbcd9))\r\n* **ui:** Implement timer ui ([#1077](https://github.com/Hypfer/Valetudo/issues/1077)) ([abd6345](https://github.com/Hypfer/Valetudo/commit/abd63454588e510d23d55c4f08a1caad1cc7c649))\r\n* **ui:** Log with SSE and display log in new UI ([#1092](https://github.com/Hypfer/Valetudo/issues/1092)) ([1721df7](https://github.com/Hypfer/Valetudo/commit/1721df7dd6969fba8acd63d726a8ca14d1977afd))\r\n* **ui:** Navigation and Events in UI ([#1090](https://github.com/Hypfer/Valetudo/issues/1090)) ([27fd2ba](https://github.com/Hypfer/Valetudo/commit/27fd2ba97e98f534c20ca6e22b0d46510f355706))\r\n* **ui:** Show MQTT config defaults ([711c312](https://github.com/Hypfer/Valetudo/commit/711c312cc41fff57867e5b97d4e867b3ef41b4c3))\r\n* **ui:** Show MQTT topic preview ([#1082](https://github.com/Hypfer/Valetudo/issues/1082)) ([865905e](https://github.com/Hypfer/Valetudo/commit/865905ea58bfff9187c7463fce3a312b738a1e90))\r\n* **ui:** Show runtime info on about page ([#1089](https://github.com/Hypfer/Valetudo/issues/1089)) ([ece2dc9](https://github.com/Hypfer/Valetudo/commit/ece2dc9d6d5baafa4d0aa291565087bf2e1f6148))\r\n* **vendor.dreame:** DreameAutoEmptyDockAutoEmptyControlCapability ([a1fa6d8](https://github.com/Hypfer/Valetudo/commit/a1fa6d8a14bad572aca4ce6af714cacb9d4e1760))\r\n* **vendor.dreame:** DreameAutoEmptyDockManualTriggerCapability ([b7aed1a](https://github.com/Hypfer/Valetudo/commit/b7aed1afa217ebd90f411c91844a28f05946460d))\r\n* **vendor.dreame:** DreameDoNotDisturbCapability ([60972ca](https://github.com/Hypfer/Valetudo/commit/60972ca6dd8d8200d8c25a2e4e084c04f97ef8ce))\r\n* **vendor.dreame:** DreameObstacleAvoidanceControlCapability ([ca9a499](https://github.com/Hypfer/Valetudo/commit/ca9a49939d9499dddfc9f77aede70c655758031a))\r\n* **webserver:** Provide mqtt config properties ([7e6962b](https://github.com/Hypfer/Valetudo/commit/7e6962bd8094120168c960d550027efbf3a53d73))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Accepting/rejecting a pending map change should always invalidate a pending event ([94c8da2](https://github.com/Hypfer/Valetudo/commit/94c8da29c6f3f3adc3e9f02b546dd258e4bd30bc))\r\n* **timers:** Prevent timer drift ([#1078](https://github.com/Hypfer/Valetudo/issues/1078)) ([105d02a](https://github.com/Hypfer/Valetudo/commit/105d02a67d502ba727e90251f2b9325837833ebd))\r\n* **ui:** Improve word breaks in MQTT topic preview ([#1088](https://github.com/Hypfer/Valetudo/issues/1088)) ([8736f7f](https://github.com/Hypfer/Valetudo/commit/8736f7fc9ee1d76dcb8a5c21975f85040fbfd723))\r\n* **ui:** Make timers use correct time zone offset ([#1079](https://github.com/Hypfer/Valetudo/issues/1079)) ([f790db3](https://github.com/Hypfer/Valetudo/commit/f790db3ec1eadcaa91726a75ac994b5d527058f4))\r\n* **ui:** Remove staleTime: Infinity for queries that should actually refresh automatically ([b53d428](https://github.com/Hypfer/Valetudo/commit/b53d428846f3013768827296b193ed68f4ca0255))\r\n* **ui:** Show old ui timer page even when there's no DoNotDisturbCapability ([ac19d5d](https://github.com/Hypfer/Valetudo/commit/ac19d5d2c1751c12d614ebf2c8cb701cdc7a0473))\r\n* **ui:** Timer action controls Memo dependency ([#1091](https://github.com/Hypfer/Valetudo/issues/1091)) ([7ebbafc](https://github.com/Hypfer/Valetudo/commit/7ebbafce307fc5b3e07f73f3652d154a63d3a248))\r\n* **ValetudoEvents:** Resetting a consumable should also set its event to processed ([d705c5b](https://github.com/Hypfer/Valetudo/commit/d705c5bc67cff5cb4b085893f428bf7794a26bb1)), closes [#1096](https://github.com/Hypfer/Valetudo/issues/1096)\r\n* **webserver:** Remove obsolete mqtt config password stripping ([c4f6fab](https://github.com/Hypfer/Valetudo/commit/c4f6fabc62c69b6573782e31511f8df02ea2e7a3))\r\n* **webserver:** Strip credentials from mqtt config REST response and remove ssh key upload ([5b66887](https://github.com/Hypfer/Valetudo/commit/5b6688778bd3efb884e027b51d2989e28c7252af))\r\n* **webserver:** Terminate SSE connections on shutdown for a clean shutdown ([bfbf4dd](https://github.com/Hypfer/Valetudo/commit/bfbf4dd7192a443ca7e49d9efa0f382040370741))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1098", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49812967/reactions", + "total_count": 2, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 2, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/49298984/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.09.0", + "id": 49298984, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOCGKICM4C8D4o", + "tag_name": "2021.09.0", + "target_commitish": "master", + "name": "Valetudo 2021.09.0", + "draft": false, + "prerelease": false, + "created_at": "2021-09-09T17:50:14Z", + "published_at": "2021-09-09T18:00:31Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44406742", + "id": 44406742, + "node_id": "RA_kwDOCGKICM4CpZfW", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33691524, + "download_count": 104, + "created_at": "2021-09-09T18:06:20Z", + "updated_at": "2021-09-09T18:06:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44407365", + "id": 44407365, + "node_id": "RA_kwDOCGKICM4CpZpF", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13167284, + "download_count": 7, + "created_at": "2021-09-09T18:14:59Z", + "updated_at": "2021-09-09T18:14:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44406739", + "id": 44406739, + "node_id": "RA_kwDOCGKICM4CpZfT", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31444040, + "download_count": 225, + "created_at": "2021-09-09T18:06:17Z", + "updated_at": "2021-09-09T18:06:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44406740", + "id": 44406740, + "node_id": "RA_kwDOCGKICM4CpZfU", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31444040, + "download_count": 156, + "created_at": "2021-09-09T18:06:18Z", + "updated_at": "2021-09-09T18:06:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44407364", + "id": 44407364, + "node_id": "RA_kwDOCGKICM4CpZpE", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12541772, + "download_count": 9, + "created_at": "2021-09-09T18:14:57Z", + "updated_at": "2021-09-09T18:14:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/44407363", + "id": 44407363, + "node_id": "RA_kwDOCGKICM4CpZpD", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12541788, + "download_count": 10, + "created_at": "2021-09-09T18:14:57Z", + "updated_at": "2021-09-09T18:14:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.09.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.09.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.09.0", + "body": "
\r\n \"valetudo\"\r\n

2021.09.0

\r\n
\r\n\r\nThis release features some more bugfixes and some breaking config changes\r\n\r\n## New UI\r\n\r\nIf you haven't seen it already, check out [the previous release notes](https://github.com/Hypfer/Valetudo/releases/tag/2021.08.1).\r\n\r\n## MQTT changes\r\n\r\n### Config Schema\r\nThis release features a much cleaner mqtt configuration schema. Now, one can actually understand what the options are for.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/132738325-10a47c75-f321-4c79-94ec-374484d7b7f4.png)\r\n\r\n\r\n\r\nSince this a **breaking change**, Valetudo will likely reject your old config file and create a new one.\r\nDon't worry though. The old one is backed up meaning that you can simply copy-paste your timers, presets etc.\r\nJust check the Log for more information.\r\n\r\n### Identifier\r\n\r\nValetudo will now use the autogenerated machine identifier as the mqtt identifier and friendly name.\r\nIf you've been using the defaults until now, you'll either want to manually configure the identifier or update your scripts, delete your Vacuum Device in Home Assistant etc.\r\n\r\nThe autogenerated unique machine identifier can be found in the Log.\r\nIt will sorta look like this: `ModestFewChinchilla`\r\n\r\n### Home Assistant Map Data\r\n\r\nThe Map data camera image has been replaced with a nicer looking one that will also hopefully lead to less confusion for newcomers.\r\nIt looks like this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/132737756-efba2973-0ed7-47cb-bae4-6b6ca18acf67.png)\r\n\r\n\r\n## Out-of-Memory Issues\r\n\r\nThe out of memory issues causing Valetudo to shut down have been fixed again even though that they were already fixed.\r\nFor some reason, npm started installing the old and unpatched dependency. Probably some weirdness regarding the `package-lock.json` or something like that.\r\n\r\nThis has been solved by reimplementing what the dependency did in Valetudo itself. Fortunately, this allowed us to add logging to that.\r\nIf you're seeing something like `[WARN] Stale SSE connection to the Map SSE Hub detected. Terminating.` in your log, the mitigation is working.\r\n\r\n## Updated Robot Docs\r\n\r\nI've added some notes for each implementation to the [Supported Robots Page](https://valetudo.cloud/pages/general/supported-robots.html) to make it easier for people to choose a robot to buy.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Log autogenerated system ID ([2cc365c](https://github.com/Hypfer/Valetudo/commit/2cc365c60415f68e3ec7d454eda8387adf8c9842))\r\n* **ui:** make toggle group full width ([#1060](https://github.com/Hypfer/Valetudo/issues/1060)) ([dfdd7f7](https://github.com/Hypfer/Valetudo/commit/dfdd7f7de54ad84f0f4fd52e34692879ce0116ff))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** reduce loglevel of user ack timeout spam messages ([3f81d4c](https://github.com/Hypfer/Valetudo/commit/3f81d4c063595f129d7b08114377b6b4703628e1))\r\n* **mqtt:** Poll robot state every refreshInterval to mitigate stale data on lost cloud connections ([95ce4bb](https://github.com/Hypfer/Valetudo/commit/95ce4bb333911f67afadd769af4104d8286dae6b))\r\n* **openapi:** Fix examples schema for ManualControlCapability ([b22ceb7](https://github.com/Hypfer/Valetudo/commit/b22ceb7288f87540492182eba58f821fe44a544e))\r\n* **ui:** Change path color to black for better visibility ([2454a85](https://github.com/Hypfer/Valetudo/commit/2454a85a650a9323293dd9190cf5a955b8b2e7f8))\r\n* **vendor.viomi:** catch set_timezone errors ([c2cbd45](https://github.com/Hypfer/Valetudo/commit/c2cbd4588dede2b4d6a86c7d0807b16d7308d0f2))\r\n\r\n### Reverts\r\n\r\n* Revert \"fix(vendor.viomi): Poll state every 30s to fix stale mqtt data\" ([b55e4a5](https://github.com/Hypfer/Valetudo/commit/b55e4a58edc20d3d7e3f67274891d46967f0fd8d))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1075", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/49298984/reactions", + "total_count": 9, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 9, + "confused": 0, + "heart": 0, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/48695654/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.08.1", + "id": 48695654, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ4Njk1NjU0", + "tag_name": "2021.08.1", + "target_commitish": "master", + "name": "Valetudo 2021.08.1", + "draft": false, + "prerelease": false, + "created_at": "2021-08-30T18:48:12Z", + "published_at": "2021-08-30T19:15:34Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642309", + "id": 43642309, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyMzA5", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33724473, + "download_count": 117, + "created_at": "2021-08-30T19:23:13Z", + "updated_at": "2021-08-30T19:23:14Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642721", + "id": 43642721, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyNzIx", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 13200601, + "download_count": 5, + "created_at": "2021-08-30T19:32:24Z", + "updated_at": "2021-08-30T19:32:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642306", + "id": 43642306, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyMzA2", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31476989, + "download_count": 252, + "created_at": "2021-08-30T19:23:11Z", + "updated_at": "2021-08-30T19:23:12Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642307", + "id": 43642307, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyMzA3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 31476989, + "download_count": 181, + "created_at": "2021-08-30T19:23:12Z", + "updated_at": "2021-08-30T19:23:13Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642720", + "id": 43642720, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyNzIw", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12575097, + "download_count": 17, + "created_at": "2021-08-30T19:32:24Z", + "updated_at": "2021-08-30T19:32:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/43642719", + "id": 43642719, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQzNjQyNzE5", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12574937, + "download_count": 7, + "created_at": "2021-08-30T19:32:23Z", + "updated_at": "2021-08-30T19:32:23Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.1/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.08.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.08.1", + "body": "
\r\n \"valetudo\"\r\n

2021.08.1

\r\n
\r\n\r\nThis release features the new React-based UI by @Jomik as well as some MQTT config changes\r\n\r\n## New UI\r\n\r\nThe new UI has been merged and is now available as a usable preview.\r\nThere's still a lot to do, however that should be much easier now that it is merged.\r\n\r\nUntil everything has been ported over, the old UI will still be the default.\r\n\r\nYou can open the new one via the menu, which now also houses a shortcut to the Swagger UI as well:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392121-d28f2ae6-278d-49a3-a51e-2ca338107ec6.png)\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392013-d984ab62-b3c4-4590-9081-f7f457b8ad11.png)\r\n\r\n\r\nThere's a drop-down where you can select a zone preset to clean in the new UI.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392187-40648196-50be-4c23-8cea-4ed1864decd5.png)\r\n\r\n\r\nFuthermore, there's also a button, which lets you set the iteration count for segment cleanups.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/131392224-31302e3d-c8dc-43ce-823f-8c82732a6ffd.png)\r\n\r\n\r\n\r\nThis marks a huge step forward for the project, which has been due since years. Thanks again to @Jomik ❤\r\n\r\n## MQTT config changes\r\n\r\nThis release removes all mqtt settings where I couldn't find a reasonable explanation for why they exist.\r\nIf you're missing something, please let me know in the comments and include an explanation _why_ it was needed.\r\n\r\n## Dreame Z10 Pro Support\r\n\r\nIf you're looking for a Valetudo-supported and affordable Vacuum Robot featuring an Auto-Empty Dock, you can now buy\r\nthe Dreame Z10 Pro. I didn't know that I needed an auto-empty dock before I got one, but I definitely needed one.\r\n\r\nDo note that it's supported on the feature level of the L10 Pro, meaning that you can't control the Dock yet.\r\nThat shouldn't matter though as it is on by default and doesn't strictly require any interactions.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **ui:** Add link to swagger ui to menu ([513bd8c](https://github.com/Hypfer/Valetudo/commit/513bd8c2778ae2f26186ae48f69030bbfde59628))\r\n* **ui:** Added html title to symbols in various map views ([#1026](https://github.com/Hypfer/Valetudo/issues/1026)) ([98d0f1e](https://github.com/Hypfer/Valetudo/commit/98d0f1e617cae48cbd44a171b5aa9178f0677a0b))\r\n* **ui:** Display system host info ([54df5ca](https://github.com/Hypfer/Valetudo/commit/54df5ca4f6b53a280bad52f0a73f074e1d5122f3))\r\n* **ui:** Support segment cleanup iteration count selection in map view ([f798ff5](https://github.com/Hypfer/Valetudo/commit/f798ff5d040e08a7b2f4d2606e61d8c5000957f5))\r\n* **vendor.dreame:** Add Dreame Z10 Pro ([4127ccd](https://github.com/Hypfer/Valetudo/commit/4127ccdc413155c5f3d03a29b51fc7c2f10a1353))\r\n* **vendor.dreame:** Log rootfs on startup if embedded ([cbde5a4](https://github.com/Hypfer/Valetudo/commit/cbde5a4873be1113b0dc5cfee0c1164cdc5bedf4))\r\n* **vendor.roborock:** Log rootfs on startup if embedded ([8d09fd6](https://github.com/Hypfer/Valetudo/commit/8d09fd6dab8413b3b5e9aa89921014ef267b3f23))\r\n* New React UI ([9acb2cd](https://github.com/Hypfer/Valetudo/commit/9acb2cd529a1b84dd7db333778dd523d8487c4e7))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Add proper shutdown methods to dummycloud and retrywrapper ([f0676ef](https://github.com/Hypfer/Valetudo/commit/f0676efa6d81535069f156dab2611b63b7e4d27c))\r\n* **miio:** Reduce loglevel for non-pending messages ([dbabe0b](https://github.com/Hypfer/Valetudo/commit/dbabe0b3a8e9540aff2d6f8f76dfdea2b68c767f))\r\n* **mqtt:** Catch exceptions on connect reconfiguration ([0e3bebd](https://github.com/Hypfer/Valetudo/commit/0e3bebda27553ee7f7b3796a4b89dbd53eec1ccb))\r\n* **mqtt:** Fix 100% cpu consumable fetch recursion ([ae163a9](https://github.com/Hypfer/Valetudo/commit/ae163a95e95b384e4e3e2804f9a4792c9e9793e9))\r\n* **mqtt:** Remove refreshInterval setting ([83d2a45](https://github.com/Hypfer/Valetudo/commit/83d2a45eb0d21cc15cc58cdf1734833688de0fac))\r\n* **networkadvertisement:** Hopefully fix valetudo crashing due to network issues ([4ace37e](https://github.com/Hypfer/Valetudo/commit/4ace37e0aaf88e5bb53dfbab5fbb4bf1d43c685e))\r\n* **ui:** Fix minor issues discovered by deepscan ([ee8b58b](https://github.com/Hypfer/Valetudo/commit/ee8b58b646ce006d8c1d6a5cca2f27d6af32392c))\r\n* **ui:** Only dark mode (for now?) ([db985f3](https://github.com/Hypfer/Valetudo/commit/db985f39fcfdf1bc9048d50a3e2d7d75bc42f3da))\r\n* **vendor.dreame:** Add error code 68 mapping ([741c711](https://github.com/Hypfer/Valetudo/commit/741c7114d4b88760cd30ab7e50697816f968ed2a))\r\n* **vendor.dreame:** Fix incorrect status mapping for powersave mode ([343c749](https://github.com/Hypfer/Valetudo/commit/343c749a107fdaa4f016965984065585c0872616))\r\n* **vendor.dreame:** Ignore \"event_occured\" cloud messages ([4d3f4ac](https://github.com/Hypfer/Valetudo/commit/4d3f4acf8fd864d690850070328b5f9b115934d4))\r\n* **vendor.roborock:** Handle more events ([972e4df](https://github.com/Hypfer/Valetudo/commit/972e4df9fc840c85324de7ef926763a521bd225d))\r\n* **vendor.viomi:** Poll state every 30s to fix stale mqtt data ([fdb315a](https://github.com/Hypfer/Valetudo/commit/fdb315a33beb6690a68f34a131bd7484802ded7d))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1055", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/48695654/reactions", + "total_count": 10, + "+1": 2, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 8, + "eyes": 0 + }, + "mentions_count": 1 + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/47830402/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.08.0", + "id": 47830402, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ3ODMwNDAy", + "tag_name": "2021.08.0", + "target_commitish": "master", + "name": "Valetudo 2021.08.0", + "draft": false, + "prerelease": false, + "created_at": "2021-08-13T18:50:06Z", + "published_at": "2021-08-13T19:05:50Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42390793", + "id": 42390793, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkwNzkz", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32535472, + "download_count": 124, + "created_at": "2021-08-13T19:08:59Z", + "updated_at": "2021-08-13T19:09:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42391177", + "id": 42391177, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkxMTc3", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12011600, + "download_count": 7, + "created_at": "2021-08-13T19:17:59Z", + "updated_at": "2021-08-13T19:18:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42390791", + "id": 42390791, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkwNzkx", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30287988, + "download_count": 300, + "created_at": "2021-08-13T19:08:57Z", + "updated_at": "2021-08-13T19:08:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42390792", + "id": 42390792, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkwNzky", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30287988, + "download_count": 218, + "created_at": "2021-08-13T19:08:58Z", + "updated_at": "2021-08-13T19:08:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42391176", + "id": 42391176, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkxMTc2", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11385424, + "download_count": 15, + "created_at": "2021-08-13T19:17:58Z", + "updated_at": "2021-08-13T19:17:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/42391175", + "id": 42391175, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQyMzkxMTc1", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11385592, + "download_count": 9, + "created_at": "2021-08-13T19:17:57Z", + "updated_at": "2021-08-13T19:17:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.08.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.08.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.08.0", + "body": "
\r\n \"valetudo\"\r\n

2021.08.0

\r\n
\r\n\r\nThis release contains mostly bugfixes and code cleanup.\r\nAlso, ordered cleanup and iterations for MQTT segment cleaning.\r\n\r\n## Dreame root public release\r\n\r\nRooting Dreame robots has been made publicly available with Dennis' DEF CON 29 Talk\r\n[Robots with lasers and cameras but no security Liberating your vacuum](https://youtu.be/EWqFxQpRbv8?t=1525).\r\n\r\nFor more information, consider joining the [Dreame Robot Vacuum Telegram Usergroup](https://t.me/joinchat/zgRioVBpWHliNGZi).\r\n\r\n## MQTT Segment Cleaning options\r\n\r\nThis release allows you to specify an iteration count when calling Segment Cleanups via MQTT.\r\nFurthermore, you can also request it to respect the order you've provided. e.g. Kitchen then Living Room then Bathroom.\r\n\r\nThis requires firmware support and is also a **breaking change.**\r\nYou'll have to update your MQTT scripts/automations/whatever.\r\n\r\n[The docs](https://valetudo.cloud/pages/integrations/home-assistant-integration.html) contain an example payload.\r\n\r\n## KeyLockCapability\r\n\r\nIf you have children, cats or drunk roommates who like to mess with your robot vacuum, you can now lock the buttons via Valetudo.\r\nThis of course needs firmware support. Something that seems to be available on most Dreame-made robots.\r\n\r\nPlease note that there's no UI toggle for it yet, meaning that you'll have to use the Swagger UI (http://ROBOT_IP/swagger/) to enable it.\r\n\r\n## _valetudo._tcp bonjour service\r\n\r\nValetudo 2021.08.0 and up will publish a bonjour service, which should make it easy to auto-discover a Valetudo instance.\r\nThis will likely be useful in the future.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** KeyLockCapability ([4e2b97b](https://github.com/Hypfer/Valetudo/commit/4e2b97b3f214d239af3ef4d032c9a123fad1a816))\r\n* **networkadvertisement:** Publish _valetudo._tcp service ([cb1c34f](https://github.com/Hypfer/Valetudo/commit/cb1c34fc3c0083d5405c2c638120e498a0ef5151))\r\n* **vendor.dreame:** 1C Manual Control ([afded40](https://github.com/Hypfer/Valetudo/commit/afded402a5f26c5bcdf409b41f22d3f6d8b7272b))\r\n* **vendor.dreame:** DreameKeyLockCapability ([36e3598](https://github.com/Hypfer/Valetudo/commit/36e3598d50efc04515809f909a1600aa8575a5ac))\r\n* **vendor.dreame:** Manual Control ([4cfddd4](https://github.com/Hypfer/Valetudo/commit/4cfddd4ca17e40187d2e6f2e4557e122349978ac))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Improve unhandledRejection event handler ([a8720b9](https://github.com/Hypfer/Valetudo/commit/a8720b931a4a89b4748470786a0fe0b9b4fd64c4))\r\n* **mqtt:** Catch exceptions when handling MQTT commands ([33b9dc3](https://github.com/Hypfer/Valetudo/commit/33b9dc3cfcd6f66d3805c662766c36c494bbad69))\r\n* **mqtt:** Fix weirdness on disconnect ([be033b6](https://github.com/Hypfer/Valetudo/commit/be033b6efe1806b382a47609802e28a2004130fb))\r\n* **mqtt:** Only try to publish state when connected ([e61cf98](https://github.com/Hypfer/Valetudo/commit/e61cf9840d73a08edd44e1368339afb3d4fecef5))\r\n* **mqtt:** Publish named as well as unnamed segments ([b5ff0b4](https://github.com/Hypfer/Valetudo/commit/b5ff0b47061d997ce2439292e6f11ceea8405de0))\r\n* **vendor.dreame:** Add error code 64 for Dreame robots ([#1017](https://github.com/Hypfer/Valetudo/issues/1017)) ([4ed64d2](https://github.com/Hypfer/Valetudo/commit/4ed64d2f2ccf66994c71091b06d9531f8b603244))\r\n* **vendor.dreame:** Error 11 Mapping for CombinedVirtualRestrictions ([491ed4b](https://github.com/Hypfer/Valetudo/commit/491ed4b4f6f670f1f148383084de0f7b2528a816))\r\n* **vendor.dreame:** Fix cleaning order of segments ([d7cfd07](https://github.com/Hypfer/Valetudo/commit/d7cfd07b681e9e8c76efcaf0257b31f0c54dfcd4))\r\n* **vendor.dreame:** Handle more segment-related error codes ([57fe90a](https://github.com/Hypfer/Valetudo/commit/57fe90afebebf93519eabd7a80bf74390e0ca4da))\r\n* **vendor.dreame:** Ignore some FDS uploads ([f1930b3](https://github.com/Hypfer/Valetudo/commit/f1930b30228e34f9c123031f0e559fcd3704a532))\r\n* **vendor.dreame:** Update error code mapping ([d1699b2](https://github.com/Hypfer/Valetudo/commit/d1699b24d9631e22e4fd189c1f054a10949e4a36))\r\n* Fix invalid use of .finally() ([770f977](https://github.com/Hypfer/Valetudo/commit/770f977a1e4c76f056e1a83c9aeca76cb45b57ab))\r\n* **vendor.dreame:** Remove logging of raw data on failed parse ([11fec98](https://github.com/Hypfer/Valetudo/commit/11fec98920afae8b7d99914158706bad38f5f082))\r\n* **vendor.roborock:** Fix unhandled rejection in virtual restrictions ([4a76029](https://github.com/Hypfer/Valetudo/commit/4a760293473e57cf49217e9b901f013e2637370b))\r\n* **vendor.viomi:** Fix unhandled rejection in virtual restrictions ([af4704f](https://github.com/Hypfer/Valetudo/commit/af4704f8846cb95630debdabd1753e61a7c76ab5))\r\n* Fix more various minor issues found by deepscan ([c6c1a7f](https://github.com/Hypfer/Valetudo/commit/c6c1a7f0dd89656b3d2385ffee648e03a5956511))\r\n* Fix various minor issues found by deepscan ([37cc55f](https://github.com/Hypfer/Valetudo/commit/37cc55f4431eb01d1b2036ddc9cf1bf458368487))", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1018", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/47830402/reactions", + "total_count": 13, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 13, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/46995769/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.07.1", + "id": 46995769, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ2OTk1NzY5", + "tag_name": "2021.07.1", + "target_commitish": "master", + "name": "Valetudo 2021.07.1", + "draft": false, + "prerelease": false, + "created_at": "2021-07-29T17:43:36Z", + "published_at": "2021-07-29T17:46:33Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286385", + "id": 41286385, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2Mzg1", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32532575, + "download_count": 105, + "created_at": "2021-07-29T17:49:30Z", + "updated_at": "2021-07-29T17:49:31Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286768", + "id": 41286768, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2NzY4", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 12009119, + "download_count": 4, + "created_at": "2021-07-29T17:57:37Z", + "updated_at": "2021-07-29T17:57:38Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286376", + "id": 41286376, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2Mzc2", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30285091, + "download_count": 229, + "created_at": "2021-07-29T17:49:28Z", + "updated_at": "2021-07-29T17:49:29Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286383", + "id": 41286383, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2Mzgz", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30285091, + "download_count": 116, + "created_at": "2021-07-29T17:49:29Z", + "updated_at": "2021-07-29T17:49:30Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286767", + "id": 41286767, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2NzY3", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11382527, + "download_count": 9, + "created_at": "2021-07-29T17:57:36Z", + "updated_at": "2021-07-29T17:57:37Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41286766", + "id": 41286766, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjg2NzY2", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11382695, + "download_count": 9, + "created_at": "2021-07-29T17:57:36Z", + "updated_at": "2021-07-29T17:57:36Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.1/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.07.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.07.1", + "body": "
\r\n \"valetudo\"\r\n

2021.07.1

\r\n
\r\n\r\nThis release includes, SSDP and Zeroconf advertisement, an Event/Notification feature some bugfixes and lowmem optimizations.\r\nFurthermore, 2021.07.1 fixes a race condition which was present in 2021.07.0 causing crashes on reboot.\r\n\r\n## Network advertisement\r\n\r\nTo make using Valetudo a bit easier and more straight-forward, advertisement of the Service via both SSDP/UPnP as well as Zeroconf was added.\r\n\r\nIf you're on Windows, opening \"Network\" in the File Explorer should look similar to this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/127387044-da7e8c18-390f-40bc-88b1-3ff316e4e6cf.png)\r\n\r\n\r\nIf you're on a Mac, I'm sure that there's also something.\r\nFurthermore, Valetudo will log the `.local` domain it's using, which might be useful in some setups.\r\n\r\n## ValetudoEvents\r\n\r\nStarting with this release, we now have something that will deal with everything that would've been a push notification\r\nwhen using the regular app. Utilizing this, the \"Bin Full\" notification on roborock vacuum robots may finally happen.\r\n\r\nThere's no UI for it just yet, however it will be implemented eventually.\r\n\r\n## Runtime Reuse\r\n\r\nAs storage space can be quite limited on these devices, it is now possible to use the NodeJS runtime bundled with\r\nValetudo for other things as well.\r\n\r\nThis can be helpful if one would e.g. want to implement a Microservice, which also runs on the Robot, talks to Valetudo\r\nand provides Telegram connectivity.\r\n\r\nJust add the `--ignore-payload` flag plus another JS file:\r\n`./valetudo --ignore-payload repl.js`\r\n\r\nThe baked-in v8 options will still apply when reusing the runtime.\r\nThat however shouldn't be an issue for most use-cases.\r\n\r\n## S5 Max Map issues\r\n\r\nApparently, the Map Reset on the S5 Max never worked. That might explain some issues users of this Robot were seeing.\r\nIt should be fixed now.\r\n\r\n## Memory-related changes\r\n\r\nDuring the development of 2021.07.0, a lot of time was spent optimizing Valetudo for use in lowmem environments\r\nsuch as the Roborock S5 Max or Dreame D9.\r\n\r\nIt was discovered that there were issues with the SSE Map update feature, which lead to Valetudo being killed by the\r\nKernel OOM killer. This was the cause of the confusing \"Hey my Valetudo is just.. gone\" reports.\r\n\r\nWhile this was fixed by introducing limits there, Valetudo was also extended to watch its own Memory usage\r\nand shut down if it exceeds 1/3 of system memory. This should provide an additional failsafe.\r\n\r\nFurthermore, Valetudo will also set its OOM score to a rather high value by itself, so that the Kernel OOM killer\r\nwill always kill Valetudo and nothing else.\r\n\r\nStill, if you can, please buy a 512mb or more RAM robot.\r\n\r\n## Misc\r\n\r\n- To help with debugging, you can now enable an option in the config file to store all uploaded maps in the filesystem.\r\n- Resetting the Map will now also invalidate the map cached by Valetudo to reduce confusion.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Network Announcement via SSDP/UPnP and mDNS/Zeroconf/Bonjour ([c158d77](https://github.com/Hypfer/Valetudo/commit/c158d7718c33d4b14b8710e636a25616c8e1acad))\r\n* **core:** MappingPassCapability ([1b09cde](https://github.com/Hypfer/Valetudo/commit/1b09cdec4ab4d3605ae2572f1f3eb187dfd2e1d5))\r\n* **core:** PendingMapChangeHandlingCapability ([ed0455d](https://github.com/Hypfer/Valetudo/commit/ed0455d66a46b7adc16e91d34daff2da3e784417))\r\n* **miio:** Add easy way to store uploaded maps for debugging purposes ([547f8c1](https://github.com/Hypfer/Valetudo/commit/547f8c13271f684d3285490b2365f161415b357d))\r\n* **vendor.dreame:** Add Support for the L10 Pro ([2f618c0](https://github.com/Hypfer/Valetudo/commit/2f618c030edf2bd27d254992940ac7514dd4b3c3))\r\n* **vendor.dreame:** DreamePendingMapChangeHandlingCapability ([d972121](https://github.com/Hypfer/Valetudo/commit/d972121d93f6cd552d868ae0935d698efba28d6b))\r\n* **vendor.dreame:** Handle more properties ([421e7de](https://github.com/Hypfer/Valetudo/commit/421e7dea340c8e364e82bb35770958b0c7b0792f))\r\n* **vendor.dreame:** MappingPassCapability ([7f9322b](https://github.com/Hypfer/Valetudo/commit/7f9322b060d354df13d3238328d99cb29ce2df43))\r\n* Set OOM Score Adj when embedded ([6de2f06](https://github.com/Hypfer/Valetudo/commit/6de2f06ba87f1884e74acab32976437cf34cf2c2))\r\n* ValetudoEvents ([aa15238](https://github.com/Hypfer/Valetudo/commit/aa152381d1c4b73e594b1dd36c04ccfc32de3f87))\r\n* **vendor.dreame:** Map fast mapping status ([021213e](https://github.com/Hypfer/Valetudo/commit/021213e8cd3b932685b590d896dcf640c311a2fc))\r\n* **vendor.dreame:** Sensor consumable ([4c1e319](https://github.com/Hypfer/Valetudo/commit/4c1e31980af77492f634fbaad375cd20d1fb8a2d))\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Catch uncaught exceptions for an orderly shutdown ([5cf19c4](https://github.com/Hypfer/Valetudo/commit/5cf19c426734acb08f38b86a88a7743c7db770db))\r\n* **core:** Reverse event order ([a829ba5](https://github.com/Hypfer/Valetudo/commit/a829ba54ab95ea0e00c9e855467d715a98ba4055))\r\n* **networkadvertisement:** Don't crash on reboots + human-friendly URL ([3cb1cb8](https://github.com/Hypfer/Valetudo/commit/3cb1cb8dae25b472ab6b79653ea2c8ba59e2c0df))\r\n* **vendor.dreame:** Fix segment cleanup via mqtt ([5dbb9d0](https://github.com/Hypfer/Valetudo/commit/5dbb9d0474b441a3285cae22140d82ecd71fb3d6))\r\n* **vendor.dreame:** Fix status mapping and ignore irrelevant property change ([68c1c0c](https://github.com/Hypfer/Valetudo/commit/68c1c0ceb0e13609b32b9637ee07addc67330c45)), closes [#969](https://github.com/Hypfer/Valetudo/issues/969)\r\n* **vendor.dreame:** Handle more properties ([6a834c8](https://github.com/Hypfer/Valetudo/commit/6a834c8ff888ab2c24516048c899f3bf42ec0290))\r\n* **vendor.dreame:** Handle sensor consumable push ([cc8b7a5](https://github.com/Hypfer/Valetudo/commit/cc8b7a5bc86014f61a6e792c69826e7ebed653db))\r\n* **vendor.dreame:** Handle sensor consumable push ([4276c36](https://github.com/Hypfer/Valetudo/commit/4276c3648e06a6951df9ee4f576db7cb1e5821bc))\r\n* **vendor.dreame:** Handle uploaded multi-map jsons ([01486b8](https://github.com/Hypfer/Valetudo/commit/01486b80292ddbafb9cae61f43ac19a0520e0a78))\r\n* **vendor.dreame:** Revert Fix status mapping ([8db8b6f](https://github.com/Hypfer/Valetudo/commit/8db8b6fd0dc22fc1b0cb23ec1052e1fa2e2ceae1))\r\n* **vendor.dreame:** Segments from rism might not apply in some situations ([e1161cf](https://github.com/Hypfer/Valetudo/commit/e1161cf6816db67306eff7ecf4935d36b2497347))\r\n* **vendor.dreame:** There actually is a difference between pause and stop ([6da5dc4](https://github.com/Hypfer/Valetudo/commit/6da5dc46a24b622b093af15024b729252b3c2e1d))\r\n* **vendor.roborock:** Add filename to map upload url ([90b7346](https://github.com/Hypfer/Valetudo/commit/90b73465159e65f89d94fce1096cf915b4903985))\r\n* **vendor.roborock:** Enable S7 Water Pump Control + No-Mop-Zones ([f699a55](https://github.com/Hypfer/Valetudo/commit/f699a558d49523f2683c08027538466c01b61ecc))\r\n* **vendor.roborock:** MapSnapshots are only available on Gen2 robots ([0752de2](https://github.com/Hypfer/Valetudo/commit/0752de2b862f697943171b4b56ba67ea0db3f203))\r\n* **vendor.roborock:** MapSnapshots IDs are strings in valetudo but numbers for roborock ([361dffa](https://github.com/Hypfer/Valetudo/commit/361dffacea59b76726ac93eb7a3296bb6905c763))\r\n* **vendor.roborock:** Multi-Map capable roborock robots use a different command for map resets ([2bbd86f](https://github.com/Hypfer/Valetudo/commit/2bbd86f9df27baeccb46580e3a24b08b02e28ab6))\r\n* **webserver:** Remove unused parameter ([d27e3b1](https://github.com/Hypfer/Valetudo/commit/d27e3b1f626e935dcc1e279d300abc4517f45517))\r\n* Fix missing git commit id ([40ca9cb](https://github.com/Hypfer/Valetudo/commit/40ca9cb55884153c4ad582fd377cff863666d9f2))\r\n* Fix OOM-issues caused by SSE connections ([a0371f4](https://github.com/Hypfer/Valetudo/commit/a0371f4909b58403bf88fabecf2969d400c5487c))\r\n* Further tweak forced garbage collection ([c70393a](https://github.com/Hypfer/Valetudo/commit/c70393a4f19e296642ab1dd4540a3f4a64f931b4))\r\n* Further tweak SSE settings ([8eae178](https://github.com/Hypfer/Valetudo/commit/8eae1786c9d85a10c3222144e1a9561141c10746))\r\n* Further tweak SSE settings ([40d16f5](https://github.com/Hypfer/Valetudo/commit/40d16f5332f746f0d589ac530007c170eaa5a024))\r\n* Further tweak SSE settings ([cb8e01e](https://github.com/Hypfer/Valetudo/commit/cb8e01e20b195146b901f405fd87b3e45b3d69b6))\r\n* Resetting the map should also clear the Map cached by Valetudo ([e70041f](https://github.com/Hypfer/Valetudo/commit/e70041fd0318b4f8389db7b78bb4dc6bb6a75a05))\r\n* **vendor.viomi:** Set correct env variables ([#979](https://github.com/Hypfer/Valetudo/issues/979)) ([5fd4a6a](https://github.com/Hypfer/Valetudo/commit/5fd4a6a618d6ea9b93991618a3f586ca4df76903))\r\n* **vendor.viomi:** Set correct ssh key location ([b15c707](https://github.com/Hypfer/Valetudo/commit/b15c707a8a7d9b344ba314a2109bc52531f0b395))\r\n* Try logging everything we can get about process memory before committing sudoku ([6578a99](https://github.com/Hypfer/Valetudo/commit/6578a99344a6d087450a0e4b45a630398fb3a544))\r\n* Tweak forced garbage collection ([d905864](https://github.com/Hypfer/Valetudo/commit/d905864f5e2b07579a0bcf6a13be649ec9e5c785))\r\n\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/1001", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46995769/reactions", + "total_count": 5, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 0, + "rocket": 5, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46930477", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46930477/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/46930477/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.07.0", + "id": 46930477, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ2OTMwNDc3", + "tag_name": "2021.07.0", + "target_commitish": "master", + "name": "Valetudo 2021.07.0", + "draft": false, + "prerelease": true, + "created_at": "2021-07-28T19:22:17Z", + "published_at": "2021-07-28T19:55:21Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41211878", + "id": 41211878, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjExODc4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32515454, + "download_count": 28, + "created_at": "2021-07-28T19:58:20Z", + "updated_at": "2021-07-28T19:58:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41212339", + "id": 41212339, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjEyMzM5", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11991550, + "download_count": 3, + "created_at": "2021-07-28T20:07:00Z", + "updated_at": "2021-07-28T20:07:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41211872", + "id": 41211872, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjExODcy", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30267970, + "download_count": 49, + "created_at": "2021-07-28T19:58:17Z", + "updated_at": "2021-07-28T19:58:18Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41211877", + "id": 41211877, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjExODc3", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30267970, + "download_count": 143, + "created_at": "2021-07-28T19:58:19Z", + "updated_at": "2021-07-28T19:58:19Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41212337", + "id": 41212337, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjEyMzM3", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11364806, + "download_count": 3, + "created_at": "2021-07-28T20:06:59Z", + "updated_at": "2021-07-28T20:07:00Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/41212335", + "id": 41212335, + "node_id": "MDEyOlJlbGVhc2VBc3NldDQxMjEyMzM1", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11365462, + "download_count": 4, + "created_at": "2021-07-28T20:06:58Z", + "updated_at": "2021-07-28T20:06:59Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.07.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.07.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.07.0", + "body": "
\r\n \"valetudo\"\r\n

2021.07.0

\r\n
\r\n\r\nThis release includes, SSDP and Zeroconf advertisement, an Event/Notification feature some bugfixes and lowmem optimizations.\r\n\r\n## Network advertisement\r\n\r\nTo make using Valetudo a bit easier and more straight-forward, advertisement of the Service via both SSDP/UPnP as well as Zeroconf was added.\r\n\r\nIf you're on Windows, opening \"Network\" in the File Explorer should look similar to this:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/127387044-da7e8c18-390f-40bc-88b1-3ff316e4e6cf.png)\r\n\r\n\r\nIf you're on a Mac, I'm sure that there's also something.\r\nFurthermore, Valetudo will log the `.local` domain it's using, which might be useful in some setups.\r\n\r\n## ValetudoEvents\r\n\r\nStarting with this release, we now have something that will deal with everything that would've been a push notification\r\nwhen using the regular app. Utilizing this, the \"Bin Full\" notification on roborock vacuum robots may finally happen.\r\n\r\nThere's no UI for it just yet, however it will be implemented eventually.\r\n\r\n## Runtime Reuse\r\n\r\nAs storage space can be quite limited on these devices, it is now possible to use the NodeJS runtime bundled with\r\nValetudo for other things as well.\r\n\r\nThis can be helpful if one would e.g. want to implement a Microservice, which also runs on the Robot, talks to Valetudo\r\nand provides Telegram connectivity.\r\n\r\nJust add the `--ignore-payload` flag plus another JS file:\r\n`./valetudo --ignore-payload repl.js`\r\n\r\nThe baked-in v8 options will still apply when reusing the runtime.\r\nThat however shouldn't be an issue for most use-cases.\r\n\r\n## S5 Max Map issues\r\n\r\nApparently, the Map Reset on the S5 Max never worked. That might explain some issues users of this Robot were seeing.\r\nIt should be fixed now.\r\n\r\n## Memory-related changes\r\n\r\nDuring the development of 2021.07.0, a lot of time was spent optimizing Valetudo for use in lowmem environments\r\nsuch as the Roborock S5 Max or Dreame D9.\r\n\r\nIt was discovered that there were issues with the SSE Map update feature, which lead to Valetudo being killed by the\r\nKernel OOM killer. This was the cause of the confusing \"Hey my Valetudo is just.. gone\" reports.\r\n\r\nWhile this was fixed by introducing limits there, Valetudo was also extended to watch its own Memory usage\r\nand shut down if it exceeds 1/3 of system memory. This should provide an additional failsafe.\r\n\r\nFurthermore, Valetudo will also set its OOM score to a rather high value by itself, so that the Kernel OOM killer\r\nwill always kill Valetudo and nothing else.\r\n\r\nStill, if you can, please buy a 512mb or more RAM robot.\r\n\r\n## Misc\r\n\r\n- To help with debugging, you can now enable an option in the config file to store all uploaded maps in the filesystem.\r\n- Resetting the Map will now also invalidate the map cached by Valetudo to reduce confusion.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* Network Announcement via SSDP/UPnP and mDNS/Zeroconf/Bonjour ([c158d77](https://github.com/Hypfer/Valetudo/commit/c158d7718c33d4b14b8710e636a25616c8e1acad))\r\n* **core:** MappingPassCapability ([1b09cde](https://github.com/Hypfer/Valetudo/commit/1b09cdec4ab4d3605ae2572f1f3eb187dfd2e1d5))\r\n* **core:** PendingMapChangeHandlingCapability ([ed0455d](https://github.com/Hypfer/Valetudo/commit/ed0455d66a46b7adc16e91d34daff2da3e784417))\r\n* **miio:** Add easy way to store uploaded maps for debugging purposes ([547f8c1](https://github.com/Hypfer/Valetudo/commit/547f8c13271f684d3285490b2365f161415b357d))\r\n* **vendor.dreame:** Add Support for the L10 Pro ([2f618c0](https://github.com/Hypfer/Valetudo/commit/2f618c030edf2bd27d254992940ac7514dd4b3c3))\r\n* **vendor.dreame:** DreamePendingMapChangeHandlingCapability ([d972121](https://github.com/Hypfer/Valetudo/commit/d972121d93f6cd552d868ae0935d698efba28d6b))\r\n* **vendor.dreame:** Handle more properties ([421e7de](https://github.com/Hypfer/Valetudo/commit/421e7dea340c8e364e82bb35770958b0c7b0792f))\r\n* **vendor.dreame:** MappingPassCapability ([7f9322b](https://github.com/Hypfer/Valetudo/commit/7f9322b060d354df13d3238328d99cb29ce2df43))\r\n* Set OOM Score Adj when embedded ([6de2f06](https://github.com/Hypfer/Valetudo/commit/6de2f06ba87f1884e74acab32976437cf34cf2c2))\r\n* ValetudoEvents ([aa15238](https://github.com/Hypfer/Valetudo/commit/aa152381d1c4b73e594b1dd36c04ccfc32de3f87))\r\n* **vendor.dreame:** Map fast mapping status ([021213e](https://github.com/Hypfer/Valetudo/commit/021213e8cd3b932685b590d896dcf640c311a2fc))\r\n* **vendor.dreame:** Sensor consumable ([4c1e319](https://github.com/Hypfer/Valetudo/commit/4c1e31980af77492f634fbaad375cd20d1fb8a2d))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Reverse event order ([a829ba5](https://github.com/Hypfer/Valetudo/commit/a829ba54ab95ea0e00c9e855467d715a98ba4055))\r\n* **vendor.dreame:** Fix segment cleanup via mqtt ([5dbb9d0](https://github.com/Hypfer/Valetudo/commit/5dbb9d0474b441a3285cae22140d82ecd71fb3d6))\r\n* **vendor.dreame:** Fix status mapping and ignore irrelevant property change ([68c1c0c](https://github.com/Hypfer/Valetudo/commit/68c1c0ceb0e13609b32b9637ee07addc67330c45)), closes [#969](https://github.com/Hypfer/Valetudo/issues/969)\r\n* **vendor.dreame:** Handle more properties ([6a834c8](https://github.com/Hypfer/Valetudo/commit/6a834c8ff888ab2c24516048c899f3bf42ec0290))\r\n* **vendor.dreame:** Handle sensor consumable push ([cc8b7a5](https://github.com/Hypfer/Valetudo/commit/cc8b7a5bc86014f61a6e792c69826e7ebed653db))\r\n* **vendor.dreame:** Handle sensor consumable push ([4276c36](https://github.com/Hypfer/Valetudo/commit/4276c3648e06a6951df9ee4f576db7cb1e5821bc))\r\n* **vendor.dreame:** Handle uploaded multi-map jsons ([01486b8](https://github.com/Hypfer/Valetudo/commit/01486b80292ddbafb9cae61f43ac19a0520e0a78))\r\n* **vendor.dreame:** Revert Fix status mapping ([8db8b6f](https://github.com/Hypfer/Valetudo/commit/8db8b6fd0dc22fc1b0cb23ec1052e1fa2e2ceae1))\r\n* **vendor.dreame:** Segments from rism might not apply in some situations ([e1161cf](https://github.com/Hypfer/Valetudo/commit/e1161cf6816db67306eff7ecf4935d36b2497347))\r\n* **vendor.dreame:** There actually is a difference between pause and stop ([6da5dc4](https://github.com/Hypfer/Valetudo/commit/6da5dc46a24b622b093af15024b729252b3c2e1d))\r\n* **vendor.roborock:** Add filename to map upload url ([90b7346](https://github.com/Hypfer/Valetudo/commit/90b73465159e65f89d94fce1096cf915b4903985))\r\n* **vendor.roborock:** Enable S7 Water Pump Control + No-Mop-Zones ([f699a55](https://github.com/Hypfer/Valetudo/commit/f699a558d49523f2683c08027538466c01b61ecc))\r\n* **vendor.roborock:** MapSnapshots are only available on Gen2 robots ([0752de2](https://github.com/Hypfer/Valetudo/commit/0752de2b862f697943171b4b56ba67ea0db3f203))\r\n* **vendor.roborock:** MapSnapshots IDs are strings in valetudo but numbers for roborock ([361dffa](https://github.com/Hypfer/Valetudo/commit/361dffacea59b76726ac93eb7a3296bb6905c763))\r\n* **webserver:** Remove unused parameter ([d27e3b1](https://github.com/Hypfer/Valetudo/commit/d27e3b1f626e935dcc1e279d300abc4517f45517))\r\n* Fix missing git commit id ([40ca9cb](https://github.com/Hypfer/Valetudo/commit/40ca9cb55884153c4ad582fd377cff863666d9f2))\r\n* Fix OOM-issues caused by SSE connections ([a0371f4](https://github.com/Hypfer/Valetudo/commit/a0371f4909b58403bf88fabecf2969d400c5487c))\r\n* Further tweak forced garbage collection ([c70393a](https://github.com/Hypfer/Valetudo/commit/c70393a4f19e296642ab1dd4540a3f4a64f931b4))\r\n* Further tweak SSE settings ([40d16f5](https://github.com/Hypfer/Valetudo/commit/40d16f5332f746f0d589ac530007c170eaa5a024))\r\n* Further tweak SSE settings ([cb8e01e](https://github.com/Hypfer/Valetudo/commit/cb8e01e20b195146b901f405fd87b3e45b3d69b6))\r\n* Resetting the map should also clear the Map cached by Valetudo ([e70041f](https://github.com/Hypfer/Valetudo/commit/e70041fd0318b4f8389db7b78bb4dc6bb6a75a05))\r\n* **vendor.roborock:** Multi-Map capable roborock robots use a different command for map resets ([2bbd86f](https://github.com/Hypfer/Valetudo/commit/2bbd86f9df27baeccb46580e3a24b08b02e28ab6))\r\n* Further tweak SSE settings ([8eae178](https://github.com/Hypfer/Valetudo/commit/8eae1786c9d85a10c3222144e1a9561141c10746))\r\n* **vendor.viomi:** Set correct env variables ([#979](https://github.com/Hypfer/Valetudo/issues/979)) ([5fd4a6a](https://github.com/Hypfer/Valetudo/commit/5fd4a6a618d6ea9b93991618a3f586ca4df76903))\r\n* **vendor.viomi:** Set correct ssh key location ([b15c707](https://github.com/Hypfer/Valetudo/commit/b15c707a8a7d9b344ba314a2109bc52531f0b395))\r\n* Try logging everything we can get about process memory before committing sudoku ([6578a99](https://github.com/Hypfer/Valetudo/commit/6578a99344a6d087450a0e4b45a630398fb3a544))\r\n* Tweak forced garbage collection ([d905864](https://github.com/Hypfer/Valetudo/commit/d905864f5e2b07579a0bcf6a13be649ec9e5c785))\r\n\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/998", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/46930477/reactions", + "total_count": 3, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 3, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/45189083/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.06.0", + "id": 45189083, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQ1MTg5MDgz", + "tag_name": "2021.06.0", + "target_commitish": "master", + "name": "Valetudo 2021.06.0", + "draft": false, + "prerelease": false, + "created_at": "2021-06-24T18:34:52Z", + "published_at": "2021-06-24T18:42:47Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173092", + "id": 39173092, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDky", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32315462, + "download_count": 98, + "created_at": "2021-06-24T18:54:23Z", + "updated_at": "2021-06-24T18:54:24Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173095", + "id": 39173095, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDk1", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11791774, + "download_count": 7, + "created_at": "2021-06-24T18:54:24Z", + "updated_at": "2021-06-24T18:54:25Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173084", + "id": 39173084, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDg0", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30067978, + "download_count": 321, + "created_at": "2021-06-24T18:54:19Z", + "updated_at": "2021-06-24T18:54:20Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173088", + "id": 39173088, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDg4", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 30067978, + "download_count": 167, + "created_at": "2021-06-24T18:54:21Z", + "updated_at": "2021-06-24T18:54:22Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173091", + "id": 39173091, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDkx", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11165330, + "download_count": 9, + "created_at": "2021-06-24T18:54:22Z", + "updated_at": "2021-06-24T18:54:23Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/39173086", + "id": 39173086, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM5MTczMDg2", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 11164986, + "download_count": 17, + "created_at": "2021-06-24T18:54:21Z", + "updated_at": "2021-06-24T18:54:21Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.06.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.06.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.06.0", + "body": "
\r\n \"valetudo\"\r\n

2021.06.0

\r\n
\r\n\r\nThis release features Swagger UI for proper REST API Documentation.\r\nAlso bugfixes and stability + performance improvements like the changelog of every single android app you have installed.\r\n\r\n## Swagger UI\r\n\r\n![image](https://user-images.githubusercontent.com/974410/123315997-9f21c580-d52c-11eb-8271-3f5ffd81931b.png)\r\n\r\n\r\nIn a tedious and brain-melting process, OpenAPI documentation was added to Valetudo.\r\nBy navigating to `ROBOT_IP/swagger/` you now have an interactive overview for the REST API, which directly lets you interface with the robot.\r\nThe schemas made for this are also used by the backend to validate every incoming request.\r\n\r\nSince staring at JSON Schemas all day is a pretty mind-numbing task, I didn't manage to also add examples for all responses and requests.\r\n\r\nI did however add examples for the Timers Endpoint, meaning that it is now easier to use those again.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/123316039-ab0d8780-d52c-11eb-9c17-34f20c944c16.png)\r\n\r\nUI support of course coming soon.\r\n\r\n## Config file Schema Validation\r\n\r\nThe new schemas are also used to validate the configuration file loaded by Valetudo.\r\nIf any errors arise, Valetudo will backup the config and create a new one using the defaults.\r\nThis will prevent issues with Valetudo not starting due to invalid configuration data.\r\n\r\nThe log will tell you what exactly was wrong in your config and where you can find the backup.\r\n\r\n\r\n## Other noteworthy changes\r\n\r\n### NodeJS v16.4.0\r\n\r\nThe Runtime was upgraded to v16.4.0 which brings v8 9.1 including the new Sparkplug thingy, which may result in CPU performance improvements.\r\n\r\n### MQTT ignores retained messages\r\n\r\nA common rookie mistake is that command MQTT messages are sent with the retain flag causing the robot to receive them on every reconnect.\r\nThis effectively executed a cleanup on each reboot at 4am.\r\n\r\nTo combat this, Valetudo will now simply ignore all retained messages received and complain about them in the logfile.\r\n\r\n### System REST Endpoints\r\n\r\nThere are new REST Endpoints providing system statistics such as Memory or CPU usage.\r\n\r\n`/api/v2/system/host/info`\r\n```json\r\n{\r\n \"hostname\": \"rockrobo\",\r\n \"arch\": \"arm\",\r\n \"mem\": {\r\n \"total\": 522792960,\r\n \"free\": 358219776,\r\n \"valetudo_current\": 59215872,\r\n \"valetudo_max\": 59699200\r\n },\r\n \"uptime\": 61036,\r\n \"load\": [\r\n 0.255,\r\n 0.2725,\r\n 0.28\r\n ]\r\n}\r\n```\r\n\r\n### Code Compression\r\n\r\nDue to the switch to `vercel/pkg` 5.3.0, Valetudo now uses the code compression feature, which results in smaller binaries.\r\n\r\n### Memory Usage\r\n\r\nMQTT Map compression is now streamed, which may or may not improve memory usage on 256mb ram robots.\r\n\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Ignore received retained message to work around common user errors ([26d8a4c](https://github.com/Hypfer/Valetudo/commit/26d8a4cd4c36410afabfda6f9e87e08fd01e9a28))\r\n* **mqtt:** Stream map serialization to improve memory usage with large maps ([98b2757](https://github.com/Hypfer/Valetudo/commit/98b2757aec0af94392038577eead7749ef659e17))\r\n* **timers:** Add endpoint which returns timer actions supported by this robot ([fe1fa88](https://github.com/Hypfer/Valetudo/commit/fe1fa88d715e1002d3ee607ce9646b8d8b2cdb9d))\r\n* **timers:** add ValetudoGoToTimerAction ([#953](https://github.com/Hypfer/Valetudo/issues/953)) ([d8a523e](https://github.com/Hypfer/Valetudo/commit/d8a523e40138f679411d2b8c33db3057d5f6c8d8))\r\n* **vendor.roborock:** Add support for the Roborock S7 ([c9ccb4a](https://github.com/Hypfer/Valetudo/commit/c9ccb4a11dc546da82684c5f2a80e96847ff2639))\r\n* **webserver:** Add SystemRouter ([efc46e6](https://github.com/Hypfer/Valetudo/commit/efc46e69001a2533077b1e30fd1d8f6de910e263))\r\n* **webserver:** Normalize reported system load ([b384ac3](https://github.com/Hypfer/Valetudo/commit/b384ac3038857f3e8677bac5859b8c1de99f80be))\r\n* **webserver:** Streamed compression of some heavy requests ([0d7d836](https://github.com/Hypfer/Valetudo/commit/0d7d8364b98e950d186d961062b81fbfff5e920a))\r\n* **webserver:** Validate actual endpoint existence against openApi schema ([f7cee31](https://github.com/Hypfer/Valetudo/commit/f7cee31eb20cba824d3fd2ed47cdb73a242de3f9))\r\n* Swagger Docs ([7842d9e](https://github.com/Hypfer/Valetudo/commit/7842d9ec0957a9a45f6c83ab357a901884b11ba1)), closes [#892](https://github.com/Hypfer/Valetudo/issues/892)\r\n* Validate configuration file and create a new one on error ([39e4613](https://github.com/Hypfer/Valetudo/commit/39e46137872f6774d2ebaf1120a10d0cddfff45b))\r\n\r\n### Bug Fixes\r\n\r\n* **configuration:** Add migration for invalid mqtt port type ([1220aa5](https://github.com/Hypfer/Valetudo/commit/1220aa5622dbf200ef2be88612f1e503ec887328))\r\n* **miio:** Allow setting new wifi credentials when provisioned ([32a12cf](https://github.com/Hypfer/Valetudo/commit/32a12cf82c698b64b3cc037a869f058fb4588f26)), closes [#657](https://github.com/Hypfer/Valetudo/issues/657)\r\n* **mqtt:** Calling GoTo Presets should use regular strings and not json strings ([ec975aa](https://github.com/Hypfer/Valetudo/commit/ec975aaec40c9857e7b35622253128ef75be3fbe)), closes [#960](https://github.com/Hypfer/Valetudo/issues/960)\r\n* **mqtt:** Use semaphore to avoid reconfigure race condition ([5b4b377](https://github.com/Hypfer/Valetudo/commit/5b4b377f98c5030aa13f2133b5a220c3366fae57))\r\n* **ntpclient:** Reduce loglevel of more error codes to avoid confusion ([ec4ee08](https://github.com/Hypfer/Valetudo/commit/ec4ee082eaba88d51d8948ebc97c0cb6e4347ed1))\r\n* **ui:** Allow resetting map when PersistentMapControl is unavailable ([#954](https://github.com/Hypfer/Valetudo/issues/954)) ([bc8feb9](https://github.com/Hypfer/Valetudo/commit/bc8feb936d373757093b79ed40ccd8b7318e8f67))\r\n* **ui:** Hide defunct zones button ([ae7c059](https://github.com/Hypfer/Valetudo/commit/ae7c05948c9cf7252bfedd1fe935c65d69a986b3))\r\n* **vendor.dreame:** Handle some previously unhandled messages ([810a212](https://github.com/Hypfer/Valetudo/commit/810a21226bb1580ed2afae9e2a2fad2b6faa475d))\r\n* **webserver:** Fix SystemRouter units ([fd908f6](https://github.com/Hypfer/Valetudo/commit/fd908f6da756d3d5a6f8350e1a4f4041990a6cf9))\r\n* **webserver:** os.freemem() isn't what it appears to be ([80743f4](https://github.com/Hypfer/Valetudo/commit/80743f455dd20d2abc316260308b9d322c33e284))\r\n* **webserver:** Properly report memory info for kernels older than 3.14 but newer than 2.6 ([9000f51](https://github.com/Hypfer/Valetudo/commit/9000f51eaf818ca465ad0b2ef9f91ca421ac2da4))\r\n\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/968", + "reactions": { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/45189083/reactions", + "total_count": 13, + "+1": 0, + "-1": 0, + "laugh": 0, + "hooray": 0, + "confused": 0, + "heart": 13, + "rocket": 0, + "eyes": 0 + } + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/43589051", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/43589051/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/43589051/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.05.0", + "id": 43589051, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQzNTg5MDUx", + "tag_name": "2021.05.0", + "target_commitish": "master", + "name": "Valetudo 2021.05.0", + "draft": false, + "prerelease": false, + "created_at": "2021-05-26T10:37:22Z", + "published_at": "2021-05-26T11:04:43Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565658", + "id": 37565658, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjU4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 36786214, + "download_count": 158, + "created_at": "2021-05-26T11:13:56Z", + "updated_at": "2021-05-26T11:13:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565661", + "id": 37565661, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjYx", + "name": "valetudo-aarch64.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 16387654, + "download_count": 9, + "created_at": "2021-05-26T11:13:57Z", + "updated_at": "2021-05-26T11:13:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-aarch64.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565650", + "id": 37565650, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjUw", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34465042, + "download_count": 400, + "created_at": "2021-05-26T11:13:51Z", + "updated_at": "2021-05-26T11:13:52Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565653", + "id": 37565653, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjUz", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34465042, + "download_count": 181, + "created_at": "2021-05-26T11:13:54Z", + "updated_at": "2021-05-26T11:13:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7-lowmem" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565656", + "id": 37565656, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjU2", + "name": "valetudo-armv7-lowmem.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 15746822, + "download_count": 13, + "created_at": "2021-05-26T11:13:55Z", + "updated_at": "2021-05-26T11:13:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7-lowmem.upx" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/37565651", + "id": 37565651, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM3NTY1NjUx", + "name": "valetudo-armv7.upx", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 15746694, + "download_count": 11, + "created_at": "2021-05-26T11:13:53Z", + "updated_at": "2021-05-26T11:13:53Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.05.0/valetudo-armv7.upx" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.05.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.05.0", + "body": "
\r\n \"valetudo\"\r\n

2021.05.0

\r\n
\r\n\r\nThis release features mostly bugfixes, unfinished features and a hostile takeover.\r\n\r\n## MQTT Rewrite\r\n\r\nDue to the scale of the MQTT rewrite that happened with 2021.04.0, some new bugs were introduced, which have been fixed with this release.\r\n\r\nFurthermore, this release removes the migration logic of the old mqtt config format so if you're planning on upgrading from something other than 2021.04.0, make sure to upgrade to that before installing 2021.05.0.\r\n\r\nAs always, reading all the release notes is strongly recommended during upgrades.\r\n\r\n## Not-yet finished things\r\n\r\nNot everything in this section is already part of this release.\r\n\r\n### UI Rewrite\r\n\r\n@jomik is still working on the rewrite of the Valetudo UI. It's already looking fantastic:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/119648987-635ae980-be22-11eb-82c9-3b1c999303c4.png)\r\n![image](https://user-images.githubusercontent.com/974410/119649000-6655da00-be22-11eb-831a-cb816a3991be.png)\r\n\r\n\r\nIf you're a frontend dev, a design person etc., feel free to join in. :)\r\nWe'll definitely need some design input, custom icons and much more stuff.\r\n\r\n### Timers\r\n\r\nA simple scheduler feature has been added to the backend for setups where a full-blown home automation system isn't required.\r\nThese shall be understood as WIP and can currently only be controlled [via REST API calls](https://github.com/Hypfer/Valetudo/discussions/824#discussioncomment-761574).\r\n\r\n### Dreame Support\r\n\r\nPublic root coming soon™, again.\r\n\r\nThe beta test has been expanded to more users. If you want to take part in that, make sure to join the [Telegram Dreame Usergroup](https://t.me/joinchat/2qGFUaQ2pV9hNzUy) and check out the pinned form.\r\nCurrently, the announcement of the Dreame W10 and Z10 is delaying the release of the rooting method.\r\n\r\n## Freenode hostile takeover\r\n\r\nAs you might've heard, Freenode, the FOSS IRC network has been taken over by the crown prince of korea, who decided to have some fun with it.\r\n\r\nToday, the #Valetudo Freenode channel was also taken over:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/119649150-97360f00-be22-11eb-9508-2dfb93ea39be.png)\r\n\r\n\r\nThere are other and much more popular victims of this:\r\n\r\n- https://mastodon.sdf.org/@kline/106299403921451814\r\n- https://news.ycombinator.com/item?id=27286628\r\n- https://twitter.com/fosdem/status/1397454352835653632\r\n\r\nI've left the network and strongly advice you to do the same.\r\n[https://libera.chat/](https://libera.chat/) is the continuation of Freenode with a different name, but the same Team that has been running Freenode for the last 20 years.\r\n\r\nFreenode on the other hand is just the same name but with completely different people.\r\n\r\nStick to the community. Not to the brand.\r\n\r\nFor more information, check out some of the resignation letters of the former freenode and current libera staff:\r\n\r\n- kline: https://www.kline.sh/\r\n- jess: https://gist.github.com/jesopo/45a3e9cdbe517dc55e6058eb43b00ed9\r\n- Md: https://blog.bofh.it/debian/id_461\r\n- niko: https://coevoet.fr/freenode.html\r\n- edk: https://gist.github.com/edk0/478fb4351bc3ba458288d6878032669d\r\n- emilsp: https://gist.github.com/pinkisemils/39d4ded8b1639b6f39dcab15618649f5\r\n- mniip: https://mniip.com/freenode.txt\r\n- Swant: https://swantzter.se/freenode-resignation/\r\n- JonathanD: https://gist.github.com/JonathanD82/6518b93708e0aaf4b8f92c8e7200816d\r\n\r\nThere's also a neat FAQ by @joepie91: https://gist.github.com/joepie91/df80d8d36cd9d1bde46ba018af497409\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **vendor.dreame:** Add iteration count to MapSegmentationCapability ([05b338f](https://github.com/Hypfer/Valetudo/commit/05b338f069feb7c311dcc11d7b50d91e310e79d3))\r\n* Timers ([7b8c37a](https://github.com/Hypfer/Valetudo/commit/7b8c37ad1006aec62e1f19e5aec83d54da94189d))\r\n* **ntpClient:** Keep track of the current state and enable configuration via REST ([e350eba](https://github.com/Hypfer/Valetudo/commit/e350eba43ab36076d406c02f933c7be108cc8e99))\r\n* **vendor.dreame:** 1C: Add/fix various Map & Volume capabilities ([#915](https://github.com/Hypfer/Valetudo/issues/915)) ([c88df12](https://github.com/Hypfer/Valetudo/commit/c88df12de41ec05797adeb4c5215bf4d18456c9b))\r\n* **vendor.roborock:** Add support for ordered segment cleanup with multiple iterations ([2541113](https://github.com/Hypfer/Valetudo/commit/25411138688454d43026d07c12e46b5eab5e9269))\r\n* **vendor.viomi:** Implement DND capability ([#877](https://github.com/Hypfer/Valetudo/issues/877)) ([dd05c51](https://github.com/Hypfer/Valetudo/commit/dd05c51f4dfa45ffdf973b95e6b4851e423a176c))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Better map upload logline ([0e7ce7c](https://github.com/Hypfer/Valetudo/commit/0e7ce7c7486498c55dd0443dd9cb0251fde1dab2))\r\n* **mqtt:** Allow strings as segment IDs ([#891](https://github.com/Hypfer/Valetudo/issues/891)) ([3e30414](https://github.com/Hypfer/Valetudo/commit/3e304146980c8dc2a394a54e7346528ec5a07620)), closes [#889](https://github.com/Hypfer/Valetudo/issues/889)\r\n* **mqtt:** Always publish state ([6a041c6](https://github.com/Hypfer/Valetudo/commit/6a041c62cfff4d2b04eb48e15ee20373512838fe))\r\n* **mqtt:** Only migrate HAss topics if enabled ([#912](https://github.com/Hypfer/Valetudo/issues/912)) ([eb2edaf](https://github.com/Hypfer/Valetudo/commit/eb2edaf969a175648cb0f53405b1780f0ac799d2))\r\n* **mqtt:** Publish state for both hass and homie, as the hass device availability_topic is set to the same topic ([#860](https://github.com/Hypfer/Valetudo/issues/860)) ([219bc34](https://github.com/Hypfer/Valetudo/commit/219bc348e95d78ff7dd279c52d498401b5e9d28c))\r\n* **mqtt:** Remove unnecessary availability_topic ([#859](https://github.com/Hypfer/Valetudo/issues/859)) ([aa85205](https://github.com/Hypfer/Valetudo/commit/aa85205fe09007b4b411ef9de754513dda98a4a0)), closes [#858](https://github.com/Hypfer/Valetudo/issues/858)\r\n* **ntpClient:** Support disabling the ntpClient ([949d8e3](https://github.com/Hypfer/Valetudo/commit/949d8e306b5de34c3a3755532f269f009eb50c51)), closes [#925](https://github.com/Hypfer/Valetudo/issues/925)\r\n* **timers:** Copy-paste antipattern ([e331eda](https://github.com/Hypfer/Valetudo/commit/e331eda332e12a138cd1d7e8b8994208f714833a))\r\n* **timers:** Fix zoned scheduled cleanup ([34443b3](https://github.com/Hypfer/Valetudo/commit/34443b3bea4feac5c48844554cd9a816df6f60ff))\r\n* **ui:** DND should be rendered as localtime but stored as UTC ([fd79163](https://github.com/Hypfer/Valetudo/commit/fd79163c3e9328562346a789ad5cec6e73bfe52d))\r\n* **vendor.dreame:** Ignore uploaded multi-map data ([6f3dcc5](https://github.com/Hypfer/Valetudo/commit/6f3dcc5a9a2a39eed6dcc73f2f08d1f438b09cac))\r\n* **vendor.roborock:** Handle DND as UTC ([8fc9ea8](https://github.com/Hypfer/Valetudo/commit/8fc9ea88d81505259f53e0dad5be3ed0e05d5d6f))\r\n* **vendor.roborock:** Roborock only accepts int coordinates ([c7efd6a](https://github.com/Hypfer/Valetudo/commit/c7efd6af1379de2e94594c440c126b74a36a7962))\r\n* Print error message when failing to load config file ([#914](https://github.com/Hypfer/Valetudo/issues/914)) ([9ebda7e](https://github.com/Hypfer/Valetudo/commit/9ebda7eb52185c5d8474344f0e25a653003c1d87))\r\n* **vendor.roborock:** Remove invalid RoborockCombinedVirtualRestrictionsCapability from V1 robot ([5a2bae4](https://github.com/Hypfer/Valetudo/commit/5a2bae404dfebf5e641a3e490e50f7bd254f633b))\r\n* **vendor.viomi:** Fix system timezone in init script ([#876](https://github.com/Hypfer/Valetudo/issues/876)) ([908d5dd](https://github.com/Hypfer/Valetudo/commit/908d5ddc16b03dbe92e1aafe9e0d4f755312e3d4))\r\n* **vendor.viomi:** Syntax error in init script ([2d53b7c](https://github.com/Hypfer/Valetudo/commit/2d53b7cf8a4e25764795859f88f6b4bb24a291e1))\r\n* **vendor.viomi:** Viomi minor bugfixes ([#820](https://github.com/Hypfer/Valetudo/issues/820)) ([4742214](https://github.com/Hypfer/Valetudo/commit/47422140a77e4253606e1e0f360eaaaebb6831f7))\r\n", + "discussion_url": "https://github.com/Hypfer/Valetudo/discussions/944" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/41971628", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/41971628/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/41971628/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.04.0", + "id": 41971628, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTQxOTcxNjI4", + "tag_name": "2021.04.0", + "target_commitish": "master", + "name": "Valetudo 2021.04.0", + "draft": false, + "prerelease": false, + "created_at": "2021-04-25T16:42:16Z", + "published_at": "2021-04-25T17:40:22Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/35800383", + "id": 35800383, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM1ODAwMzgz", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 34350491, + "download_count": 274, + "created_at": "2021-04-25T17:41:05Z", + "updated_at": "2021-04-25T17:41:05Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.04.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/35800380", + "id": 35800380, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM1ODAwMzgw", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32577571, + "download_count": 605, + "created_at": "2021-04-25T17:41:02Z", + "updated_at": "2021-04-25T17:41:03Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.04.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/35800381", + "id": 35800381, + "node_id": "MDEyOlJlbGVhc2VBc3NldDM1ODAwMzgx", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32577571, + "download_count": 391, + "created_at": "2021-04-25T17:41:03Z", + "updated_at": "2021-04-25T17:41:04Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.04.0/valetudo-armv7-lowmem" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.04.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.04.0", + "body": "
\r\n \"valetudo\"\r\n

2021.04.0

\r\n
\r\n\r\nThis release features a complete rewrite of the MQTT interface, which brings superior OpenHAB support by fully\r\nimplementing the Homie specification, Segment renaming, Water Usage Controls, No-Mop-Zones, UI improvements and better\r\nstability in low-mem environments such as the Roborock S5 Max\r\n\r\n## Newcomer Guide\r\n\r\nTo answer common questions newcomers or people that haven't actively been following the project may have, there's now\r\nthe [Valetudo Newcomer Guide Early 2021 Edition](https://valetudo.cloud/pages/general/newcomer_guide_early_2021.html) in the docs.\r\n\r\n## MQTT Rewrite\r\n\r\n@depau has spent countless hours completely rewriting the MQTT Interface of Valetudo.\r\nNote that this is a breaking change and will require additional attention from you on upgrade.\r\n\r\nWe're now fully [Homie-compatible](https://homieiot.github.io) which brings much better support for Home Automation systems other than Home Assistant such as [OpenHAB](https://www.openhab.org/) which has recently been completely overhauled.\r\nMake sure to check out [their new demo](https://demo.openhab.org/) as well as the [Valetudo OpenHAB integration docs](https://valetudo.cloud/pages/integrations/openhab-integration.html).\r\n\r\nIf you're using something else such as FHEM or ioBroker, the new Homie MQTT implementation should also be much easier to work with.\r\nDocumentation on the new MQTT schema can be found in the [MQTT Docs](https://valetudo.cloud/pages/integrations/mqtt.html).\r\n\r\nDavide also went the extra mile and wrote an excellent [developer documentation for the new MQTT feature](https://valetudo.cloud/pages/development/mqtt.html) which is a must-read if you want to contribute to that part of Valetudo.\r\n\r\n### Home Assistant MQTT Rewrite FAQ\r\n\r\nValetudo will try its best to auto-migrate your configuration file and Home Assistant configuration.\r\nHowever, the latter may not work 100% all the time. Therefore, here's an FAQ for Home Assistant users migrating to Valetudo 2021.04.0\r\n\r\nQ: Home Assistant now shows everything as unavailable.\r\nA: Refresh the page\r\n\r\nQ: The consumables do not update in Home Assistant\r\nA: Wait one minute, or open valetudo and navigate to the consumables page\r\n\r\nQ: ICBINV does not seem to be retrieving the map\r\nA: The map topic changed, it is now TOPIC_PREFIX/IDENTIFIER/MapData/map-data, update your ICBINV config and ICBINV to 2021.04.0\r\n\r\nQ: Some stuff is still not detected by Home Assistant\r\nA: Reset the autodiscovery configuration by performing the following:\r\n1. Go to the MQTT settings\r\n2. Disable MQTT, enable \"Delete autodiscovery on shutdown\" under \"Home Assistant Autodscovery\".\r\n3. Save MQTT configuration\r\n4. Check Hass to ensure everything has disappeared, refresh the page as needed.\r\n5. Enable MQTT, disable \"Delete autodiscovery on shutdown\" under \"Home Assistant Autodscovery\".\r\n6. Save MQTT configuration\r\n\r\nQ: `vacuum.send_command` doesn't work anymore\r\nA: Yep. The docs will be updated shortly with information on how to achieve the same stuff now\r\n\r\n## Segment Renaming\r\n\r\nValetudo now supports (re-)naming segments and cleaning them from the UI Homepage in the same way you'd trigger a\r\nZonePreset cleanup.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/116003253-844ed580-a5fd-11eb-9ef1-4325a0104996.png)\r\n\r\n## Water Usage Control and No-Mop Zones\r\n\r\nIt is now possible to control the water grades of your robot using Valetudo, which is a completely new feature\r\nthat never appeared elsewhere before :^)\r\n\r\nFurthermore, no-mop-zones are back as well.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/116003434-38e8f700-a5fe-11eb-8273-39f8f713479d.png)\r\n![image](https://user-images.githubusercontent.com/974410/116003272-9d578680-a5fd-11eb-9c4d-8d954bec7913.png)\r\n\r\n\r\n## Lowmem enhancements\r\n\r\nAs it turns out, running nodejs in very resource-limited embedded environments such as vacuum robots isn't exactly\r\nthe intended core use-case of the runtime, which is why we seem to be pushing the limits especially on devices with\r\nonly 256mb ob ram such as the Roborock S5 Max.\r\n\r\nAnother surprising discovery is that Nodejs Buffers are not part of the configured heap, which is why even though we've\r\nset the maximum heap size to under 40mb, in some cases, the rss of Valetudo grew to over 100mb, which then caused some\r\nrobots to go out of memory.\r\n\r\nFor some reason, the garbage collector simply doesn't care about old and unused Buffers even if the memory pressure rises.\r\nTherefore, for now, we're forcing a manual garbage collection if the memory usage seems odd.\r\n\r\nThis significantly improved the stability on the S5 Max and is now enabled for all builds.\r\nStill, I'd recommend choosing the lowmem build for 256mb ram roborock robots.\r\n\r\n## UI\r\n\r\nStuff such as Virtual Walls will now snap to reasonable angles on creation so that you don't get virtual walls that are infuriatingly almost straight but not quite.\r\n\r\n## Musl\r\n\r\nThanks to recent changes in vercel/pkg, the nodejs base binaries used are now statically linked against musl instead of glibc,\r\nwhich apart from being neat enables us to drop the DNSHack.\r\n\r\nAlso, we've upgraded the runtime to Node v14.16.1\r\n\r\n## Dreame Support\r\n\r\nThe Dreame 1c support has been greatly improved thanks to the help of @frankZZ\r\n\r\nPublic root coming soon™\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Collect our own garbage ([3c3df9a](https://github.com/Hypfer/Valetudo/commit/3c3df9a584cdb7193715b583fbb90c9dcd8591ca))\r\n* **core:** MapSegmentRenameCapability ([6371291](https://github.com/Hypfer/Valetudo/commit/63712911c5a81584fc6482ac94d587aa35e5bfbb))\r\n* **MockRobot:** add GoToLocationCapability and MockMap ([2957e25](https://github.com/Hypfer/Valetudo/commit/2957e25bb57c9f9c8f8c68dcf4691900b4e68544))\r\n* **MockRobot:** add MapResetCapability ([531498b](https://github.com/Hypfer/Valetudo/commit/531498b47327ddf4be6337806e68020eafa597eb))\r\n* **MockRobot:** Add MockCarpetModeControlCapability ([#759](https://github.com/Hypfer/Valetudo/issues/759)) ([5bd5fb7](https://github.com/Hypfer/Valetudo/commit/5bd5fb7a99988cc6f0db7d2ed2d39b16d756cca7))\r\n* **MockRobot:** Add MockConsumableMonitoringCapability ([6d8b8e0](https://github.com/Hypfer/Valetudo/commit/6d8b8e092ad31190c111c7a0b12f5acbcb319b5b))\r\n* **MockRobot:** Add MockDoNotDisturbCapability ([f85194c](https://github.com/Hypfer/Valetudo/commit/f85194c0192a8a0d5b6b0058f6250841eb08d89f))\r\n* **MockRobot:** Add MockWifiConfigurationCapability ([accba05](https://github.com/Hypfer/Valetudo/commit/accba051906cdb111e734bf1950484f918562e9c))\r\n* **MockRobot:** add PersistentMapControlCapability ([f91e8e7](https://github.com/Hypfer/Valetudo/commit/f91e8e7e38d0a14de7f22fd432ef14cb8dd5d09f))\r\n* **MockRobot:** Add speaker capabilities ([12d1a27](https://github.com/Hypfer/Valetudo/commit/12d1a27119fad31a9f4d3b56c3a73b9f0cde24f2))\r\n* **mqtt:** Add MapSegmentationCapabilityMqttHandle ([#842](https://github.com/Hypfer/Valetudo/issues/842)) ([0534888](https://github.com/Hypfer/Valetudo/commit/0534888b23295d031fac7358a1846a0355b7b504))\r\n* **mqtt:** Add vacuum error state description property ([#850](https://github.com/Hypfer/Valetudo/issues/850)) ([14793c7](https://github.com/Hypfer/Valetudo/commit/14793c7744aa38f83de5c8eab88b0abfebd1edb1)), closes [#816](https://github.com/Hypfer/Valetudo/issues/816)\r\n* **mqtt:** Await MQTT disconnect before proceeding with shutdown ([1c0410c](https://github.com/Hypfer/Valetudo/commit/1c0410c1d6fe0554609baaaa521ebe9d300fe5f3))\r\n* **mqtt:** Provide segment information ([f104189](https://github.com/Hypfer/Valetudo/commit/f1041890164d451d7ee9e6c8a991a8f360bd394c))\r\n* **mqtt:** Remove increase/decrease from intensity capability ([#843](https://github.com/Hypfer/Valetudo/issues/843)) ([e6fd6e4](https://github.com/Hypfer/Valetudo/commit/e6fd6e4534db0366078b7cd7797dc0f0051ade99))\r\n* **ui:** Add dialog for renaming segments ([#772](https://github.com/Hypfer/Valetudo/issues/772)) ([306b8ba](https://github.com/Hypfer/Valetudo/commit/306b8ba9c27331bb79f886b468b0edadd86c1e70))\r\n* **ui:** add Segments on home ([2129e22](https://github.com/Hypfer/Valetudo/commit/2129e2278362424f42eab7c2062094461911f720)), closes [#773](https://github.com/Hypfer/Valetudo/issues/773)\r\n* **ui:** capitalize robot states in UI ([#765](https://github.com/Hypfer/Valetudo/issues/765)) ([c988e69](https://github.com/Hypfer/Valetudo/commit/c988e6992d85b84a1d24c1f01b097d7734ac6603))\r\n* **ui:** Generate consumables list dynamically ([#764](https://github.com/Hypfer/Valetudo/issues/764)) ([05d658b](https://github.com/Hypfer/Valetudo/commit/05d658bc90fb8a4fee13a81caae4fb2a0fb5de8c))\r\n* **ui:** Snap zones and walls to grid and reasonable angles to implement [#796](https://github.com/Hypfer/Valetudo/issues/796) ([25836e8](https://github.com/Hypfer/Valetudo/commit/25836e87b70e9065d943daf1ce85478bee179074))\r\n* **ui:** Toggle button states depending on Robot Capabilities ([#769](https://github.com/Hypfer/Valetudo/issues/769)) ([cc66d52](https://github.com/Hypfer/Valetudo/commit/cc66d5292f1ba0306e8b5362b63860d177fb5b0f))\r\n* **ui:** Water Usage Control ([cf375ce](https://github.com/Hypfer/Valetudo/commit/cf375ceeb65ace4f0cbe99a7ef58d865426e6e07))\r\n* **vendor.dreame:** 1C voicepack install support ([#795](https://github.com/Hypfer/Valetudo/issues/795)) ([b72ca53](https://github.com/Hypfer/Valetudo/commit/b72ca53f99bfa94f693c1b9c36a904cc417c2533))\r\n* **vendor.dreame:** Add Dreame F9 ([4fe0ff7](https://github.com/Hypfer/Valetudo/commit/4fe0ff7fd952533a073cd51432626f99aeadd856))\r\n* **vendor.dreame:** Add more 1C variants ([9e2e194](https://github.com/Hypfer/Valetudo/commit/9e2e194bcdacc141fc87e5c49489eb669de9c8a9))\r\n* **vendor.dreame:** Add MOVA Z500 ([0107932](https://github.com/Hypfer/Valetudo/commit/01079324727b71acd17eb8d8b16a2547663179b3))\r\n* **vendor.dreame:** DreameCarpetModeControlCapability ([2d674d4](https://github.com/Hypfer/Valetudo/commit/2d674d4d6381f9ca7f146d71445e671f14195773))\r\n* **vendor.dreame:** DreameMapResetCapability ([f60fe24](https://github.com/Hypfer/Valetudo/commit/f60fe242ba8b2bba4560a7c91443ba0c07dbd133))\r\n* **vendor.dreame:** DreameWaterUsageControlCapability ([8be7cd4](https://github.com/Hypfer/Valetudo/commit/8be7cd437bcd2cb938ea5798f767b112c22f87b5))\r\n* **vendor.viomi:** Add viomi.vacuum.v6 to supported devices ([#849](https://github.com/Hypfer/Valetudo/issues/849)) ([a18633c](https://github.com/Hypfer/Valetudo/commit/a18633c97bb3897ecf60d6736b68ab9f9477a3ed)), closes [#848](https://github.com/Hypfer/Valetudo/issues/848)\r\n* **webserver:** Add X-Valetudo-Version header ([d494510](https://github.com/Hypfer/Valetudo/commit/d494510e0209f743e5f8bc8bef898a9e787bf9db))\r\n* Debug capability ([#813](https://github.com/Hypfer/Valetudo/issues/813)) ([4866475](https://github.com/Hypfer/Valetudo/commit/48664757035ebd0a6493c3de5433c02eb197800e))\r\n* Remove DNSHack since we're using musl now ([79194b6](https://github.com/Hypfer/Valetudo/commit/79194b690d27d4ba012536564ed35cad4d3df3b4))\r\n* SSE Endpoints for State and StateAttributes ([c90d426](https://github.com/Hypfer/Valetudo/commit/c90d426cb96c26b2326d64e2a7da27694ea08014))\r\n* **vendor.dreame:** 1C active zone & segments ([2281701](https://github.com/Hypfer/Valetudo/commit/22817015de62d93a9aaf46fb9fa4304d66603d6e))\r\n* **vendor.dreame:** DreameMapSegmentRenameCapability ([1470c53](https://github.com/Hypfer/Valetudo/commit/1470c539d3fb0425906b989f59adaad4b9efa739))\r\n* **vendor.dreame:** Implement/setup most capabilities of the 1C ([256b907](https://github.com/Hypfer/Valetudo/commit/256b9076a3727e3f85bfc8412e296e8009a42052))\r\n* **vendor.dreame:** Update 1C properties_changed handling ([83dddfe](https://github.com/Hypfer/Valetudo/commit/83dddfe402183456d50781435b154281d03acf1e))\r\n* **vendor.dreame:** Use currently configured water grade and fanspeed when starting a zone or segment cleanup ([200b13b](https://github.com/Hypfer/Valetudo/commit/200b13b5c8434375db486b93067278ddca490a42))\r\n* **vendor.roborock:** RoborockManualControlCapability ([59b9bd5](https://github.com/Hypfer/Valetudo/commit/59b9bd5e7a315c21f459613a9f09e8f50787ab7b))\r\n* **vendor.roborock:** RoborockMapSegmentRenameCapability ([4d6a1a4](https://github.com/Hypfer/Valetudo/commit/4d6a1a415c67c2d4e43f8220f7babe18e322e641))\r\n* **vendor.roborock:** RoborockWaterUsageControlCapability ([fdebd3c](https://github.com/Hypfer/Valetudo/commit/fdebd3c45df68797b353866dfd7a1e8684600a99))\r\n* **vendor.viomi:** Add MapResetCapability ([#785](https://github.com/Hypfer/Valetudo/issues/785)) ([696d76b](https://github.com/Hypfer/Valetudo/commit/696d76be682a905c809298c86032041243a2e1fe))\r\n* **vendor.viomi:** Add ViomiMapSegmentationCapability ([#762](https://github.com/Hypfer/Valetudo/issues/762)) ([1a9eef4](https://github.com/Hypfer/Valetudo/commit/1a9eef40b34fe991ed26989033daafdd8ace856d))\r\n* **vendor.viomi:** Add ViomiMapSegmentRenamenCapability ([0123f24](https://github.com/Hypfer/Valetudo/commit/0123f245bf6b7cedabaebf61da15f1959727c9e8))\r\n* **vendor.viomi:** Manual control capability ([#740](https://github.com/Hypfer/Valetudo/issues/740)) ([a5324e8](https://github.com/Hypfer/Valetudo/commit/a5324e8ece40709be7168730ef77978c3f971d94))\r\n* **vendor.viomi:** ViomiMapSegmentEditCapability ([#766](https://github.com/Hypfer/Valetudo/issues/766)) ([a210b0e](https://github.com/Hypfer/Valetudo/commit/a210b0edcadc29e7ab82e29258b2594fc622c53c))\r\n* no-mop zones ([f011023](https://github.com/Hypfer/Valetudo/commit/f0110231fe84f9ae7d7ed219bcece1bf387f2088))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **core:** Add name to ValetudoMapSegment ([e9da2cf](https://github.com/Hypfer/Valetudo/commit/e9da2cf5ea2cc408365fc96fb34430fcf73585d4))\r\n* **core:** Lowmem enhancements ([5787afa](https://github.com/Hypfer/Valetudo/commit/5787afa34d281e709dbe7e5f81af33e5623154e0))\r\n* **core:** Segment IDs should be strings ([97c832e](https://github.com/Hypfer/Valetudo/commit/97c832ea527665459ad9e3eb2c8f562f70a08478))\r\n* **miio:** Improve error message on missing keys in device.conf ([7ed177a](https://github.com/Hypfer/Valetudo/commit/7ed177a85ac50ec23a913c5265511e9adf839f8a))\r\n* **mqtt:** Await close event before considering MQTT closed ([1afa717](https://github.com/Hypfer/Valetudo/commit/1afa717d6e4815ba773200523324a8e835cc382d))\r\n* **mqtt:** Do not disconnect on cfg reload if not connected ([5c74342](https://github.com/Hypfer/Valetudo/commit/5c74342f94774333b42398c9a4373015bf9bbc4d))\r\n* **mqtt:** Handle nested reconfiguration ([#841](https://github.com/Hypfer/Valetudo/issues/841)) ([c0ff5ce](https://github.com/Hypfer/Valetudo/commit/c0ff5ce03fdcdf282f56adfabf3362bae5de38c6))\r\n* **mqtt:** Make BasicCtl actually home when HOME is sent ([8272dd5](https://github.com/Hypfer/Valetudo/commit/8272dd59e0fcbfd75ad75c0b992b56469cab2c53))\r\n* **mqtt:** Map zone presets to zones ([#839](https://github.com/Hypfer/Valetudo/issues/839)) ([8ac882f](https://github.com/Hypfer/Valetudo/commit/8ac882f75e3b4c67bc2a9192f28074e4609aaa58))\r\n* **mqtt:** Remove test leftovers from consumable monitoring ([#831](https://github.com/Hypfer/Valetudo/issues/831)) ([ec289a0](https://github.com/Hypfer/Valetudo/commit/ec289a08de38f4e24bfab61f2467cee9d99e2cba))\r\n* **ui:** instead of hiding settings based on capabilities at page load, unhide at page load ([#774](https://github.com/Hypfer/Valetudo/issues/774)) ([e5f0f4f](https://github.com/Hypfer/Valetudo/commit/e5f0f4fe2494ab7faf6825f54bfd38b8217d40e1))\r\n* **vendor.roborock:** do not send empty layers ([#809](https://github.com/Hypfer/Valetudo/issues/809)) ([a2e1c21](https://github.com/Hypfer/Valetudo/commit/a2e1c21bcc3dbf12a83fdaea84701b98d9387c17))\r\n* **vendor.roborock:** Don't store null to this.state.map on map parse failure ([ae4bf24](https://github.com/Hypfer/Valetudo/commit/ae4bf248d6c3848abae0a6ebc039aa2f0efc6bbc))\r\n* **vendor.roborock:** Fix segment rename ([0bed81a](https://github.com/Hypfer/Valetudo/commit/0bed81ab4f0ddccdad044ce805dda3af8736eb96))\r\n* **vendor.roborock:** Fix V1 capabilities ([6cdcc1e](https://github.com/Hypfer/Valetudo/commit/6cdcc1eb00a414d5f450c83f27f0267c082e7099))\r\n* **vendor.roborock:** Renaming map segments always requires the full list of names ([559d1ad](https://github.com/Hypfer/Valetudo/commit/559d1ada913e04258217134f3c7aa148d7eb7e21))\r\n* **vendor.roborock:** Roborock expects a number as the segmentId ([1e6db81](https://github.com/Hypfer/Valetudo/commit/1e6db81e71d43bf2060dec7ff90173a4cdc6e150))\r\n* **vendor.viomi:** Don't store paths with zero points ([77e7128](https://github.com/Hypfer/Valetudo/commit/77e712813191bc427306c80bf79f1b81f47202fd))\r\n* **vendor.viomi:** Fix \"Unknown water grade\" ([#784](https://github.com/Hypfer/Valetudo/issues/784)) ([04f2df4](https://github.com/Hypfer/Valetudo/commit/04f2df4c1cb546d195f3414c79557fcf0d320ae1))\r\n* **vendor.viomi:** Fix basic control functionality ([#782](https://github.com/Hypfer/Valetudo/issues/782)) ([a0fa7f4](https://github.com/Hypfer/Valetudo/commit/a0fa7f49f7f0779357c3ce61d354badd5bac07ed))\r\n* **vendor.viomi:** Fix last clean time ([#822](https://github.com/Hypfer/Valetudo/issues/822)) ([21b5876](https://github.com/Hypfer/Valetudo/commit/21b5876362939fc2e0d7ee7edbb4651411be39da))\r\n* **vendor.viomi:** Fix map issues (hopefully) ([#819](https://github.com/Hypfer/Valetudo/issues/819)) ([07a1c7a](https://github.com/Hypfer/Valetudo/commit/07a1c7ad78e3593b90e12ba0bb8286ed0c4f58e1))\r\n* **vendor.viomi:** Fix operation mode selection ([710758d](https://github.com/Hypfer/Valetudo/commit/710758d4840b06b3bff3bfb1e7dd521e48fa3d3b))\r\n* **vendor.viomi:** Fix water grade controlling fan speed instead ([#791](https://github.com/Hypfer/Valetudo/issues/791)) ([3f4d844](https://github.com/Hypfer/Valetudo/commit/3f4d844c2979527624623bb2ff67654a0961f768))\r\n* **vendor.viomi:** Increase timeout for set_timezone ([#806](https://github.com/Hypfer/Valetudo/issues/806)) ([a128a91](https://github.com/Hypfer/Valetudo/commit/a128a91499d94f0e75d17f87396571f6c889a7ac)), closes [#799](https://github.com/Hypfer/Valetudo/issues/799)\r\n* **vendor.viomi:** Raise default miIO timeout ([#817](https://github.com/Hypfer/Valetudo/issues/817)) ([5f6068d](https://github.com/Hypfer/Valetudo/commit/5f6068d7790a8f3f322f4825493608605ed80a63))\r\n* **vendor.viomi:** replace fanSpeeds with waterGrades ([#825](https://github.com/Hypfer/Valetudo/issues/825)) ([2b5d3e6](https://github.com/Hypfer/Valetudo/commit/2b5d3e69b9ea9a1ab966efc67652f55e638bf0f4))\r\n* **vendor.viomi:** Viomi segment edit fixes ([#821](https://github.com/Hypfer/Valetudo/issues/821)) ([5c8495c](https://github.com/Hypfer/Valetudo/commit/5c8495ce2eff247a667e87b2649c98ee13bddf28))\r\n* Improve state handling in MockConsumableMonitoringCapability ([1138c84](https://github.com/Hypfer/Valetudo/commit/1138c8466ca776960e0dc6030b1efe5f6e8343f2))\r\n* MapParsers should not return empty path map entities ([371ceea](https://github.com/Hypfer/Valetudo/commit/371ceea9e4e7b591b19b0dc3d4887feca3ab8692))\r\n* Typo in ConsumableStateAttribute ([7d64a1a](https://github.com/Hypfer/Valetudo/commit/7d64a1a90407d555cdd84eca6d1fae2ed828d5e2))\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/39835836", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/39835836/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/39835836/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.03.0", + "id": 39835836, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM5ODM1ODM2", + "tag_name": "2021.03.0", + "target_commitish": "master", + "name": "Valetudo 2021.03.0", + "draft": false, + "prerelease": false, + "created_at": "2021-03-15T17:48:10Z", + "published_at": "2021-03-15T18:15:42Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/33495678", + "id": 33495678, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMzNDk1Njc4", + "name": "valetudo-aarch64", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 36243394, + "download_count": 508, + "created_at": "2021-03-15T18:16:57Z", + "updated_at": "2021-03-15T18:16:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.03.0/valetudo-aarch64" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/33495673", + "id": 33495673, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMzNDk1Njcz", + "name": "valetudo-armv7", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32291086, + "download_count": 3226, + "created_at": "2021-03-15T18:16:54Z", + "updated_at": "2021-03-15T18:16:55Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.03.0/valetudo-armv7" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/33495674", + "id": 33495674, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMzNDk1Njc0", + "name": "valetudo-armv7-lowmem", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32291086, + "download_count": 83, + "created_at": "2021-03-15T18:16:56Z", + "updated_at": "2021-03-15T18:16:57Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.03.0/valetudo-armv7-lowmem" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.03.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.03.0", + "body": "
\r\n \"valetudo\"\r\n

2021.03.0

\r\n
\r\n\r\nThis release features segment editing, SVG path and icon rendering, and a cool new companion service.\r\n\r\n## Segment editing\r\n\r\nYep. It's finally here.
\r\nStarting with this release, you can split and merge your Segments, which you might also refer to as Rooms.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201031-a565e480-85c2-11eb-8650-ec0b46d9b348.png)\r\n\r\n\r\nIf this was the only thing holding you back from switching back to Valetudo: Welcome back.\r\n\r\n## SVG Path + Icons\r\n\r\nThe map rendering was reworked. It's still a canvas but everything that isn't pixel-based is now drawn as an SVG, which results in greatly improved visual fidelity.\r\nSee for yourself:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201075-b31b6a00-85c2-11eb-894e-877a136a84e6.png)\r\n\r\n\r\nFurthermore, this might also improve performance. In any case, I'm quite happy with how good zooming in looks now.\r\n\r\n## Valeronoi\r\n\r\n@ccoors built a companion service which connects to Valetudo and generates a Wifi signal strength heatmap.
\r\nYou should definitely check that out. It's great!\r\n\r\n![image](https://user-images.githubusercontent.com/974410/111201122-be6e9580-85c2-11eb-9d7c-3dcdcf7cd8f3.png)\r\n\r\n\r\nIts repo can be found here: [https://github.com/ccoors/Valeronoi](https://github.com/ccoors/Valeronoi)\r\n\r\nI'm looking forward to seeing more companion services appear in the near future.\r\n\r\n## More Valetudo Builds\r\n\r\nStarting with this release, there's more than one Valetudo binary available for download in the releases section.
\r\nThe regular `valetudo` binary has been renamed to `valetudo-armv7` so just take that one if you're upgrading.\r\n\r\nThere's also a `valetudo-armv7-lowmem` with a slightly decreased heap size. I haven't testet that very much yet so feel free to do that\r\nespecially if your robot only has 256mb or less of ram available.\r\n\r\nAnd finally there's now a `valetudo-aarch64` binary to support robots with that cpu architecture.\r\n\r\nWhile doing that, I've also upgraded the Valetudo nodejs base binaries to `v14.16.0` which should include performance, stability and security improvements.\r\n\r\n## Misc\r\n\r\n### VoicePacks\r\n\r\n@depau added a way to install new VoicePacks. There's no UI support for that and the request required might vary from vendor to vendor.
\r\nUsually, it should be sufficient to provide an URL to the VoicePack + its hash and it should install fine.\r\n\r\n\r\n### MockRobot\r\n\r\n@alexkn added a `MockRobot` to make development easier and enable you to contribute to Valetudo even if you don't have a robot around.\r\n\r\n### ID Button\r\n\r\nFurthermore, I've added an ID button to the Zone and Location Preset map edit view, which shows you the ID of the preset you're editing so that you can\r\nuse it via MQTT.\r\nIt's pretty much a hack but that's better than nothing ¯\\_(ツ)_/¯\r\n\r\n### Git Commit UI Info\r\n\r\nThe info section of the UI will now also contain your currently running git commit id, which should make debugging a bit easier in certain situations.\r\n\r\n### Docs\r\n\r\nThe Docs at [valetudo.cloud](https://valetudo.cloud) have been improved and now feature an autogenerated overview of all supported robots\r\nplus a page that explains all available capabilities.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **core:** Log and display git commit id ([2d94408](https://github.com/Hypfer/Valetudo/commit/2d9440832a0f0c5efa83e5a8d065907e1d9b89b2))\r\n* **MockRobot:** add BatteryStateAttribute ([584bfcb](https://github.com/Hypfer/Valetudo/commit/584bfcb1ba7e782d0697c36d4a3fd467451c9d6c))\r\n* **MockRobot:** add ModelName ([db643c6](https://github.com/Hypfer/Valetudo/commit/db643c687f9fb1d43a4a29b41ffe18af93542c78))\r\n* **MockRobot:** add returning state to BasicControlCapability ([721cd78](https://github.com/Hypfer/Valetudo/commit/721cd78b053ac72fdcbe01df83e7a741f0204a2b))\r\n* **MockRobot:** introduce MockRobot ([96c4bae](https://github.com/Hypfer/Valetudo/commit/96c4bae2750971d121e3165b9aff3cc6f76398ca))\r\n* **MockRobot:** MockLocateCapability ([#752](https://github.com/Hypfer/Valetudo/issues/752)) ([5c41d49](https://github.com/Hypfer/Valetudo/commit/5c41d499b2478b09007a1af1a395f3a946dcb2ea))\r\n* **ui:** Add info button which shows the id of a zone or location preset ([ea7cce4](https://github.com/Hypfer/Valetudo/commit/ea7cce4a27c54412a6818e4b969d294d0190493c))\r\n* **ui:** Draw path as SVG ([48e5d54](https://github.com/Hypfer/Valetudo/commit/48e5d54417fb0e11cb92ea82930ce81580f70743))\r\n* **ui:** Nice rounded paths ([59aaee3](https://github.com/Hypfer/Valetudo/commit/59aaee3bf9d2cdfd3823ef0f91566d17b388af1d))\r\n* **ui:** Render icons as SVGs ([12f2907](https://github.com/Hypfer/Valetudo/commit/12f290741bb16c05530294a934f8167069288675))\r\n* **ui:** Segment editing ([e306569](https://github.com/Hypfer/Valetudo/commit/e306569d2daaa6f8ab7cfe75d3cd4a99b37faa8b))\r\n* **vendor.dreame:** DreameVoicePackManagementCapability ([f9d6ab1](https://github.com/Hypfer/Valetudo/commit/f9d6ab13ad8939b5fbdb09372b2f8b3fc3ac5187))\r\n* **vendor.dreame:** Fully implemented segment joining + splitting ([82e4fe3](https://github.com/Hypfer/Valetudo/commit/82e4fe3609b706c7a38efd47086604d5e92c1f36))\r\n* **vendor.roborock:** Add support for the S4 Max ([#699](https://github.com/Hypfer/Valetudo/issues/699)) ([f7eb451](https://github.com/Hypfer/Valetudo/commit/f7eb45105751827d371661e78b44b5e2d8c190d6))\r\n* **vendor.roborock:** RoborockVoicePackManagementCapability ([d81befc](https://github.com/Hypfer/Valetudo/commit/d81befc121116864faad129a06327325bf3b8dd4))\r\n* **vendor.viomi:** Ensure timezone is UTC ([#732](https://github.com/Hypfer/Valetudo/issues/732)) ([bafa158](https://github.com/Hypfer/Valetudo/commit/bafa158814c3185cffbbaa9c9529227883f13071)), closes [#728](https://github.com/Hypfer/Valetudo/issues/728)\r\n* **vendor.viomi:** initial implementation of ViomiZoneCleaningCapability class ([#675](https://github.com/Hypfer/Valetudo/issues/675)) ([f760137](https://github.com/Hypfer/Valetudo/commit/f7601370353659ce8a35e6c2a942c48d4f614226))\r\n* **vendor.viomi:** Speaker control capabilities ([#738](https://github.com/Hypfer/Valetudo/issues/738)) ([630d2ab](https://github.com/Hypfer/Valetudo/commit/630d2ab4f7c52c5c26d306e2b4e34d518123e64d))\r\n* **vendor.viomi:** ViomiCarpetModeControlCapability ([#739](https://github.com/Hypfer/Valetudo/issues/739)) ([fe31438](https://github.com/Hypfer/Valetudo/commit/fe3143854ff94de1b11d5c86720b97dbeff44058))\r\n* **webserver:** Fully implemented MapSegmentationCapabilityRouter ([eda7dcd](https://github.com/Hypfer/Valetudo/commit/eda7dcd071ac6d5438fbd1124c5b78704a8dc2ed))\r\n* Add os.freemem() to debug memoryStats ([5c7dfc3](https://github.com/Hypfer/Valetudo/commit/5c7dfc37392467602acea038407a12ccb39244e3))\r\n* Add voice pack managemenet capability ([#725](https://github.com/Hypfer/Valetudo/issues/725)) ([c953e2b](https://github.com/Hypfer/Valetudo/commit/c953e2b558b7bce5eace00655c3fb2f3ad30b0d6))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** Fix map canvas size ([3c05e2d](https://github.com/Hypfer/Valetudo/commit/3c05e2d9917e222a777a9d86207712d3b798dbec))\r\n* Fix default map ([25eac7c](https://github.com/Hypfer/Valetudo/commit/25eac7c57eb6b761ac6124fe6278cc628aad24a0))\r\n* **dnshack:** Don't try resolving ip addresses ([b8c456d](https://github.com/Hypfer/Valetudo/commit/b8c456d20cfe27946390aa528a7c99ab0a02801d))\r\n* **logger:** Use the windows equivalent of /dev/null on windows machines ([fa8f909](https://github.com/Hypfer/Valetudo/commit/fa8f9097496111d4664600553538729e105d8858))\r\n* **miio:** Bind dummycloud after setting event listeners ([#741](https://github.com/Hypfer/Valetudo/issues/741)) ([2aba77e](https://github.com/Hypfer/Valetudo/commit/2aba77e1330690bb7b422e29a79951c06d62e671))\r\n* **miio:** Discard handshake packets with older stamps to avoid endless loops with 100% cpu ([e274cf1](https://github.com/Hypfer/Valetudo/commit/e274cf145b635e2cd421657da29e53e54c8e521a))\r\n* **miio:** Fix broken development token refresh ([9217f70](https://github.com/Hypfer/Valetudo/commit/9217f70702eec6fe5ba0b2e41382eaaf42482d08))\r\n* **miio:** Fix Valetudo crashing due to missing onMessage function ([4512fe0](https://github.com/Hypfer/Valetudo/commit/4512fe08a3c9bbb46aa734a625261fa8418ba6e1))\r\n* **miio:** Various fixes related to Valetudo crashing in some situations ([a62d7e3](https://github.com/Hypfer/Valetudo/commit/a62d7e35745180260d4a8a28d0b40332e7cf1f66))\r\n* **mqtt:** Log on command-less custom command json ([3fa8232](https://github.com/Hypfer/Valetudo/commit/3fa823212fe97cb62704f04c560bce365a5dfd23))\r\n* **ui:** Decouple svg path generation from rendering to eliminate flicker ([9ebee25](https://github.com/Hypfer/Valetudo/commit/9ebee2515df021ddffac52ae1ed537430e9239f1))\r\n* **ui:** do not cache API responses ([#698](https://github.com/Hypfer/Valetudo/issues/698)) ([6e3b462](https://github.com/Hypfer/Valetudo/commit/6e3b462a36db49819718d47d58cb708728477360))\r\n* **ui:** Fix copy-paste error ([4479777](https://github.com/Hypfer/Valetudo/commit/4479777743df99ce4f042f5f641ee6a22e09f292))\r\n* **ui:** Fix initial map offset ([#711](https://github.com/Hypfer/Valetudo/issues/711)) ([a408edc](https://github.com/Hypfer/Valetudo/commit/a408edce5139f4aa2d767d52da0bb527eec8160f))\r\n* **ui:** Fix log UI only working once ([#718](https://github.com/Hypfer/Valetudo/issues/718)) ([2d02570](https://github.com/Hypfer/Valetudo/commit/2d02570f0c85c078941e67020e5e02a89fa62894))\r\n* **ui:** Fix new zone placement ([036752a](https://github.com/Hypfer/Valetudo/commit/036752a58ae73fd7180d4c46ef0424d38b52dc48))\r\n* **ui:** Only show presets if the robot is capable of having those ([d996beb](https://github.com/Hypfer/Valetudo/commit/d996beb4291146e71c90971dc3654926ed72f698))\r\n* **ui:** Reduce path render resolution ([aa64016](https://github.com/Hypfer/Valetudo/commit/aa64016c29151499cad8f7fef11d8826e7cd58ad))\r\n* **ui:** Reduce path render solution and render charger + robot as locations ([1c4e4f3](https://github.com/Hypfer/Valetudo/commit/1c4e4f3374251d64f3c79689747050c469a02ad7))\r\n* **ui:** Remove old paths if they vanish from the map data ([eef055e](https://github.com/Hypfer/Valetudo/commit/eef055ed42b208deb1caaf0d2fe1b16cd48ca046))\r\n* **ui:** Various scaling-related issues ([fb92c16](https://github.com/Hypfer/Valetudo/commit/fb92c162cff7f6f42099781596cd82e9afeeca4d))\r\n* **vendor.dreame:** Maps are always persistent ([3630fa3](https://github.com/Hypfer/Valetudo/commit/3630fa36d3137516245b738ee0102721fb4f217c))\r\n* **vendor.roborock:** Fix map not being available on a fresh boot for another 60s ([f4c4c1a](https://github.com/Hypfer/Valetudo/commit/f4c4c1a0784b4930bd6913cd9da6f092e1f0aa03))\r\n* **vendor.roborock:** Fix S4 detection logic ([#729](https://github.com/Hypfer/Valetudo/issues/729)) ([75974a5](https://github.com/Hypfer/Valetudo/commit/75974a5be0735035193118594f0ee3362d3e2a43))\r\n* **vendor.roborock:** RoborockS4 actually needs the MultiMapPersistentMapControlCapability ([6279831](https://github.com/Hypfer/Valetudo/commit/6279831f16c60a8115c9a2849e1c1258d75e2477))\r\n* **vendor.viomi:** Use marketing model name for viomi.v8 ([#742](https://github.com/Hypfer/Valetudo/issues/742)) ([7987168](https://github.com/Hypfer/Valetudo/commit/79871685bec0b4afb89d6b8e41f13d5db4dd8042))\r\n* **vendor.viomi:** Wait a few seconds after cloud connected before fixing TZ ([#736](https://github.com/Hypfer/Valetudo/issues/736)) ([f9bfb00](https://github.com/Hypfer/Valetudo/commit/f9bfb001c68f20f9438ad7703f4bbb3dd9e84626))\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/38135830", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/38135830/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/38135830/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.02.0", + "id": 38135830, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM4MTM1ODMw", + "tag_name": "2021.02.0", + "target_commitish": "master", + "name": "Valetudo 2021.02.0", + "draft": false, + "prerelease": false, + "created_at": "2021-02-16T21:17:31Z", + "published_at": "2021-02-16T22:37:28Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/32171459", + "id": 32171459, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMyMTcxNDU5", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32961247, + "download_count": 1241, + "created_at": "2021-02-16T22:38:04Z", + "updated_at": "2021-02-16T22:38:05Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.02.0/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.02.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.02.0", + "body": "
\r\n \"valetudo\"\r\n

2021.02.0

\r\n
\r\n\r\nThis release features Home Assistant MQTT Autoconfig for the Map Data, an NTP Client and more.\r\n\r\n## Map Autodiscovery\r\n\r\nThe Valetudo Map Data is now optionally (on by default) provided as embedded and compressed text of a PNG file.
\r\nThis is not only easy due to the nature of the PNG file format but also 100% according to specs.\r\nWe're actually publishing a completely valid PNG to MQTT containing the full Map as a JSON.\r\n\r\nThis enables Valetudo to do Home Assistant Autoconfiguration for the Map as well since camera entities aren't persistent to the HA database and therefore no user interaction regarding the exclusion of the map entity from the recorder is needed.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/108130382-de886300-70af-11eb-9dca-146b677cad18.png)\r\n\r\n\r\nI'm quite happy with this approach because there's no added CPU load to Valetudo since we're just sandwiching the deflated Map JSON between other PNG chunks.\r\nFurthermore, providing the raw map data instead of an image enables better interactions with the map such as\r\n- better zooming\r\n- custom colors\r\n- custom icons\r\n- mouseover things\r\n- click-to-select things\r\n\r\netc.\r\n\r\n\r\nThe [lovelace-valetudo-map-card](https://github.com/TheLastProject/lovelace-valetudo-map-card) is required to extract and render\r\nthe map data from the camera image.\r\n\r\nIf you were already using the Valetudo Map in Home Assistant, you will need to revise your setup.
\r\nNo worries though. It is much easier now :)\r\n\r\n## NTP Client\r\n\r\nDuring \"normal\" cloud operation, miio-based robots receive the time via the miio protocol. This of course resulted in\r\nthe robots syncing their time to their time, which doesn't make much sense and may even interfere with some features.\r\n\r\nAlso, not all robot firmwares contain a build of `ntpd` and cross-compiling can be hard.\r\n\r\nTherefore, there's now a simple NTP Client integrated into Valetudo, which by default fetches the time from `pool.ntp.org` on startup\r\nand every 8 hours after a successful sync.\r\n\r\nIt can be disabled via the configuration file and doesn't do anything if Valetudo isn't running in `embedded`-mode.\r\n\r\nOf course, you can also change the ntp server to a different one in the configuration file if you happen to own a\r\nstratum-0 cesium atomic clock or even a fritzbox with an integrated ntp server.\r\n\r\n## UI-Accessible Logs\r\n\r\nThanks to @ccoors, you will now find the contents of your Valetudo logfile under Settings > Info in the Web UI.\r\nNo need for SSH anymore.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/108130399-e516da80-70af-11eb-8b15-57649eac37af.png)\r\n\r\n\r\nIt is also possible to temporarily increase the Loglevel there until the next reboot.\r\n\r\n\r\nIf you're looking for stuff like the firmware version or your local token, the log viewer is the right place for you.\r\n\r\n## Misc\r\n\r\n@bensweet86 ported even more capabilities over to the new capabilities system. Starting with this release, Valetudo is now\r\nable to both control the volume and the carpet mode setting again.\r\n\r\nFurthermore, he also fixed a long outstanding bug regarding pinch to zoom on iOS devices.\r\n\r\n\r\n\r\nDreame support has been improved as well.\r\nPublic root for those is still TBA.\r\n\r\n\r\n\r\nThere were also quite a few changes regarding the cloud redirection in this release.\r\nPlease make sure to follow the official upgrade instructions so that you don't run into any issues.\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **logger:** Log config and logfile location to logfile ([0171a8d](https://github.com/Hypfer/Valetudo/commit/0171a8d1ba12c96045124d0e1f5b1b215655c314))\r\n* Add Valetudo log to UI ([#690](https://github.com/Hypfer/Valetudo/issues/690)) ([89320f4](https://github.com/Hypfer/Valetudo/commit/89320f45c4b7e49d8246f9b2508bdacd4c549efb))\r\n* Log the firmware version if embedded ([4bd09c8](https://github.com/Hypfer/Valetudo/commit/4bd09c8b8ad0d2f411630430a88dacd3e6230063))\r\n* **core:** Change the interface of the SpeakerVolumeControlCapability and add the SpeakerTestCapability ([56b0637](https://github.com/Hypfer/Valetudo/commit/56b06378a8c183d488eb503056bee39ff8872486))\r\n* **mqtt:** Home Assistant Autodiscovery for Maps by embedding the map data in a png ([83d1d13](https://github.com/Hypfer/Valetudo/commit/83d1d13bc47bb7a16f1a9ed8937ce616a0f2b5ec))\r\n* **vendor.dreame:** Consumable monitoring ([e986687](https://github.com/Hypfer/Valetudo/commit/e986687f649e0f3c061653aac9d362b74bde5065))\r\n* **vendor.dreame:** D9 error codes ([669f192](https://github.com/Hypfer/Valetudo/commit/669f19273eb9e849b578508adaa7e37f99d79fed))\r\n* **vendor.dreame:** Improve handling of RISM maps ([186abd3](https://github.com/Hypfer/Valetudo/commit/186abd34852d62b3ab418216a500bfbb72423b85))\r\n* **vendor.dreame:** Minor improvements for D9 Firmware 1072 ([ef949be](https://github.com/Hypfer/Valetudo/commit/ef949be485ba97bd8c65066ff5c3f427fbf35f6e))\r\n* **vendor.dreame:** Virtual Restrictions ([3f1f494](https://github.com/Hypfer/Valetudo/commit/3f1f4940c582534f6fb5d18442e21e1183498378))\r\n* **vendor.dreame:** Volume Control + Volume Test ([1509be3](https://github.com/Hypfer/Valetudo/commit/1509be361552f76148c4f38b3d7ec1da3c400735))\r\n* **vendor.roborock:** Roborock/Capability Carpet Mode ([#661](https://github.com/Hypfer/Valetudo/issues/661)) ([54ca606](https://github.com/Hypfer/Valetudo/commit/54ca6068dbe8f09cf8105fd11c50b9107c2b739f)), closes [#656](https://github.com/Hypfer/Valetudo/issues/656)\r\n* **vendor.roborock:** Volume Control + Volume Test ([4a47939](https://github.com/Hypfer/Valetudo/commit/4a47939ebea220e19ed9da3b4427c53da429e700))\r\n* NTPClient ([8b54c7d](https://github.com/Hypfer/Valetudo/commit/8b54c7d0066d7b4b306aaf1b096ce1027651998c))\r\n\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **logger:** Default loglevel should be info ([3e23678](https://github.com/Hypfer/Valetudo/commit/3e2367875b364d4ca63ea98548fbc3c2e841ee15))\r\n* **logger:** Do not log twice if logfile is the same as stdout redirection ([#691](https://github.com/Hypfer/Valetudo/issues/691)) ([2bd4c82](https://github.com/Hypfer/Valetudo/commit/2bd4c820a5f46e77383d9d489867494d4696fc09))\r\n* **logger:** Logger should log 🪵 ([58515d9](https://github.com/Hypfer/Valetudo/commit/58515d97559b 8bd2ab2ac12ddfbadd4fad576d9f))\r\n* **miio:** Don't get confused by the system clock doing weird things ([5e6d8df](https://github.com/Hypfer/Valetudo/commit/5e6d8df224d845da5218d0836f20f7eb4027d39c))\r\n* **miio:** http_dns: Block ott.io.mi.com requests ([#671](https://github.com/Hypfer/Valetudo/issues/671)) ([852683b](https://github.com/Hypfer/Valetudo/commit/852683b25815a05235b580a313a2464714786f4c))\r\n* **miio:** One failing message should not kill the process 20 minutes later ([e5fd0a5](https://github.com/Hypfer/Valetudo/commit/e5fd0a54ab1e040c2c82c60a4c5c310f4709fc6e))\r\n* **miio:** Set ServerSocket to disconnected on timeouts to prevent valetudo breaking on wifi issues ([e14935d](https://github.com/Hypfer/Valetudo/commit/e14935dfa9ef06a15871b3bd7683c55956b4db52))\r\n* **mqtt:** Fix home assistant vacuum.send_command functionality ([97ac35e](https://github.com/Hypfer/Valetudo/commit/97ac35e7e34fc7da3dbc3e4774f1f9ecbe7afe64))\r\n* **ntpClient:** Intercept dns lookup calls for our ntp server as well ([c7095a7](https://github.com/Hypfer/Valetudo/commit/c7095a7a340cfad293385a37f6f9dcf04a477e61))\r\n* **ui:** Fix for pinch zoom bug in IOS / Safari ([#683](https://github.com/Hypfer/Valetudo/issues/683)) ([3c0a644](https://github.com/Hypfer/Valetudo/commit/3c0a644da402f1e392fe7f088ba7fd3da4dafc69))\r\n* **ui:** SSE Map updates should use a relative path ([54bc2b7](https://github.com/Hypfer/Valetudo/commit/54bc2b71d99c0d2c411e807a2365107eb7949b36))\r\n* **vendor.dreame:** Don't store empty MapLayers ([1230c08](https://github.com/Hypfer/Valetudo/commit/1230c082b50f9264a27219f4f8e211de54541caf))\r\n* **vendor.dreame:** Proper angles ([43aa8c6](https://github.com/Hypfer/Valetudo/commit/43aa8c60ded5ed1bf52fdfce406c6bb0933f1cc1))\r\n* **vendor.dreame:** Properly parse map with correct rotation, offsets etc ([5e037c2](https://github.com/Hypfer/Valetudo/commit/5e037c22dfb27be9f3cdfa50b6d18911998da913))\r\n* **vendor.roborock:** calculation of max elements for virtual restrictions ([#681](https://github.com/Hypfer/Valetudo/issues/681)) ([2e4421b](https://github.com/Hypfer/Valetudo/commit/2e4421b0e27adc563a40ab9c8d2e3b804128ce57))\r\n* **vendor.viomi:** consumables command fix for viaomi.v8 ([#677](https://github.com/Hypfer/Valetudo/issues/677)) ([bef609e](https://github.com/Hypfer/Valetudo/commit/bef609efbe772632b270c67efb660ef2b8f06c0f))\r\n* **vendor.viomi:** Resolve [#672](https://github.com/Hypfer/Valetudo/issues/672): Fix viomi fan speed control ([#673](https://github.com/Hypfer/Valetudo/issues/673)) ([be0efca](https://github.com/Hypfer/Valetudo/commit/be0efca344ea7fe53858b9a28c7097ad4c99dea1))\r\n* **vendor.viomi:** Various fixes for 2020.01.1 ([a38987a](https://github.com/Hypfer/Valetudo/commit/a38987affba30f37e0cd09a67627a51adf695679)), closes [#641](https://github.com/Hypfer/Valetudo/issues/641)\r\n* **webserver:** Fix handleHttpDnsRequest scope ([8226e4a](https://github.com/Hypfer/Valetudo/commit/8226e4ad3e840539f13a358d817ec1b9217a2085))\r\n* **webserver:** Rate-limit logfile access ([8fd53a5](https://github.com/Hypfer/Valetudo/commit/8fd53a5237bc847708b7ee631da4afbd8fe7b950))\r\n\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/36957518", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/36957518/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/36957518/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.01.1", + "id": 36957518, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM2OTU3NTE4", + "tag_name": "2021.01.1", + "target_commitish": "master", + "name": "Valetudo 2021.01.1", + "draft": false, + "prerelease": false, + "created_at": "2021-01-27T08:58:03Z", + "published_at": "2021-01-27T09:10:00Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/31246605", + "id": 31246605, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMxMjQ2NjA1", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33170157, + "download_count": 894, + "created_at": "2021-01-27T09:10:38Z", + "updated_at": "2021-01-27T09:10:36Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.01.1/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.01.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.01.1", + "body": "
\r\n \"valetudo\"\r\n

2021.01.1

\r\n
\r\n\r\n**Be advised: This release will break (almost) everything that you're currently using.**
\r\n\r\nConfig format, HTTP API and MQTT have changed significantly in this release.
\r\nYou will need to recreate your Zone presets as well as your Home Assistant Robot entity.\r\n\r\nMake sure to disable any Timers you might've configured before upgrading, since there's no way to delete/configure them in this release anymore!\r\n\r\nAlso, note that this release comes with fewer features than the previous, because not everything has been ported to the new structures yet.\r\n\r\n## Core rewrite (Capabilities)\r\n\r\nTo support a growing number of Vacuum Robots with different feature sets made by different Vendors, the core infrastructure\r\nof Valetudo was completely rewritten.\r\n\r\nNow, instead of having robots that inherit from other robots, there are so-called `capabilities` as an abstraction of features.
\r\nThere's always a generic base class for each feature (e.g. `GoToLocationCapability`) which is extended by multiple vendor-specific\r\nimplementations (e.g. `RoborockGoToLocationCapability`, `ViomiGoToLocationCapability` etc).\r\n\r\nThis approach completely encapsulates vendor-specific implementation details and makes them invisible for e.g. the webinterface or other\r\nusers of the HTTP API which has also been rewritten.\r\n\r\nOverall, I'm quite happy with how it turned out. Time will tell whether this abstraction was generic enough to deal with\r\nall possible vendor-specific differences.\r\n\r\n## New HTTP REST Interface\r\n\r\nAs mentioned, the REST interface was rewritten and is now an official way of communicating with Valetudo.
\r\n\r\nAll endpoints are dynamically generated according to which capabilities are available for the robot implementation Valetudo is using.\r\nFor example basic controls such as \"start\", \"stop\" or \"home\" are done via a PUT request to `/api/v2/robot/capabilities/BasicControlCapability`.\r\n\r\nTo find out more about all possible endpoints for your Valetudo instance, a meta-endpoint has also been added.
\r\nAt `/api/v2/` you will get JSON containing all endpoints as well as their accepted methods.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436664-9061f200-4c1e-11eb-8541-5c8ed6ccc4c2.png)\r\n\r\n## New MQTT Interface\r\n\r\nThe MQTT interface was also rewritten to support different subsets of capabilities.\r\nInstead of having a single topic, which contains all the information available, data is now split up onto different topics\r\nbased on capabilities.\r\n\r\nThis also means that you will have multiple entities for your robot in Home Assistant:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436641-44af4880-4c1e-11eb-8a9f-019d17398359.png)\r\n\r\nFurthermore, Wi-Fi information is now also available over MQTT so in theory, one could build a microservice which subscribes\r\nto both map and Wi-Fi data updates and build a Wi-Fi heatmap of their home by mapping the measurements to the position in the map.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436651-5f81bd00-4c1e-11eb-99f9-9efe6875d5b3.png)\r\n\r\n\r\nNote that the default identifier changed from `rockrobo` to `robot`, since Valetudo is not just dealing with Roborock anymore.
\r\nTherefore when reconfiguring this release, you may want to change that back to the old value if your setup relies on it.\r\n\r\n## New Config Schema + Location\r\n\r\nTo support different robots with different folder structures (some of them being read-only), the configuration location\r\nhad to be made configurable, which is a chicken/egg problem, because the information on where to find the configuration\r\nwould be configured within the configuration.\r\n\r\nTo solve this, Valetudo is now using the environment variable `VALETUDO_CONFIG_PATH` and defaults to `os.tmpdir()` if it isn't set.\r\n\r\nDue to the fact that the configuration schema also changed significantly, **you will need to reconfigure Valetudo on upgrade**.\r\n\r\nYou will also need to update your means of running valetudo to include this ENV variable since otherwise your configuration will vanish on each reboot.\r\nThis can be done either by building a new firmware image or copying the changes required from these commits\r\n\r\n[Roborock](https://github.com/zvldz/vacuum/commit/5981577aa8e8f75c4fbea7045bf4484066881b55)\r\n\r\n[Viomi](https://github.com/Hypfer/Valetudo/commit/923f941e76e2e41be7a714e47f3a08428d09cfd4)\r\n\r\n## Dreame Support\r\n\r\nWith the launch of the Dreame D9, there's now a promising successor to the Roborock S5 regarding both pricing and ease of installation.\r\nThis release already contains support for basic controls, Map Rendering, Segment Cleaning and Zoned Cleaning.\r\n\r\nRooting instructions will follow soon-ish. :)\r\n\r\nIt looks like this code should also be adaptable to the F9. We'll see about that if/when I get my hands on one\r\n\r\n## Misc\r\n\r\n**Viomi note:** If you're upgrading on a Viomi, make sure to change the cloud IP used for redirection to `203.0.113.1` which is now hardcoded.
\r\nThe docs have been updated to reflect that.\r\n\r\nValetudo is now using the CalVer versioning scheme, because it better fits the constantly changing scope of the project.\r\n\r\nI'd like to especially thank @depau for his port of the Viomi robot to the new infrastructure using only the half-finished capabilities branch\r\nand no documentation whatsoever as a reference.\r\n\r\nFurthermore, thanks to @bensweet86 for porting more capabilities to the new framework.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **mqtt:** Publish ValetudoGoToLocations & ValetudoZonePresets ([76a9c52](https://github.com/Hypfer/Valetudo/commit/76a9c5234dfbcce864d70d1d6db781af86d6a98b))\r\n* **ui:** Bring back consumable monitoring & resetting for now ([fde2ffd](https://github.com/Hypfer/Valetudo/commit/fde2ffd8d3c7b5869f221870774a2032232d6c54))\r\n* **vacuum.roborock:** Add support for no-mopping zones on S5 Max and S6 ([#630](https://github.com/Hypfer/Valetudo/issues/630)) ([61902ed](https://github.com/Hypfer/Valetudo/commit/61902edd8b185d116dd27a02827866e3defd01b1)\r\n)\r\n* **vacuum.roborock:** Re-added support for S6 Pure ([0226cd5](https://github.com/Hypfer/Valetudo/commit/0226cd56a6f245e307944dab623d28bda8fcc288))\r\n* **vacuum.viomi:** Virtual Walls & No-Go Areas ([96462ac](https://github.com/Hypfer/Valetudo/commit/96462ac752b025a3385e31d4ea0cfbea268b207c))\r\n* **vendor.dreame:** Basic Dreame D9 support ([7c5e231](https://github.com/Hypfer/Valetudo/commit/7c5e231326bc8ca454e303b31c647f14f6773cd8))\r\n* **vendor.dreame:** Re-add support for 1c as well as more dreame capabilities ([cd76abe](https://github.com/Hypfer/Valetudo/commit/cd76abe952cda43fd260eda2b217aff677b98d29))\r\n* **vendor.roborock:** Do not disturb capability ([#659](https://github.com/Hypfer/Valetudo/issues/659)) ([4b3ed97](https://github.com/Hypfer/Valetudo/commit/4b3ed974d064b788f470c9439a719a3f3ed95cb9))\r\n* **vendor.roborock:** Use the lo alias approach for more robots ([58a2618](https://github.com/Hypfer/Valetudo/commit/58a26186f34e5331fe5373e231e97f403e15e147))\r\n* Add properties to capability ([7114fcc](https://github.com/Hypfer/Valetudo/commit/7114fccb502305e3176b350973f1ba0825e98845))\r\n* Configure authorized_keys location via ENV variable ([d06520d](https://github.com/Hypfer/Valetudo/commit/d06520da114f45778527e54446eed70df38e66ba))\r\n* Viomi capabilities port ([8486f04](https://github.com/Hypfer/Valetudo/commit/8486f04fdd9176af6e4e7be684bb3eecebaa39e1))\r\n\r\n### Bug Fixes\r\n\r\n* **miio:** Only report a new token from handshake if it is actually new ([b373703](https://github.com/Hypfer/Valetudo/commit/b37370349514fea07fc8b27b89637a44e6df668e))\r\n* Fix map layer dimensions calculation for empty layers ([216c347](https://github.com/Hypfer/Valetudo/commit/216c3474e7680b90859b47e2ea5308ced8d1c7ff))\r\n* **ui:** fix [#565](https://github.com/Hypfer/Valetudo/issues/565) ui not working with safari and basic auth ([252c22d](https://github.com/Hypfer/Valetudo/commit/252c22dc9d457aa69bdbee0829930aa156430a9b))\r\n* **vendor.dreame:** Fix map parser tests ([a81b8e9](https://github.com/Hypfer/Valetudo/commit/a81b8e94a6db0c39b0881bbb29122ca62f5a2247))\r\n* **vendor.roborock:** Use lo alias cloud redirection approach for S6 & S5Max with miio_client 3.5.8 ([71bc1f8](https://github.com/Hypfer/Valetudo/commit/71bc1f8b91b47503a45b3771c3217655cc30a7fd))\r\n* Set VALETUDO_CONFIG_PATH variable for Upstart ([#648](https://github.com/Hypfer/Valetudo/issues/648)) ([f75b70d](https://github.com/Hypfer/Valetudo/commit/f75b70d7f7d3092f724555090db99aea4bccf6d9))\r\n* **mqtt:** missing / in set_fan_speed topic ([26ceb95](https://github.com/Hypfer/Valetudo/commit/26ceb95a71154396d14adfb01b6fb1d198fa3490))\r\n* **vacuum.roborock:** Fix broken cloud connectivity on newer roborock vacuums caused by missing region ([28483ab](https://github.com/Hypfer/Valetudo/commit/28483abd4431cf0d38953aefeb3995e9d45ea2b8))\r\n* **vacuum.viomi:** Added model names for viomi.v8 ([20d86c3](https://github.com/Hypfer/Valetudo/commit/20d86c3c005ac78d36bab29a78946e17f163f2c3))\r\n* **vacuum.viomi:** Fix fan speed state parsing ([3ca7450](https://github.com/Hypfer/Valetudo/commit/3ca745054d3c159023edb632e198126e89d7494a))\r\n* **vacuum.viomi:** Fix invalid property access ([6da2822](https://github.com/Hypfer/Valetudo/commit/6da282201172b3fb5efa1969aac6192d5ead5842))\r\n* **vacuum.viomi:** Segments + Docs ([#600](https://github.com/Hypfer/Valetudo/issues/600)) ([89a5485](https://github.com/Hypfer/Valetudo/commit/89a5485f17e7ac68e7b8d97ae9a8381d2f0a7767))\r\n* Improved dnshack to catch all problematic dns.lookup requests ([8609612](https://github.com/Hypfer/Valetudo/commit/8609612e03bc756194982d35b4389d27557842ac))\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/35892435", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/35892435/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/35892435/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/2021.01.0b0", + "id": 35892435, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTM1ODkyNDM1", + "tag_name": "2021.01.0b0", + "target_commitish": "master", + "name": "Valetudo 2021.01.0b0", + "draft": false, + "prerelease": true, + "created_at": "2021-01-01T09:36:08Z", + "published_at": "2021-01-01T09:47:01Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/30164475", + "id": 30164475, + "node_id": "MDEyOlJlbGVhc2VBc3NldDMwMTY0NDc1", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 33117585, + "download_count": 590, + "created_at": "2021-01-01T09:47:37Z", + "updated_at": "2021-01-01T09:47:38Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/2021.01.0b0/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/2021.01.0b0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/2021.01.0b0", + "body": "
\r\n \"valetudo\"\r\n

2021.01.0b0

\r\n
\r\n\r\n**Be advised: This release will break (almost) everything that you're currently using.**
\r\n\r\nConfig format, HTTP API and MQTT have changed significantly in this release.
\r\nYou will need to recreate your Zone presets as well as your Home Assistant Robot entity.\r\n\r\nMake sure to disable any Timers you might've configured before upgrading, since there's no way to delete/configure them in this release anymore!\r\n\r\nAlso, note that this release comes with fewer features than the previous, because not everything has been ported to the new structures yet.\r\n\r\n## Core rewrite (Capabilities)\r\n\r\nTo support a growing number of Vacuum Robots with different feature sets made by different Vendors, the core infrastructure\r\nof Valetudo was completely rewritten.\r\n\r\nNow, instead of having robots that inherit from other robots, there are so-called `capabilities` as an abstraction of features.
\r\nThere's always a generic base class for each feature (e.g. `GoToLocationCapability`) which is extended by multiple vendor-specific\r\nimplementations (e.g. `RoborockGoToLocationCapability`, `ViomiGoToLocationCapability` etc).\r\n\r\nThis approach completely encapsulates vendor-specific implementation details and makes them invisible for e.g. the webinterface or other\r\nusers of the HTTP API which has also been rewritten.\r\n\r\nOverall, I'm quite happy with how it turned out. Time will tell whether this abstraction was generic enough to deal with\r\nall possible vendor-specific differences.\r\n\r\n## New HTTP REST Interface\r\n\r\nAs mentioned, the REST interface was rewritten and is now an official way of communicating with Valetudo.
\r\n\r\nAll endpoints are dynamically generated according to which capabilities are available for the robot implementation Valetudo is using.\r\nFor example basic controls such as \"start\", \"stop\" or \"home\" are done via a PUT request to `/api/v2/robot/capabilities/BasicControlCapability`.\r\n\r\nTo find out more about all possible endpoints for your Valetudo instance, a meta-endpoint has also been added.
\r\nAt `/api/v2/` you will get JSON containing all endpoints as well as their accepted methods.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436664-9061f200-4c1e-11eb-8541-5c8ed6ccc4c2.png)\r\n\r\n## New MQTT Interface\r\n\r\nThe MQTT interface was also rewritten to support different subsets of capabilities.\r\nInstead of having a single topic, which contains all the information available, data is now split up onto different topics\r\nbased on capabilities.\r\n\r\nThis also means that you will have multiple entities for your robot in Home Assistant:\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436641-44af4880-4c1e-11eb-8a9f-019d17398359.png)\r\n\r\nFurthermore, Wi-Fi information is now also available over MQTT so in theory, one could build a microservice which subscribes\r\nto both map and Wi-Fi data updates and build a Wi-Fi heatmap of their home by mapping the measurements to the position in the map.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/103436651-5f81bd00-4c1e-11eb-99f9-9efe6875d5b3.png)\r\n\r\n\r\nNote that the default identifier changed from `rockrobo` to `robot`, since Valetudo is not just dealing with Roborock anymore.
\r\nTherefore when reconfiguring this release, you may want to change that back to the old value if your setup relies on it.\r\n\r\n## New Config Schema + Location\r\n\r\nTo support different robots with different folder structures (some of them being read-only), the configuration location\r\nhad to be made configurable, which is a chicken/egg problem, because the information on where to find the configuration\r\nwould be configured within the configuration.\r\n\r\nTo solve this, Valetudo is now using the environment variable `VALETUDO_CONFIG_PATH` and defaults to `os.tmpdir()` if it isn't set.\r\n\r\nDue to the fact that the configuration schema also changed significantly, **you will need to reconfigure Valetudo on upgrade**.\r\n\r\nYou will also need to update your means of running valetudo to include this ENV variable since otherwise your configuration will vanish on each reboot.\r\nThis can be done either by building a new firmware image or copying the changes required from these commits\r\n\r\n[Roborock](https://github.com/zvldz/vacuum/commit/5981577aa8e8f75c4fbea7045bf4484066881b55)\r\n\r\n[Viomi](https://github.com/Hypfer/Valetudo/commit/923f941e76e2e41be7a714e47f3a08428d09cfd4)\r\n\r\n## Misc\r\n\r\n**Viomi note:** If you're upgrading on a Viomi, make sure to change the cloud IP used for redirection to `203.0.113.1` which is now hardcoded.
\r\nThe docs have been updated to reflect that.\r\n\r\nValetudo is now using the CalVer versioning scheme, because it better fits the constantly changing scope of the project.\r\n\r\nI'd like to especially thank @depau for his port of the Viomi robot to the new infrastructure using only the half-finished capabilities branch\r\nand no documentation whatsoever as a reference.\r\n\r\n\r\n## Autogenerated changelog\r\n\r\n### Features\r\n\r\n* **vacuum.viomi:** Virtual Walls & No-Go Areas ([96462ac](https://github.com/Hypfer/Valetudo/commit/96462ac752b025a3385e31d4ea0cfbea268b207c))\r\n* Configure authorized_keys location via ENV variable ([d06520d](https://github.com/Hypfer/Valetudo/commit/d06520da114f45778527e54446eed70df38e66ba))\r\n* Viomi capabilities port ([8486f04](https://github.com/Hypfer/Valetudo/commit/8486f04fdd9176af6e4e7be684bb3eecebaa39e1))\r\n* **mqtt:** Publish ValetudoGoToLocations & ValetudoZonePresets ([76a9c52](https://github.com/Hypfer/Valetudo/commit/76a9c5234dfbcce864d70d1d6db781af86d6a98b))\r\n* **vacuum.roborock:** Add support for no-mopping zones on S5 Max and S6 ([#630](https://github.com/Hypfer/Valetudo/issues/630)) ([61902ed](https://github.com/Hypfer/Valetudo/commit/61902edd8b185d116dd27a02827866e3defd01b1))\r\n\r\n### Bug Fixes\r\n\r\n* **ui:** fix [#565](https://github.com/Hypfer/Valetudo/issues/565) ui not working with safari and basic auth ([252c22d](https://github.com/Hypfer/Valetudo/commit/252c22dc9d457aa69bdbee0829930aa156430a9b))\r\n* **vacuum.viomi:** Added model names for viomi.v8 ([20d86c3](https://github.com/Hypfer/Valetudo/commit/20d86c3c005ac78d36bab29a78946e17f163f2c3))\r\n* **vacuum.viomi:** Fix fan speed state parsing ([3ca7450](https://github.com/Hypfer/Valetudo/commit/3ca745054d3c159023edb632e198126e89d7494a))\r\n* **vacuum.viomi:** Fix invalid property access ([6da2822](https://github.com/Hypfer/Valetudo/commit/6da282201172b3fb5efa1969aac6192d5ead5842))\r\n* **vacuum.viomi:** Segments + Docs ([#600](https://github.com/Hypfer/Valetudo/issues/600)) ([89a5485](https://github.com/Hypfer/Valetudo/commit/89a5485f17e7ac68e7b8d97ae9a8381d2f0a7767))\r\n* Improved dnshack to catch all problematic dns.lookup requests ([8609612](https://github.com/Hypfer/Valetudo/commit/8609612e03bc756194982d35b4389d27557842ac))\r\n\r\n\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/29111413", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/29111413/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/29111413/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.6.1", + "id": 29111413, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI5MTExNDEz", + "tag_name": "0.6.1", + "target_commitish": "master", + "name": "Valetudo 0.6.1", + "draft": false, + "prerelease": false, + "created_at": "2020-07-30T10:49:25Z", + "published_at": "2020-07-30T10:51:41Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/23406574", + "id": 23406574, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIzNDA2NTc0", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32380902, + "download_count": 5086, + "created_at": "2020-07-30T10:52:25Z", + "updated_at": "2020-07-30T10:52:26Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.6.1/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.6.1", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.6.1", + "body": "
\r\n \"valetudo\"\r\n

0.6.1

\r\n
\r\n\r\nThis is merely a small fix release.\r\n\r\nWith 0.6.1, valetudo doesn't segfault anymore when using a domain name as the mqtt host.\r\nFurthermore, zones are now back to being cleaned once instead of ten times.\r\n\r\nIf you've arrived at this release and haven't seen the [0.6.0 release notes](https://github.com/Hypfer/Valetudo/releases/tag/0.6.0) yet, I strongly encourage you to do so now.\r\n\r\n\r\nAutogenerated changelog:\r\n\r\n### Features\r\n\r\n* **mqtt:** Added sw_version to mqtt autodiscovery to fix [#568](https://github.com/Hypfer/Valetudo/issues/568) ([a23d5af](https://github.com/Hypfer/Valetudo/commit/a23d5af95b7986c21e3487eb5e2d4f93c16c8ba3))\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Fix segfault on mqtt hostname resolution ([b2410ff](https://github.com/Hypfer/Valetudo/commit/b2410ff5eda5a67f02ff5fcad7ef7c30e498674c))\r\n* **mqtt:** Fixed [#571](https://github.com/Hypfer/Valetudo/issues/571) mqtt pause status ([8b06203](https://github.com/Hypfer/Valetudo/commit/8b06203de22871c47be97bc8e353118796636853))\r\n* **ui:** Fix mqtt settings checkboxes ([039b741](https://github.com/Hypfer/Valetudo/commit/039b7411325b74c2b4abbe58a91134fd1d1b9982))\r\n* **ui:** Restore context after drawing active zone ([4f7ec2c](https://github.com/Hypfer/Valetudo/commit/4f7ec2c44e8da163bf30c097df26a3df37380f04))\r\n* **vacuum.roborock:** Don't multiply iterations by 10 to fix [#573](https://github.com/Hypfer/Valetudo/issues/573) ([f3cc935](https://github.com/Hypfer/Valetudo/commit/f3cc9354d6da3149a69ef5476c922d97df0eb8a3))\r\n* override dns.lookup to mitigate static nodejs segfaults ([41f3e98](https://github.com/Hypfer/Valetudo/commit/41f3e981a590e76261e7d57ccff8d97b3d4b94ad))" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/28964045", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/28964045/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/28964045/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.6.0", + "id": 28964045, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI4OTY0MDQ1", + "tag_name": "0.6.0", + "target_commitish": "master", + "name": "Valetudo 0.6.0", + "draft": false, + "prerelease": false, + "created_at": "2020-07-26T17:09:00Z", + "published_at": "2020-07-26T17:15:02Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/23253232", + "id": 23253232, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIzMjUzMjMy", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32381338, + "download_count": 377, + "created_at": "2020-07-26T17:15:32Z", + "updated_at": "2020-07-26T17:15:33Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.6.0/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.6.0", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.6.0", + "body": "
\r\n \"valetudo\"\r\n

0.6.0

\r\n
\r\n\r\n## New Data Format\r\nI've finally found the time to rework the Map Data format as well as the robot state format.\r\nBoth previously being heavily influenced by roborock, the new and improved formats are a huge step for easier adaption\r\nof Valetudo to new Vacuums as well as implementation of new features.\r\n\r\nIn fact it has already proven itself in other work that has been done for this release and decreased memory pressure quite a bit.\r\n\r\nThis change is also of course a **breaking change**.\r\nMake sure to update any dependant applications/integrations/etc. as well.\r\n\r\n\r\n## (Initial) Support for many more Vacuums + a new Vendor\r\nThe list of _technically_ supported roborock vacuums has grown quite a bit.\r\nEspecially since Dennis released his guide on how to root the S6 which you can find [here](https://www.youtube.com/playlist?list=PL9PoaNtZCJRZc61c792VCr_I6jQK_IdSb).\r\n\r\nFurthermore, Valetudo has also received initial support for a dreame-made xiaomi vacuum robot: **Xiaomi MiJia 1C**\r\n\r\nThere's no map parsing yet though. Contributions much appreciated.\r\n\r\nPlease note that there's no dreame rooting guide available yet.\r\nThese release notes will be updated when it becomes available.\r\n\r\n\r\n## Segment Cleaning via the Web and MQTT\r\nOwners of room-cleaning capable roborock vacuums can now use Valetudo to do so.\r\n\r\nSimply select the segments you want to clean and start the cleanup like you would start a zoned cleanup.\r\nCurrently cleaned segments are denoted by a rotated icon.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485125-f3ff3980-cf73-11ea-87f2-dbe85508c5e1.png)\r\n\r\nIf you zoom in on a segment marker, it will display both it's segment id as well as the segments' area in `m²`.\r\nThe latter also being a benefit of the new Map Data format.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485127-fd88a180-cf73-11ea-819c-cdd60b3b062c.png)\r\n\r\nSegment cleaning is of course also available via MQTT.\r\nCheck out the updated Home Assistant docs for an example on how to use it.\r\n\r\nSince this is a generic implementation, support for other vacuum vendors will follow.\r\nYou just need to open a PR for that.\r\n\r\n### UI enhancements\r\nDynamic zones now display their size in meters which is also a helpful addition if you quickly want to measure something without leaving your desk.\r\n\r\n![image](https://user-images.githubusercontent.com/974410/88485140-109b7180-cf74-11ea-82cf-23da553ae201.png)\r\n\r\nFurthermore, it is now impossible for you to break the map by zooming out too far.\r\n\r\n\r\n## Misc\r\n* The map renderer has been updated by @aa-ko to always color adjacent segments in a different color thanks to math™\r\n* MQTT supports client certificate authentication thanks to @mqtt-fan\r\n\r\nand of course there's the autogenerated changelog:\r\n\r\n### Features\r\n\r\n* Segment cleanup via WebUI + MQTT ([f14f6cc](https://github.com/Hypfer/Valetudo/commit/f14f6cc253766e11f9a95dfe6cbff7cfafc73e70))\r\n* **entities.state:** Added Charging/Charged/Discharging status to BatteryStateAttribute ([97b5cdf](https://github.com/Hypfer/Valetudo/commit/97b5cdfd93bc4f562752a0a890f1b972b620119c))\r\n* **mqtt:** add support for client certificate ([#549](https://github.com/Hypfer/Valetudo/issues/549)) ([33f94ec](https://github.com/Hypfer/Valetudo/commit/33f94ec6614d15876b5e1f77446500001185b317))\r\n* **roborock:** Experimental support for even more roborock vacuums ([2450ceb](https://github.com/Hypfer/Valetudo/commit/2450ceb3f5cb2653ee32dd3d5ef0fbf2c7e69645))\r\n* **ui:** Added zone size display, proper icon/text scaling and limited scaling ([6b61ca8](https://github.com/Hypfer/Valetudo/commit/6b61ca816f377c07c784cb9075be43e838ecb405))\r\n* **ui:** Use math (four color theorem) to properly color segments ([d462f65](https://github.com/Hypfer/Valetudo/commit/d462f65e8fe57de43daf098f295d987a11990f9d))\r\n* **vacuum.dreame:** Initial basic support for the dreame.vacuum.mc1808 ([f73c7c6](https://github.com/Hypfer/Valetudo/commit/f73c7c61dfe786131704fa90fd93e632263b982d))\r\n* **vacuum.viomi:** add support for viomi.vacuum.v8 + mop enhancements ([#543](https://github.com/Hypfer/Valetudo/issues/543)) ([17bb01e](https://github.com/Hypfer/Valetudo/commit/17bb01efe088a494563f6037076ade6e13c8c553)), closes [#541](https://github.com/Hypfer/Valetudo/issues/541) [#538](https://github.com/Hypfer/Valetudo/issues/538) [#548](https://github.com/Hypfer/Valetudo/issues/548)\r\n* Experimental support(?) for S6 MaxV ([88de212](https://github.com/Hypfer/Valetudo/commit/88de212274872eca0ca97c3b0dfadb70d2a4baa5))\r\n\r\n\r\n### Bug Fixes\r\n\r\n* **entities.map:** Fixed MapLayer area calculation ([ac86c84](https://github.com/Hypfer/Valetudo/commit/ac86c84c8fa75408b52067306f7e0c4a201e9725))\r\n* **mqtt:** Check DNS resolution before connecting to mqtt broker to fix [#563](https://github.com/Hypfer/Valetudo/issues/563) ([38a0af8](https://github.com/Hypfer/Valetudo/commit/38a0af82db66428b8a6e7340dfaac394bbfcb2ac))\r\n* **ui:** Default to colorIndex 0 if solver can't find the segment in its graph ([e1565d0](https://github.com/Hypfer/Valetudo/commit/e1565d073642c87c084d93c56e031ebbec1160bd))\r\n* **ui:** Fix map coloring ([#567](https://github.com/Hypfer/Valetudo/issues/567)) ([890120c](https://github.com/Hypfer/Valetudo/commit/890120c76930bb8941459a7e0d1baa0af8577d83))\r\n* **ui:** Fixed zone dimensions ([0ca13e3](https://github.com/Hypfer/Valetudo/commit/0ca13e328d6e4943a444f750eb35365748dd5523))\r\n* **vacuum.roborock:** Changed set_lab_status payload for S6 to fix [#540](https://github.com/Hypfer/Valetudo/issues/540) ([19e141e](https://github.com/Hypfer/Valetudo/commit/19e141efc0b6e9f4798a9bff2482feaa10f3772f))\r\n* **vacuum.roborock:** Fix map parsing failing for maps with no image data ([f187906](https://github.com/Hypfer/Valetudo/commit/f1879064b15ea978df32a12f8a23b346ba2e3e39))\r\n* **vacuum.viomi:** Hackishly fixed map parsing for viomi v6 + fan speed settings for all viomi ([ffbb8e7](https://github.com/Hypfer/Valetudo/commit/ffbb8e75ffc4ce06bab6baa6f7328877cf66659b))\r\n* **vacuum.viomi:** Hackishly fixed path + angle ([fdd80d2](https://github.com/Hypfer/Valetudo/commit/fdd80d24c577a66ecb358f838e675126abd0c084))\r\n\r\n\r\n" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/27531929", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/27531929/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/27531929/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.5.3", + "id": 27531929, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI3NTMxOTI5", + "tag_name": "0.5.3", + "target_commitish": "master", + "name": "Valetudo 0.5.3", + "draft": false, + "prerelease": false, + "created_at": "2020-06-14T13:39:35Z", + "published_at": "2020-06-14T14:04:32Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/21736930", + "id": 21736930, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIxNzM2OTMw", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 32810703, + "download_count": 3114, + "created_at": "2020-06-14T14:05:08Z", + "updated_at": "2020-06-14T14:05:10Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.5.3/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.5.3", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.5.3", + "body": "
\r\n \"valetudo\"\r\n

0.5.3

\r\n
\r\n\r\nWith this release, Valetudo is upgraded to a stripped NodeJS 14.4.0 runtime, which brings both smaller binary size as well as enhanced performance.\r\n\r\nFurthermore, the long awaited cleaning of multiple zones via the Web Interface is finally here.\r\n\r\nIf you had root access to your Roborock S6/T6/S4/T4 or M1S, you could now use Valetudo as well.\r\nThere will be a guide on how to do that in the near future. Be aware, that no new features beyond those which are already available on the S5 are supported yet.\r\n\r\nIf you're a Valetudo developer, your life has become a lot easier with 0.5.3.\r\nRobot Model, Webserver Port and all the relevant settings are now configured via the config.json. No more messing around with ENV variables.\r\n\r\n\r\nHere's the autogenerated changelog:\r\n\r\n### Features\r\n\r\n* Initial Support for Roborock T/S4 and M1S ([24579f7](https://github.com/Hypfer/Valetudo/commit/24579f7acd98e276f4a85344919c4e8a8d356381))\r\n* Try to write a backup in case we're overwriting an invalid configuration file. ([#537](https://github.com/Hypfer/Valetudo/issues/537)) ([e738491](https://github.com/Hypfer/Valetudo/commit/e7384917354efa7e1d1b730b746966d4e46d87f2))\r\n* **ui:** Allow select of multiple zones for zone clean ([#535](https://github.com/Hypfer/Valetudo/issues/535)) ([1a29155](https://github.com/Hypfer/Valetudo/commit/1a29155094cdd76e02c5cbea28739d4637d90c00))\r\n* Added debug config option to continuously log memory usage ([d96eb15](https://github.com/Hypfer/Valetudo/commit/d96eb15c8f299ff49d98f9d6661c6f44225bc633))\r\n* Added option to fully configure model information via the config file ([#497](https://github.com/Hypfer/Valetudo/issues/497)) ([e241c1d](https://github.com/Hypfer/Valetudo/commit/e241c1d9b0dd1870f759fd8ebd1f1e7ec1f7cf61))\r\n* Initial support for S6 T6 and S5 Max ([f417b4d](https://github.com/Hypfer/Valetudo/commit/f417b4de3f27b0664552471c05adb220592f5c51))\r\n\r\n### Bug Fixes\r\n\r\n* **mqtt:** Removed unnecessary availability topic mitigation ([b76ce14](https://github.com/Hypfer/Valetudo/commit/b76ce144b4a3eb920a1dbab1991c83cf87ee7967))\r\n* Always assume embedded operation unless specified otherwise ([#536](https://github.com/Hypfer/Valetudo/issues/536)) ([7585f86](https://github.com/Hypfer/Valetudo/commit/7585f86e9fb1ec196b4b710454e1414673482081))\r\n* Removed useless app_get_locale functionality to fix [#532](https://github.com/Hypfer/Valetudo/issues/532) ([ffc06d6](https://github.com/Hypfer/Valetudo/commit/ffc06d65ba788cfbc3aee33b8e3d9d9e3fe647f9))\r\n* Simplify embedded logic now that 'auto' is gone. [#536](https://github.com/Hypfer/Valetudo/issues/536) ([b9097a6](https://github.com/Hypfer/Valetudo/commit/b9097a6f128aa947e4bb4a05fb3d79453f0f9e71))\r\n* **mqtt:** Update availability topic on each attribute topic update to fix false offline status ([af69673](https://github.com/Hypfer/Valetudo/commit/af696739d3119fbd84b1e9ba20b50b3fedce7a12))\r\n* **ui:** Fix [#527](https://github.com/Hypfer/Valetudo/issues/527) not working close and cancel buttons in timer settings ([e2ea1ce](https://github.com/Hypfer/Valetudo/commit/e2ea1ce212c4f85bba492dc273c6b7e75f4768b8))\r\n* **ui:** Hide forbidden zones editor menu item on gen 1 ([#382](https://github.com/Hypfer/Valetudo/issues/382)) ([32e9416](https://github.com/Hypfer/Valetudo/commit/32e94168fb3141fb49721be6019e0611690f3292))" + }, + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/26992913", + "assets_url": "https://api.github.com/repos/Hypfer/Valetudo/releases/26992913/assets", + "upload_url": "https://uploads.github.com/repos/Hypfer/Valetudo/releases/26992913/assets{?name,label}", + "html_url": "https://github.com/Hypfer/Valetudo/releases/tag/0.5.2", + "id": 26992913, + "author": { + "login": "Hypfer", + "id": 974410, + "node_id": "MDQ6VXNlcjk3NDQxMA==", + "avatar_url": "https://avatars.githubusercontent.com/u/974410?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Hypfer", + "html_url": "https://github.com/Hypfer", + "followers_url": "https://api.github.com/users/Hypfer/followers", + "following_url": "https://api.github.com/users/Hypfer/following{/other_user}", + "gists_url": "https://api.github.com/users/Hypfer/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Hypfer/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Hypfer/subscriptions", + "organizations_url": "https://api.github.com/users/Hypfer/orgs", + "repos_url": "https://api.github.com/users/Hypfer/repos", + "events_url": "https://api.github.com/users/Hypfer/events{/privacy}", + "received_events_url": "https://api.github.com/users/Hypfer/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "MDc6UmVsZWFzZTI2OTkyOTEz", + "tag_name": "0.5.2", + "target_commitish": "master", + "name": "Valetudo 0.5.2", + "draft": false, + "prerelease": false, + "created_at": "2020-05-28T14:06:02Z", + "published_at": "2020-05-28T14:15:20Z", + "assets": [ + { + "url": "https://api.github.com/repos/Hypfer/Valetudo/releases/assets/21144297", + "id": 21144297, + "node_id": "MDEyOlJlbGVhc2VBc3NldDIxMTQ0Mjk3", + "name": "valetudo", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "binary/octet-stream", + "state": "uploaded", + "size": 48594687, + "download_count": 1089, + "created_at": "2020-05-28T14:15:57Z", + "updated_at": "2020-05-28T14:15:58Z", + "browser_download_url": "https://github.com/Hypfer/Valetudo/releases/download/0.5.2/valetudo" + } + ], + "tarball_url": "https://api.github.com/repos/Hypfer/Valetudo/tarball/0.5.2", + "zipball_url": "https://api.github.com/repos/Hypfer/Valetudo/zipball/0.5.2", + "body": "
\r\n \"valetudo\"\r\n

0.5.2

\r\n
\r\n\r\nThis release contains a new and reworked Iconset for the map view as well as support for displaying detected rooms.\r\n\r\nFurthermore, these are the first release notes which feature semi-autogenerated changelogs utilizing [Conventional Commits](https://www.conventionalcommits.org)\r\n### Features\r\n\r\n* **mqtt:** Add availability as last will ([b196625](https://github.com/Hypfer/Valetudo/commit/b196625ac73e4932324b2bd2cf487790d6758711))\r\n* **ui:** Display Model information in Info Page ([8db6ca2](https://github.com/Hypfer/Valetudo/commit/8db6ca271aa63eeded999a377bcd02c94fa6dc16))\r\n* Always log Stacktrace on unclean exit code ([e2a542c](https://github.com/Hypfer/Valetudo/commit/e2a542c95a4abd147b3bb7f1c151247334347d1b))\r\n* **vacuum.roborock:** Add backup map restore to vacuum class ([2b76965](https://github.com/Hypfer/Valetudo/commit/2b7696565b02615a2aaeb73b6bf4bd1bca7885d4))\r\n* **vacuum.roborock:** added more events without handler ([3bbdd80](https://github.com/Hypfer/Valetudo/commit/3bbdd80f99339d8a8efb638f9ae1326399a0dd00))\r\n* log process exit code + debug log process exit stacktrace ([afd7e5a](https://github.com/Hypfer/Valetudo/commit/afd7e5a95781c7429d0d5b4ee2240fc3e26dfd89))\r\n* **mqtt:** added time and area information to mqtt attributes ([9eaf848](https://github.com/Hypfer/Valetudo/commit/9eaf848ef2f25d17ac8e19702abc24bf6ce19c90))\r\n* **ui:** Added and reworked icons, fixed rendering bugs and fully enabled map dark mode ([4c181ae](https://github.com/Hypfer/Valetudo/commit/4c181aee7f9f41a1881267a5a477b1ff499c4875))\r\n* new robot + charger icon ([964b935](https://github.com/Hypfer/Valetudo/commit/964b935a21e5af62e87ec84e32a751e99106b90f))\r\n* Parse and render segments ([386c344](https://github.com/Hypfer/Valetudo/commit/386c344160e5ad17e1d9503121d3ae87abb302b0))\r\n* **mqtt:** split broker_url in multiple fields ([c41f6da](https://github.com/Hypfer/Valetudo/commit/c41f6da874373b36bc670507d24ee488e5252ee8))\r\n* Upgrade MQTT to 4.0.0 ([#518](https://github.com/Hypfer/Valetudo/issues/518)) ([6063775](https://github.com/Hypfer/Valetudo/commit/606377569cfa31eb968e69536baa07617332213b))\r\n\r\n### Bug Fixes\r\n\r\n* **api:** remove passwords from /api/get_config ([18261bb](https://github.com/Hypfer/Valetudo/commit/18261bb1680cc28a80526869c2c2a95974f9072c))\r\n* **ui:** Fixed virtual wall placement ([6724e55](https://github.com/Hypfer/Valetudo/commit/6724e5556f3350c1c3cc6d4d5f09a9e08e8f2a6b))\r\n* **ui:** Removed misleading firmware version which was actually the miio_client version ([ac757b2](https://github.com/Hypfer/Valetudo/commit/ac757b2ba126509c7c61eb7d3aa987b9ea17f95c))\r\n* **vacuum:** missing roborock onStatusChange implementation ([cd42a7e](https://github.com/Hypfer/Valetudo/commit/cd42a7ed50c5b29d586470461f1c1afd9555419f))\r\n* **vacuum.roborock:** getCurrentStatus should return a promise ([dd63d75](https://github.com/Hypfer/Valetudo/commit/dd63d75cf2c15bbc7e65e459da7b865be2a3dffd))\r\n* **vacuum.roborock:** Limit maximum amount of virtual walls according to firmware limits ([6787826](https://github.com/Hypfer/Valetudo/commit/67878263132d3138b2eeb3820ed9c69349d08aea))" + } +] diff --git a/backend/test/lib/utils/KeyValueDeduplicationCache_spec.js b/backend/test/lib/utils/KeyValueDeduplicationCache_spec.js new file mode 100644 index 00000000..5e875dbb --- /dev/null +++ b/backend/test/lib/utils/KeyValueDeduplicationCache_spec.js @@ -0,0 +1,34 @@ +const should = require("should"); + +const KeyValueDeduplicationCache = require("../../../lib/utils/KeyValueDeduplicationCache"); + +should.config.checkProtoEql = false; + +describe("KeyValueDeduplicationCache", function () { + + it("Should deduplicate strings", async function() { + const cache = new KeyValueDeduplicationCache(); + + cache.update("theKey", "theValue").should.equal(true); + cache.update("theKey", "theValue").should.equal(false); + cache.update("theKey", "value2").should.equal(true); + cache.update("theKey", "value2").should.equal(false); + + cache.update("theKey2", "someValue").should.equal(true); + cache.update("theKey", "value2").should.equal(false); + cache.update("theKey2", "someValue").should.equal(false); + }); + + it("Should deduplicate buffers", async function() { + const cache = new KeyValueDeduplicationCache(); + + cache.update("theKey", Buffer.from("theValue")).should.equal(true); + cache.update("theKey", Buffer.from("theValue")).should.equal(false); + cache.update("theKey", Buffer.from("value2")).should.equal(true); + cache.update("theKey", Buffer.from("value2")).should.equal(false); + + cache.update("theKey2", Buffer.from("someValue")).should.equal(true); + cache.update("theKey", Buffer.from("value2")).should.equal(false); + cache.update("theKey2", Buffer.from("someValue")).should.equal(false); + }); +}); diff --git a/backend/test/lib/utils/LinuxToolsHelper_spec.js b/backend/test/lib/utils/LinuxToolsHelper_spec.js new file mode 100644 index 00000000..ab9d5437 --- /dev/null +++ b/backend/test/lib/utils/LinuxToolsHelper_spec.js @@ -0,0 +1,71 @@ +const fs = require("fs"); +const path = require("path"); +const should = require("should"); + +const LinuxToolsHelper = require("../../../lib/utils/LinuxToolsHelper"); + +should.config.checkProtoEql = false; + +describe("LinuxToolsHelper", function () { + + it("Should parse /proc/meminfo Kernel 3.4.39 from roborock s5 correctly", async function() { + let data = fs.readFileSync(path.join(__dirname, "/res/meminfo_3.4.39_roborock_s5.txt")).toString().replaceAll("\r", ""); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/meminfo_3.4.39_roborock_s5.json")).toString()); + + let actual = LinuxToolsHelper.PARSE_PROC_MEMINFO(data); + + actual.should.deepEqual(expected); + }); + + it("Should parse /proc/meminfo Kernel 3.4.39 from viomi v7 correctly", async function() { + let data = fs.readFileSync(path.join(__dirname, "/res/meminfo_3.4.39_viomi_v7.txt")).toString().replaceAll("\r", ""); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/meminfo_3.4.39_viomi_v7.json")).toString()); + + let actual = LinuxToolsHelper.PARSE_PROC_MEMINFO(data); + + actual.should.deepEqual(expected); + }); + + it("Should parse /proc/meminfo Kernel 4.9.191 from dreame z10 correctly", async function() { + let data = fs.readFileSync(path.join(__dirname, "/res/meminfo_4.9.191_dreame_z10.txt")).toString().replaceAll("\r", ""); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/meminfo_4.9.191_dreame_z10.json")).toString()); + + let actual = LinuxToolsHelper.PARSE_PROC_MEMINFO(data); + + actual.should.deepEqual(expected); + }); + + + + + + it("Should parse /proc/cmdline Kernel 3.4.39 from roborock s5 correctly", async function() { + let data = fs.readFileSync(path.join(__dirname, "/res/cmdline_3.4.39_roborock_s5.txt")).toString(); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/cmdline_3.4.39_roborock_s5.json")).toString()); + + let actual = LinuxToolsHelper.PARSE_PROC_CMDLINE(data); + + actual.should.deepEqual(expected); + }); + + it("Should parse /proc/cmdline Kernel 3.4.39 from viomi v7 correctly", async function() { + let data = fs.readFileSync(path.join(__dirname, "/res/cmdline_3.4.39_viomi_v7.txt")).toString(); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/cmdline_3.4.39_viomi_v7.json")).toString()); + + let actual = LinuxToolsHelper.PARSE_PROC_CMDLINE(data); + + actual.should.deepEqual(expected); + }); + + it("Should parse /proc/cmdline Kernel 4.9.191 from dreame z10 correctly", async function() { + let data = fs.readFileSync(path.join(__dirname, "/res/cmdline_4.9.191_dreame_z10.txt")).toString(); + let expected = JSON.parse(fs.readFileSync(path.join(__dirname, "/res/cmdline_4.9.191_dreame_z10.json")).toString()); + + let actual = LinuxToolsHelper.PARSE_PROC_CMDLINE(data); + + actual.should.deepEqual(expected); + }); + + + +}); diff --git a/backend/test/lib/utils/res/cmdline_3.4.39_roborock_s5.json b/backend/test/lib/utils/res/cmdline_3.4.39_roborock_s5.json new file mode 100644 index 00000000..edae2e8f --- /dev/null +++ b/backend/test/lib/utils/res/cmdline_3.4.39_roborock_s5.json @@ -0,0 +1,22 @@ +{ + "rootwait": true, + "boot_fs": "a", + "console": "ttyS0,115200", + "root": "/dev/mmcblk0p8", + "rootfstype": "ext4", + "loglevel": "7", + "partitions": { + "/dev/mmcblk0p2": "boot-res", + "/dev/mmcblk0p5": "env", + "/dev/mmcblk0p6": "app", + "/dev/mmcblk0p7": "recovery", + "/dev/mmcblk0p8": "system_a", + "/dev/mmcblk0p9": "system_b", + "/dev/mmcblk0p10": "Download", + "/dev/mmcblk0p11": "reserve", + "/dev/mmcblk0p1": "UDISK" + }, + "boot_reason": "0x69617070", + "location": "en", + "boot_ver": "2011.09-rc1-dirty" +} diff --git a/backend/test/lib/utils/res/cmdline_3.4.39_roborock_s5.txt b/backend/test/lib/utils/res/cmdline_3.4.39_roborock_s5.txt new file mode 100644 index 00000000..92ea6cb8 --- /dev/null +++ b/backend/test/lib/utils/res/cmdline_3.4.39_roborock_s5.txt @@ -0,0 +1 @@ +rootwait boot_fs=a console=ttyS0,115200 root=/dev/mmcblk0p8 rootfstype=ext4 loglevel=7 partitions=boot-res@mmcblk0p2:env@mmcblk0p5:app@mmcblk0p6:recovery@mmcblk0p7:system_a@mmcblk0p8:system_b@mmcblk0p9:Download@mmcblk0p10:reserve@mmcblk0p11:UDISK@mmcblk0p1 boot_reason=0x69617070 location=en boot_ver=2011.09-rc1-dirty diff --git a/backend/test/lib/utils/res/cmdline_3.4.39_viomi_v7.json b/backend/test/lib/utils/res/cmdline_3.4.39_viomi_v7.json new file mode 100644 index 00000000..bd07f39d --- /dev/null +++ b/backend/test/lib/utils/res/cmdline_3.4.39_viomi_v7.json @@ -0,0 +1,25 @@ +{ + "boot_type": "0", + "disp_para": "0", + "fb_base": "0x0", + "config_size": "40080", + "boot.serialno": "29a78a5860c6ffffea83", + "boot.hardware": "sun8i", + "console": "ttyS2,115200", + "root": "/dev/nandd", + "rootwait": true, + "init": "/sbin/init", + "ion_cma_list": "8m,32m,64m,128m,256m", + "loglevel": "4", + "partitions": { + "/dev/nanda": "boot-res", + "/dev/nandb": "env", + "/dev/nandc": "boot", + "/dev/nandd": "rootfs", + "/dev/nande": "rootfs_data", + "/dev/nandf": "private", + "/dev/nandg": "recovery", + "/dev/nandh": "misc", + "/dev/nandi": "UDISK" + } +} diff --git a/backend/test/lib/utils/res/cmdline_3.4.39_viomi_v7.txt b/backend/test/lib/utils/res/cmdline_3.4.39_viomi_v7.txt new file mode 100644 index 00000000..5e5f00fb --- /dev/null +++ b/backend/test/lib/utils/res/cmdline_3.4.39_viomi_v7.txt @@ -0,0 +1 @@ +boot_type=0 disp_para=0 fb_base=0x0 config_size=40080 boot.serialno=29a78a5860c6ffffea83 boot.hardware=sun8i console=ttyS2,115200 root=/dev/nandd rootwait init=/sbin/init ion_cma_list=8m,32m,64m,128m,256m loglevel=4 partitions=boot-res@nanda:env@nandb:boot@nandc:rootfs@nandd:rootfs_data@nande:private@nandf:recovery@nandg:misc@nandh:UDISK@nandi diff --git a/backend/test/lib/utils/res/cmdline_4.9.191_dreame_z10.json b/backend/test/lib/utils/res/cmdline_4.9.191_dreame_z10.json new file mode 100644 index 00000000..004e6b2b --- /dev/null +++ b/backend/test/lib/utils/res/cmdline_4.9.191_dreame_z10.json @@ -0,0 +1,39 @@ +{ + "console": "ttyS0,115200", + "root": "/dev/nand0p7", + "rootwait": true, + "init": "/sbin/init", + "rdinit": "/rdinit", + "loglevel": "0", + "earlyprintk": "sunxi-uart,0x05000000", + "initcall_debug": "0", + "partitions": { + "/dev/nand0p1": "boot-resource", + "/dev/nand0p2": "env", + "/dev/nand0p3": "env-redund", + "/dev/nand0p4": "boot1", + "/dev/nand0p5": "rootfs1", + "/dev/nand0p6": "boot2", + "/dev/nand0p7": "rootfs2", + "/dev/nand0p8": "private", + "/dev/nand0p9": "misc", + "/dev/nand0p10": "pstore", + "/dev/nand0p11": "UDISK" + }, + "cma": "4M", + "gpt": "1", + "rotpk_status": "0", + "pstore_blk.blkdev": "/dev/nand0p10", + "pstore.update_ms": "1000", + "androidboot.mode": "normal", + "androidboot.serialno": "cc00141db7444731d10", + "androidboot.hardware": "sun50iw10p1", + "boot_type": "0", + "androidboot.boot_type": "0", + "androidboot.secure_os_exist": "1", + "androidboot.trustchain": "false", + "androidboot.verifiedbootstate": "green", + "uboot_message": "2018.05-g8278af4(08/20/2020-06:52:00)", + "disp_reserve": "4096000,0x5c016280", + "bootreason": "button" +} diff --git a/backend/test/lib/utils/res/cmdline_4.9.191_dreame_z10.txt b/backend/test/lib/utils/res/cmdline_4.9.191_dreame_z10.txt new file mode 100644 index 00000000..2241d58f --- /dev/null +++ b/backend/test/lib/utils/res/cmdline_4.9.191_dreame_z10.txt @@ -0,0 +1 @@ +console=ttyS0,115200 root=/dev/nand0p7 rootwait init=/sbin/init rdinit=/rdinit loglevel=0 earlyprintk=sunxi-uart,0x05000000 initcall_debug=0 loglevel=0 partitions=boot-resource@nand0p1:env@nand0p2:env-redund@nand0p3:boot1@nand0p4:rootfs1@nand0p5:boot2@nand0p6:rootfs2@nand0p7:private@nand0p8:misc@nand0p9:pstore@nand0p10:UDISK@nand0p11 cma=4M gpt=1 rotpk_status=0 pstore_blk.blkdev=/dev/nand0p10 pstore.update_ms=1000 androidboot.mode=normal androidboot.serialno=cc00141db7444731d10 androidboot.hardware=sun50iw10p1 boot_type=0 androidboot.boot_type=0 androidboot.secure_os_exist=1 androidboot.trustchain=false gpt=1 androidboot.verifiedbootstate=green uboot_message=2018.05-g8278af4(08/20/2020-06:52:00) disp_reserve=4096000,0x5c016280 bootreason=button diff --git a/backend/test/lib/utils/res/meminfo_3.4.39_roborock_s5.json b/backend/test/lib/utils/res/meminfo_3.4.39_roborock_s5.json new file mode 100644 index 00000000..09388c3b --- /dev/null +++ b/backend/test/lib/utils/res/meminfo_3.4.39_roborock_s5.json @@ -0,0 +1,35 @@ +{ + "Active": 90271744, + "Active(anon)": 74407936, + "Active(file)": 15863808, + "AnonPages": 73109504, + "Bounce": 0, + "Buffers": 28938240, + "Cached": 60735488, + "CommitLimit": 261394432, + "Committed_AS": 264192000, + "Dirty": 20480, + "Inactive": 72519680, + "Inactive(anon)": 2625536, + "Inactive(file)": 69894144, + "KernelStack": 1286144, + "Mapped": 29560832, + "MemFree": 314470400, + "MemTotal": 522792960, + "Mlocked": 0, + "NFS_Unstable": 0, + "PageTables": 1273856, + "SReclaimable": 12386304, + "SUnreclaim": 8323072, + "Shmem": 3923968, + "Slab": 20709376, + "SwapCached": 0, + "SwapFree": 0, + "SwapTotal": 0, + "Unevictable": 0, + "VmallocChunk": 255131648, + "VmallocTotal": 511705088, + "VmallocUsed": 5246976, + "Writeback": 0, + "WritebackTmp": 0 +} diff --git a/backend/test/lib/utils/res/meminfo_3.4.39_roborock_s5.txt b/backend/test/lib/utils/res/meminfo_3.4.39_roborock_s5.txt new file mode 100644 index 00000000..ddcb83c8 --- /dev/null +++ b/backend/test/lib/utils/res/meminfo_3.4.39_roborock_s5.txt @@ -0,0 +1,33 @@ +MemTotal: 510540 kB +MemFree: 307100 kB +Buffers: 28260 kB +Cached: 59312 kB +SwapCached: 0 kB +Active: 88156 kB +Inactive: 70820 kB +Active(anon): 72664 kB +Inactive(anon): 2564 kB +Active(file): 15492 kB +Inactive(file): 68256 kB +Unevictable: 0 kB +Mlocked: 0 kB +SwapTotal: 0 kB +SwapFree: 0 kB +Dirty: 20 kB +Writeback: 0 kB +AnonPages: 71396 kB +Mapped: 28868 kB +Shmem: 3832 kB +Slab: 20224 kB +SReclaimable: 12096 kB +SUnreclaim: 8128 kB +KernelStack: 1256 kB +PageTables: 1244 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 255268 kB +Committed_AS: 258000 kB +VmallocTotal: 499712 kB +VmallocUsed: 5124 kB +VmallocChunk: 249152 kB diff --git a/backend/test/lib/utils/res/meminfo_3.4.39_viomi_v7.json b/backend/test/lib/utils/res/meminfo_3.4.39_viomi_v7.json new file mode 100644 index 00000000..ac2eeaa1 --- /dev/null +++ b/backend/test/lib/utils/res/meminfo_3.4.39_viomi_v7.json @@ -0,0 +1,39 @@ +{ + "MemTotal": 536870912, + "MemFree": 251392000, + "Buffers": 15433728, + "Cached": 66658304, + "SwapCached": 0, + "Active": 180379648, + "Inactive": 67112960, + "Active(anon)": 167264256, + "Inactive(anon)": 28672, + "Active(file)": 13115392, + "Inactive(file)": 67084288, + "Unevictable": 0, + "Mlocked": 0, + "HighTotal": 0, + "HighFree": 0, + "LowTotal": 524058624, + "LowFree": 251392000, + "SwapTotal": 0, + "SwapFree": 0, + "Dirty": 0, + "Writeback": 0, + "AnonPages": 165425152, + "Mapped": 33492992, + "Shmem": 1892352, + "Slab": 11808768, + "SReclaimable": 3829760, + "SUnreclaim": 7979008, + "KernelStack": 1171456, + "PageTables": 1294336, + "NFS_Unstable": 0, + "Bounce": 0, + "WritebackTmp": 0, + "CommitLimit": 262029312, + "Committed_AS": 236625920, + "VmallocTotal": 511705088, + "VmallocUsed": 6078464, + "VmallocChunk": 255975424 +} diff --git a/backend/test/lib/utils/res/meminfo_3.4.39_viomi_v7.txt b/backend/test/lib/utils/res/meminfo_3.4.39_viomi_v7.txt new file mode 100644 index 00000000..3df8455c --- /dev/null +++ b/backend/test/lib/utils/res/meminfo_3.4.39_viomi_v7.txt @@ -0,0 +1,37 @@ +MemTotal: 524288 kB +MemFree: 245500 kB +Buffers: 15072 kB +Cached: 65096 kB +SwapCached: 0 kB +Active: 176152 kB +Inactive: 65540 kB +Active(anon): 163344 kB +Inactive(anon): 28 kB +Active(file): 12808 kB +Inactive(file): 65512 kB +Unevictable: 0 kB +Mlocked: 0 kB +HighTotal: 0 kB +HighFree: 0 kB +LowTotal: 511776 kB +LowFree: 245500 kB +SwapTotal: 0 kB +SwapFree: 0 kB +Dirty: 0 kB +Writeback: 0 kB +AnonPages: 161548 kB +Mapped: 32708 kB +Shmem: 1848 kB +Slab: 11532 kB +SReclaimable: 3740 kB +SUnreclaim: 7792 kB +KernelStack: 1144 kB +PageTables: 1264 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 255888 kB +Committed_AS: 231080 kB +VmallocTotal: 499712 kB +VmallocUsed: 5936 kB +VmallocChunk: 249976 kB diff --git a/backend/test/lib/utils/res/meminfo_4.9.191_dreame_z10.json b/backend/test/lib/utils/res/meminfo_4.9.191_dreame_z10.json new file mode 100644 index 00000000..ba2dcc07 --- /dev/null +++ b/backend/test/lib/utils/res/meminfo_4.9.191_dreame_z10.json @@ -0,0 +1,38 @@ +{ + "MemTotal": 501870592, + "MemFree": 138256384, + "MemAvailable": 277094400, + "Buffers": 26779648, + "Cached": 104718336, + "SwapCached": 0, + "Active": 201469952, + "Inactive": 80515072, + "Active(anon)": 153038848, + "Inactive(anon)": 405504, + "Active(file)": 48431104, + "Inactive(file)": 80109568, + "Unevictable": 0, + "Mlocked": 0, + "SwapTotal": 0, + "SwapFree": 0, + "Dirty": 49152, + "Writeback": 0, + "AnonPages": 150528000, + "Mapped": 63811584, + "Shmem": 2957312, + "Slab": 57352192, + "SReclaimable": 21700608, + "SUnreclaim": 35651584, + "KernelStack": 2179072, + "PageTables": 1290240, + "NFS_Unstable": 0, + "Bounce": 0, + "WritebackTmp": 0, + "CommitLimit": 250933248, + "Committed_AS": 409722880, + "VmallocTotal": 269374914560, + "VmallocUsed": 0, + "VmallocChunk": 0, + "CmaTotal": 4194304, + "CmaFree": 1736704 +} diff --git a/backend/test/lib/utils/res/meminfo_4.9.191_dreame_z10.txt b/backend/test/lib/utils/res/meminfo_4.9.191_dreame_z10.txt new file mode 100644 index 00000000..f907998d --- /dev/null +++ b/backend/test/lib/utils/res/meminfo_4.9.191_dreame_z10.txt @@ -0,0 +1,36 @@ +MemTotal: 490108 kB +MemFree: 135016 kB +MemAvailable: 270600 kB +Buffers: 26152 kB +Cached: 102264 kB +SwapCached: 0 kB +Active: 196748 kB +Inactive: 78628 kB +Active(anon): 149452 kB +Inactive(anon): 396 kB +Active(file): 47296 kB +Inactive(file): 78232 kB +Unevictable: 0 kB +Mlocked: 0 kB +SwapTotal: 0 kB +SwapFree: 0 kB +Dirty: 48 kB +Writeback: 0 kB +AnonPages: 147000 kB +Mapped: 62316 kB +Shmem: 2888 kB +Slab: 56008 kB +SReclaimable: 21192 kB +SUnreclaim: 34816 kB +KernelStack: 2128 kB +PageTables: 1260 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 245052 kB +Committed_AS: 400120 kB +VmallocTotal: 263061440 kB +VmallocUsed: 0 kB +VmallocChunk: 0 kB +CmaTotal: 4096 kB +CmaFree: 1696 kB diff --git a/build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-armv7 b/build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-arm64 similarity index 72% rename from build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-armv7 rename to build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-arm64 index 11df18d4..6e9ecd69 100644 Binary files a/build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-armv7 and b/build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-arm64 differ diff --git a/build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-arm64 b/build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-armv7 similarity index 63% rename from build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-arm64 rename to build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-armv7 index c4375b93..db935752 100644 Binary files a/build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-arm64 and b/build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-armv7 differ diff --git a/build_dependencies/readme.md b/build_dependencies/readme.md deleted file mode 100644 index 90dc468d..00000000 --- a/build_dependencies/readme.md +++ /dev/null @@ -1,6 +0,0 @@ -Due to [ideological differences](https://github.com/vercel/pkg-fetch/issues/109#issuecomment-831393241), -we still have to vendor and build our own pkg base binaries. - -This however has gotten at least a bit more streamlined since pkg-fetch 3.0.0 was released. - -See [https://github.com/Hypfer/pkg-fetch](https://github.com/Hypfer/pkg-fetch) for more information diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 20dea458..c5551ee4 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.0.4.1) + activesupport (6.0.4.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -17,39 +17,43 @@ GEM commonmarker (0.17.13) ruby-enum (~> 0.5) concurrent-ruby (1.1.9) - dnsruby (1.61.7) + dnsruby (1.61.9) simpleidn (~> 0.1) - em-websocket (0.5.2) + em-websocket (0.5.3) eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) - ethon (0.14.0) + http_parser.rb (~> 0) + ethon (0.15.0) ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.8.1) - faraday (1.7.1) + faraday (1.10.0) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.1) + faraday-net_http_persistent (~> 1.0) faraday-patron (~> 1.0) faraday-rack (~> 1.0) - multipart-post (>= 1.2, < 3) + faraday-retry (~> 1.0) ruby2_keywords (>= 0.0.4) faraday-em_http (1.0.0) faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) - ffi (1.15.3) + faraday-retry (1.0.3) + ffi (1.15.5) forwardable-extended (2.6.0) gemoji (3.0.1) - github-pages (219) - github-pages-health-check (= 1.17.7) + github-pages (223) + github-pages-health-check (= 1.17.9) jekyll (= 3.9.0) jekyll-avatar (= 0.7.0) jekyll-coffeescript (= 1.1.1) @@ -58,6 +62,7 @@ GEM jekyll-feed (= 0.15.1) jekyll-gist (= 1.5.0) jekyll-github-metadata (= 2.13.0) + jekyll-include-cache (= 0.2.1) jekyll-mentions (= 1.6.0) jekyll-optional-front-matter (= 0.3.2) jekyll-paginate (= 1.1.0) @@ -89,10 +94,10 @@ GEM liquid (= 4.0.3) mercenary (~> 0.3) minima (= 2.5.1) - nokogiri (>= 1.10.4, < 2.0) + nokogiri (>= 1.12.5, < 2.0) rouge (= 3.26.0) terminal-table (~> 1.4) - github-pages-health-check (1.17.7) + github-pages-health-check (1.17.9) addressable (~> 2.3) dnsruby (~> 1.60) octokit (~> 4.0) @@ -101,7 +106,7 @@ GEM html-pipeline (2.14.0) activesupport (>= 2) nokogiri (>= 1.4) - http_parser.rb (0.6.0) + http_parser.rb (0.8.0) i18n (0.9.5) concurrent-ruby (~> 1.0) jekyll (3.9.0) @@ -138,6 +143,8 @@ GEM jekyll-github-metadata (2.13.0) jekyll (>= 3.4, < 5.0) octokit (~> 4.0, != 4.4.0) + jekyll-include-cache (0.2.1) + jekyll (>= 3.7, < 5.0) jekyll-mentions (1.6.0) html-pipeline (~> 2.3) jekyll (>= 3.7, < 5.0) @@ -215,7 +222,7 @@ GEM kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) liquid (4.0.3) - listen (3.7.0) + listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) @@ -223,18 +230,18 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.14.4) + minitest (5.15.0) multipart-post (2.1.1) nokogiri (1.13.8-x86_64-linux) racc (~> 1.4) - octokit (4.21.0) + octokit (4.22.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) pathutil (0.16.2) forwardable-extended (~> 2.6) public_suffix (4.0.6) racc (1.6.0) - rb-fsevent (0.11.0) + rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) rexml (3.2.5) @@ -263,9 +270,9 @@ GEM thread_safe (~> 0.1) unf (0.1.4) unf_ext - unf_ext (0.0.7.7) - unicode-display_width (1.7.0) - zeitwerk (2.4.2) + unf_ext (0.0.8.1) + unicode-display_width (1.8.0) + zeitwerk (2.5.4) PLATFORMS x86_64-linux @@ -278,4 +285,4 @@ DEPENDENCIES wdm (~> 0.1.1) BUNDLED WITH - 2.2.26 + 2.2.27 diff --git a/docs/_config.yml b/docs/_config.yml index 4c1ef340..d851f21a 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,13 +1,11 @@ title: Valetudo description: >- - Valetudo aims to be a vendor-agnostic abstraction and cloud replacement for vacuum robots which started as a standalone binary on rooted roborock vacuums. + Open source cloud replacement for vacuum robots enabling local-only operation baseurl: "" url: https://valetudo.cloud github_username: Hypfer -remote_theme: pages-themes/minimal@v0.2.0 plugins: - - jekyll-remote-theme - jekyll-seo-tag collections: pages: diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index b3fd5d93..51e59088 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -58,6 +58,5 @@

{{ cat.name }}

- diff --git a/docs/_pages/companion_apps/fun_games.md b/docs/_pages/companion_apps/fun_games.md index 4746c2b0..8dcb8eaa 100644 --- a/docs/_pages/companion_apps/fun_games.md +++ b/docs/_pages/companion_apps/fun_games.md @@ -1,7 +1,7 @@ --- title: Fun & Games category: Companion Apps -order: 19 +order: 20 --- # Valetudo Minecraft Mapper diff --git a/docs/_pages/companion_apps/i_cant_believe_its_not_valetudo.md b/docs/_pages/companion_apps/i_cant_believe_its_not_valetudo.md index 0e2c6c2b..29cc7367 100644 --- a/docs/_pages/companion_apps/i_cant_believe_its_not_valetudo.md +++ b/docs/_pages/companion_apps/i_cant_believe_its_not_valetudo.md @@ -1,7 +1,7 @@ --- title: I can't believe it's not Valetudo category: Companion Apps -order: 17 +order: 18 --- # I can't believe it's not Valetudo diff --git a/docs/_pages/companion_apps/lovelace_valetudo_map_card.md b/docs/_pages/companion_apps/lovelace_valetudo_map_card.md index ee001d64..f4e406e9 100644 --- a/docs/_pages/companion_apps/lovelace_valetudo_map_card.md +++ b/docs/_pages/companion_apps/lovelace_valetudo_map_card.md @@ -1,7 +1,7 @@ --- title: Lovelace Valetudo Map Card category: Companion Apps -order: 16 +order: 17 --- # Lovelace Valetudo Map Card diff --git a/docs/_pages/companion_apps/node-red-contrib-valetudo.md b/docs/_pages/companion_apps/node-red-contrib-valetudo.md index e37ce474..5bed0046 100644 --- a/docs/_pages/companion_apps/node-red-contrib-valetudo.md +++ b/docs/_pages/companion_apps/node-red-contrib-valetudo.md @@ -1,7 +1,7 @@ --- title: node-red-contrib-valetudo category: Companion Apps -order: 18 +order: 19 --- # node-red-contrib-valetudo diff --git a/docs/_pages/companion_apps/other_noteworthy_projects.md b/docs/_pages/companion_apps/other_noteworthy_projects.md index adf55e7b..d061daca 100644 --- a/docs/_pages/companion_apps/other_noteworthy_projects.md +++ b/docs/_pages/companion_apps/other_noteworthy_projects.md @@ -1,7 +1,7 @@ --- title: Other Noteworthy Projects category: Companion Apps -order: 20 +order: 21 --- # Other Noteworthy Projects @@ -12,7 +12,7 @@ This page lists things that aren't necessarily Valetudo Companion services but m These things apply to roborock only -### Rockbin +### Rockbin (Archived) A Go-based microservice, which publishes the dustbin state to mqtt. diff --git a/docs/_pages/companion_apps/valeronoi.md b/docs/_pages/companion_apps/valeronoi.md index ec28b86a..5c65165d 100644 --- a/docs/_pages/companion_apps/valeronoi.md +++ b/docs/_pages/companion_apps/valeronoi.md @@ -1,7 +1,7 @@ --- title: Valeronoi category: Companion Apps -order: 15 +order: 16 --- # Valeronoi diff --git a/docs/_pages/companion_apps/valetudo_companion.md b/docs/_pages/companion_apps/valetudo_companion.md index 7f391684..cdb48fea 100644 --- a/docs/_pages/companion_apps/valetudo_companion.md +++ b/docs/_pages/companion_apps/valetudo_companion.md @@ -15,7 +15,7 @@ Note that this app is completely optional and only exists to make Valetudo more This app will not provide any UI to interface with Valetudo during normal operation. Basically, you can think of it as an automatically updating bookmark + some wizard stuff. -Its sourcecode is available on Github (Apache-2.0): [https://github.com/Hypfer/valetudo-companion](https://github.com/Hypfer/valetudo-companion) +Its sourcecode is available on GitHub (Apache-2.0): [https://github.com/Hypfer/valetudo-companion](https://github.com/Hypfer/valetudo-companion) ## How to Install diff --git a/docs/_pages/companion_apps/valetudo_tray_companion.md b/docs/_pages/companion_apps/valetudo_tray_companion.md new file mode 100644 index 00000000..696d42b2 --- /dev/null +++ b/docs/_pages/companion_apps/valetudo_tray_companion.md @@ -0,0 +1,13 @@ +--- +title: Valetudo Tray Companion (Windows) +category: Companion Apps +order: 15 +--- +# Valetudo Tray Companion (Windows) + +![image](https://user-images.githubusercontent.com/974410/156892054-01d113e8-17e3-4a6f-b931-3eb2b54756d4.png) + +Valetudo Tray Companion (Windows) offers a tray icon, which on right-click provides you with a list of Valetudo instances on your network.
+Clicking on one of them will open its Webinterface in your default browser. + +Downloads, installation instructions and the sourcecode (Apache-2.0) can be found on GitHub: [https://github.com/Hypfer/valetudo-tray-companion](https://github.com/Hypfer/valetudo-tray-companion). diff --git a/docs/_pages/dev_faq.md b/docs/_pages/dev_faq.md deleted file mode 100644 index c148531a..00000000 --- a/docs/_pages/dev_faq.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: Frequently requested features -category: Misc -order: 31 ---- -# Frequently requested features - -## Translation support - -While a lot of people are asking for this feature, I'm afraid it won't happen anytime soon if ever. - -Let me explain the reasoning behind this with an example. Consider this car radio in a car made for the german market: - -![Bosch Car Radio](./img/car_radio.jpg) - -In fact, the radio is engineered by Bosch in Hildesheim. Still, the button isn't labeled `Karte`. - -Now, let's take a look at the Valetudo UI (Version 0.6.1): - -![Valetudo 0.6.1 UI](./img/valetudo-ui.png) - -Regarding overall complexity, it's comparable to the buttons on the radio. -It's even easier to understand, because there are a lot more icons.
-Considering that people do in fact manage to use their car radios even if their english skills may be lacking, -I'd say that **accessibility** isn't a problem here. - - -As a matter of fact, Internationalization isn't free. It always introduces more work, more complexity etc.
-Of course **accessibility** is often worth the effort, however since we've already established that this factor isn't relevant here, -we can take a look at a non-exhaustive list of downsides of i18n: - -* Getting support is harder when screenshots/error messages are in a language that isn't english, because supporters may not speak it -* Development of new features, refactoring etc. is always blocked by having to translate everything new to all languages -* Increased codebase complexity - * Harder to read - * Harder to work with -* Lots of initial work to translate everything - * Time/effort that could be spent better elsewhere - -Now, let us look at another real-world example of i18n. - -![Apple Shortcuts Example](./img/apple_shortcuts_example.png) - -This is a screenshot of Apple Shortcuts running on an iPhone set to the German locale. -It is just a basic HTTP PUT with a JSON payload. -For some reason however, "Header" as in "HTTP Header" was translated to "Überschrift" which means "Headline". -Even worse, "Request body" became "Haupttext anfordern" which translated back to english means "(to) request the main text"??? - -The actual meaning got lost in translation, which is a common issue. -Even with german being a common language and understanding of the HTTP protocol being fairly common as well. - -Preventing this is hard, because you will need someone who understands the project from a technical standpoint as well as speaks the language it should be translated to. -This is also required even if the translation is done by someone else, because you still have to validate what they did. - -As even huge corporations known for being user-friendly and also paired with insane budgets fail to do this all the time, -I don't think that it is actually a feasible task. - -# Multiple Maps / Multi-Floor - -Multiple maps are a feature that is inherently linked to a huge increase in code complexity since most functionality -of the robot needs to be aware of not only that there are multiple maps but also, which one is the current one. - -These include but are not limited to -- Zone Presets -- GoTo Locations -- Timers -- Cached stuff such as roborock segment names - -It gets even worse when there are multiple versions of each map due to stuff like automated snapshots/backups. - -This change costs time and therefore money, but it is not just a one-time payment. The increase in complexity is permanent -meaning that the cost of maintaining the codebase is also increased permanently. - -Even if there was a PR to reduce the initial cost, it would still not be merged due to its permanent impact -on the running costs.
-Implementing multi-floor support was already investigated multiple times with each iteration resulting in the discovery -of even more things that make this hard to pull off using Valetudo. - -A lot of stuff in the robots core operation logic assumes that the cloud is always available with a permanent storage -of all data such as maps uploaded to it in some database or similar. -Sometimes, the robot will report to the cloud that it won't upload the requested map file again as instead -the cloud should use file with ID XYZ. This works fine when the cloud is actually the cloud but breaks entirely -when the "cloud" is Valetudo with no persistent storage of uploads. - -Adding persistence also isn't feasible, because you'd need to store everything all the time as you can never know -if an uploaded artifact might become relevant later. There are simply not enough resources to do that on the robot. - - -Furthermore, since vacuum robots cannot climb stairs, the whole multi-floor experience is just objectively inferior -as you loose the ability to do all the fancy automation stuff with robots starting to clean a room as soon as everyone has left etc. - - -And lastly, as of now (2021-10-23), you can get a factory-new robot supported by Valetudo for less than 150€.
-If you own a multi-floor home, there is absolutely no possibility that you're unable to afford that. diff --git a/docs/_pages/development/building-and-modifying-valetudo.md b/docs/_pages/development/building-and-modifying-valetudo.md index b0bf0120..57648d85 100644 --- a/docs/_pages/development/building-and-modifying-valetudo.md +++ b/docs/_pages/development/building-and-modifying-valetudo.md @@ -69,10 +69,6 @@ When running on the robot itself, these are usually detected automatically. | | deviceId | /mnt/default/device.conf | did | | | cloudSecret | /mnt/default/device.conf | key | | | localSecret | /mnt/data/miio/device.token | | -| Viomi | valetudo.conf | /mnt/data/valetudo/config.json | | -| | deviceId | /etc/miio/device.conf | did | -| | cloudSecret | /etc/miio/device.conf | key | -| | localSecret | /etc/miio/device.token | | | Dreame | valetudo.conf | /data/valetudo_config.json | | | | deviceId | /data/config/miio/device.conf | did | | | cloudSecret | /data/config/miio/device.conf | key | diff --git a/docs/_pages/development/valetudo-core-concepts.md b/docs/_pages/development/valetudo-core-concepts.md index 590b2c2f..e859a152 100644 --- a/docs/_pages/development/valetudo-core-concepts.md +++ b/docs/_pages/development/valetudo-core-concepts.md @@ -46,7 +46,7 @@ Capabilities are the base class for everything a robot can do which solves the p different subsets of all of the vendors possible features which would be hard to implement by simple inheritance. There's always a generic base class for each feature (e.g. `GoToLocationCapability`) which is extended by multiple vendor-specific -implementations (e.g. `RoborockGoToLocationCapability`, `ViomiGoToLocationCapability` etc). +implementations (e.g. `RoborockGoToLocationCapability`). Capabilities may only be implemented fully so that we can be certain, that a Robot with a `GoToLocationCapability` will always be able to do everything the `GoToLocationCapability`. diff --git a/docs/_pages/general/buying-supported-robots.md b/docs/_pages/general/buying-supported-robots.md index 5a8f0043..73936bfe 100644 --- a/docs/_pages/general/buying-supported-robots.md +++ b/docs/_pages/general/buying-supported-robots.md @@ -1,15 +1,38 @@ --- title: Buying supported robots category: General -order: 12 +order: 13 --- # Buying supported robots The recommended source to buy a [supported robot](https://valetudo.cloud/pages/general/supported-robots.html) is -wherever it is cheapest. After rooting, you won't have any warranty anyways, which is why buying local usually doesn't -offer any benefits apart from higher prices. +wherever it is cheapest. In general, when buying something, you should always use price comparison websites, shopping communities, check Aliexpress etc. -In general, when buying something, you should always use price comparison websites, shopping communities, check Aliexpress etc. +## Recommendation + +As mentioned above, the [supported robots](https://valetudo.cloud/pages/general/supported-robots.html) offers an autogenerated +overview of all supported robots. + +For your convenience however, here's the gist of it (updated 2022-08-05). + +**Note:** +This list only features robots that can be fairly easy to root depending on the firmware they're running. +They're also ranked based on desirability due to features, performance, etc. + +For buying a new robot, the best options would be the these: + +- Dreame Z10 +- Dreame L10 + +If you're on a budget, you could also consider buying one of these: + +- Dreame D9 (not max!) +- Roborock S5 (used. They're not being made anymore) (not max!) + +If you're even more on a budget, consider buying one of these: + +- Dreame F9 +- Dreame 1C ## Affiliate links diff --git a/docs/_pages/general/capabilities-overview.md b/docs/_pages/general/capabilities-overview.md index 8a623f85..3c3e24bd 100644 --- a/docs/_pages/general/capabilities-overview.md +++ b/docs/_pages/general/capabilities-overview.md @@ -1,7 +1,7 @@ --- title: Capabilities Overview category: General -order: 9 +order: 10 --- # Capabilities overview @@ -57,8 +57,6 @@ This capability enables you to send your robot to a location on your map. It wil One common use-case of this is to send the robot to your bin. -Furthermore, this capability will enable you to define ValetudoGoToLocationPresets which are predefined spots that can be called via MQTT. - ## KeyLockCapability This capability enables you to disable control of the robot via the buttons on the devices. @@ -143,5 +141,3 @@ This capability enables you to get the current Wi-Fi connection details (includi ## ZoneCleaningCapability This capability enables you to send your robot to clean one or more (depending on the vendor) zones drawn onto the map. - -Furthermore, this also enables you to define ValetudoZonePresets which are predefined zones that can be called via MQTT. diff --git a/docs/_pages/general/firmware-updates.md b/docs/_pages/general/firmware-updates.md new file mode 100644 index 00000000..01ef0181 --- /dev/null +++ b/docs/_pages/general/firmware-updates.md @@ -0,0 +1,28 @@ +--- +title: Firmware Updates +category: General +order: 12 +--- + +# Firmware Updates + +By rooting your robot, you will lose the ability to install firmware updates directly from the vendor via OTA. +This is intentional as those would un-root your robot. +To update your robots' firmware, you will need to install a rooted version of that firmware. + +Do note that just because a new firmware version is out, this does not mean that you'll be able to instantly install and use it. +With every new firmware, we need to figure out how to root and patch it to work offline. + +Usually, some software updates break out patching, and thus we have to rework it. +Occasionally, the vendor might even introduce new countermeasures against us. +While unlikely, it might happen that a new firmware version turns out to not be rootable at all. Do keep that in mind. + + +To update your robots' firmware, simply head over to [the Dustbuilder](https://builder.dontvacuum.me/) and build a new +rooted firmware image with the version you want to install. Make sure to select the "Build for manual installation" option. + +With the image built, SSH into your robot, download the tar file, extract it and install the firmware with the installation script provided inside the tar file. +The process is basically the same as the one done during the initial root. Make sure that the robot is docked during that procedure. + +If your robot has multiple system partitions like most of them do, you can run that install procedure twice for good measure. +It is however not required to do that. diff --git a/docs/_pages/general/getting-started.md b/docs/_pages/general/getting-started.md index 57ebe3c8..97d3f493 100644 --- a/docs/_pages/general/getting-started.md +++ b/docs/_pages/general/getting-started.md @@ -1,7 +1,7 @@ --- title: Getting Started category: General -order: 7 +order: 8 --- # Getting Started @@ -9,6 +9,9 @@ order: 7 This page shall help you start using Valetudo. Make sure that you've read the [latest newcomer guide](https://valetudo.cloud/pages/general/newcomer_guide_late_2021.html). If you haven't done that already please do so and then come back here. +You may also want to read the [Why Valetudo?](https://valetudo.cloud/pages/general/why-valetudo.html) and [Why not Valetudo?](https://valetudo.cloud/pages/general/why-not-valetudo.html) +pages before continuing with this guide. + ## Table of Contents 0. [Choosing a robot](#choosing_a_robot) 1. [Installing Valetudo](#installing_valetudo) @@ -19,8 +22,10 @@ If you haven't done that already please do so and then come back here. ## Choosing a robot First, you'll need to acquire a supported robot. There are many ways to do that, but usually they involve you paying money. -To not waste all that hard-earned money, please make sure to thoroughly read the [supported robots](https://valetudo.cloud/pages/general/supported-robots.html) -docs page. There are remarks for each device, which shall help you decide on what to buy. +To not waste all that hard-earned money, please make sure to thoroughly read the [buying supported robots](https://valetudo.cloud/pages/general/buying-supported-robots.html) +docs page. +There's also the [supported robots](https://valetudo.cloud/pages/general/supported-robots.html) page, which features +remarks for each device to further help you decide on what to buy. Please refrain from buying any random robot just to then ask how we can make Valetudo on that thing happen. @@ -48,7 +53,14 @@ and follow the instructions there after pressing the + button on the bottom righ [](https://github.com/Hypfer/valetudo-companion/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-05.png) -You can also connect to the Webinterface of Valetudo in your browser and use it to do the provisioning. +If you are using a laptop, an iphone or remember to disable mobile data on your android phone yourself, +you can also visit Valetudo by connecting to the AP provided by the robot and do the provisioning via its webinterface: + +![image](https://user-images.githubusercontent.com/974410/142760331-ee5a4031-c692-49be-9ad8-4144f35bb5e0.png) + +The IP of robot can either be figured out by the IP assigned to you by its DHCP server or by just trying out +`http://192.168.5.1` and `http://192.168.8.1`. +Note that some browsers might try redirecting you to `https://` without you noticing. ## Using Valetudo @@ -64,8 +76,6 @@ If you're using a computer running Microsoft Windows, you can also open the expl ![image](https://user-images.githubusercontent.com/974410/127387044-da7e8c18-390f-40bc-88b1-3ff316e4e6cf.png) -If things don't work as expected after the initial Wi-Fi provisioning, please try rebooting the robot once. - ## Now What? Congratulations! You have now significantly increased the baseline cleanliness of your living space. diff --git a/docs/_pages/img/apple_shortcuts_example.png b/docs/_pages/general/img/apple_shortcuts_example.png similarity index 100% rename from docs/_pages/img/apple_shortcuts_example.png rename to docs/_pages/general/img/apple_shortcuts_example.png diff --git a/docs/_pages/img/car_radio.jpg b/docs/_pages/general/img/car_radio.jpg similarity index 100% rename from docs/_pages/img/car_radio.jpg rename to docs/_pages/general/img/car_radio.jpg diff --git a/docs/_pages/img/valetudo-ui.png b/docs/_pages/general/img/valetudo-ui.png similarity index 100% rename from docs/_pages/img/valetudo-ui.png rename to docs/_pages/general/img/valetudo-ui.png diff --git a/docs/_pages/general/img/visual_studio_2017_example.png b/docs/_pages/general/img/visual_studio_2017_example.png new file mode 100644 index 00000000..9598945a Binary files /dev/null and b/docs/_pages/general/img/visual_studio_2017_example.png differ diff --git a/docs/_pages/general/newcomer_guide_early_2021.md b/docs/_pages/general/newcomer_guide_early_2021.md index 6065a4ae..9e55e808 100644 --- a/docs/_pages/general/newcomer_guide_early_2021.md +++ b/docs/_pages/general/newcomer_guide_early_2021.md @@ -10,7 +10,14 @@ Hi and welcome to the Valetudo Newcomer Guide Early 2021 Edition This should hopefully answer all the questions you might have and also be interesting to read for people that haven't been following the recent development. -**Note: This guide has been archived and is only still here so that links don't break. You should [read the most recent one instead.](https://valetudo.cloud/pages/general/newcomer_guide_late_2021.html)** + @@ -19,7 +26,7 @@ This should hopefully answer all the questions you might have and also be intere Valetudo is a cloud replacement for vacuum robots enabling local-only operation. It is not a custom firmware. That means that it cannot change anything about how the robot operates. -What it can do however is protect your data and enable you to connect your robot +What it can do however is protecting your data and enable you to connect your robot to your home automation system without having to detour through a vendor cloud, which, apart from the whole data problematic, might not be reachable due to your internet connection being down or some servers in the datacenter being on fire. @@ -49,8 +56,8 @@ Valetudo fully supports: - Room Cleaning, splitting, merging and renaming **new 2021** - Water Pump controls and editing no-mop zones **new 2021** - Editing Virtual Walls, No-Go Areas -- Dynamic zoned cleanup with stored presets -- Go-To locations with stored presets +- Dynamic zoned cleanup +- Go-To locations - Start/Stop/Home/Locate and Fan speed control - Consumables monitoring - Carpet mode and persistent data control @@ -112,13 +119,10 @@ You don't need to be a developer to contribute to Valetudo, because the best way Just stick around in the Telegram Group, the IRC and/or the Github Discussions :) -Furthermore, there's always stuff to improve in the docs, which is another great way to contribute to Valetudo without writing a single line of code. - ### As a developer If you're a developer, the usual stuff applies. They may be Issues tagged with "Good First Issue" which should be the right place to start. -If not, you can also search for "TODO" in the codebase. Maybe you'll find something If you intend to open a PR, please make sure to make yourself familiar with the [PR Template](https://raw.githubusercontent.com/Hypfer/Valetudo/master/.github/PULL_REQUEST_TEMPLATE.md). diff --git a/docs/_pages/general/newcomer_guide_late_2021.md b/docs/_pages/general/newcomer_guide_late_2021.md index 28870bb2..ba09d508 100644 --- a/docs/_pages/general/newcomer_guide_late_2021.md +++ b/docs/_pages/general/newcomer_guide_late_2021.md @@ -17,7 +17,7 @@ This should hopefully answer all the questions you might have and also be intere Valetudo is a cloud replacement for vacuum robots enabling local-only operation. It is not a custom firmware. That means that it cannot change anything about how the robot operates. -What it can do however is protect your data and enable you to connect your robot +What it can do however is protecting your data and enable you to connect your robot to your home automation system without having to detour through a vendor cloud, which, apart from the whole data problematic, might not be reachable due to your internet connection being down or some servers in the datacenter being on fire. @@ -76,8 +76,8 @@ Valetudo fully supports: - Room Cleaning, splitting, merging and renaming - Water Pump controls and editing no-mop zones - Editing Virtual Walls, No-Go Areas -- Dynamic zoned cleanup with stored presets -- Go-To locations with stored presets +- Dynamic zoned cleanup +- Go-To locations - Start/Stop/Home/Locate and Fan speed control - Consumables monitoring - Carpet mode and persistent data control @@ -141,13 +141,10 @@ You don't need to be a developer to contribute to Valetudo, because the best way Just stick around in the Telegram Group, the IRC and/or the Github Discussions :) -Furthermore, there's always stuff to improve in the docs, which is another great way to contribute to Valetudo without writing a single line of code. - ### As a developer If you're a developer, the usual stuff applies. They may be Issues tagged with "Good First Issue" which should be the right place to start. -If not, you can also search for "TODO" in the codebase. Maybe you'll find something If you intend to open a PR, please make sure to make yourself familiar with the [PR Template](https://raw.githubusercontent.com/Hypfer/Valetudo/master/.github/PULL_REQUEST_TEMPLATE.md). diff --git a/docs/_pages/general/rooting-instructions.md b/docs/_pages/general/rooting-instructions.md index 538dafed..4f8c681a 100644 --- a/docs/_pages/general/rooting-instructions.md +++ b/docs/_pages/general/rooting-instructions.md @@ -1,11 +1,46 @@ --- title: Rooting instructions category: General -order: 10 +order: 11 --- # Rooting instructions -This page contains an incomplete overview of installation instructions for various robots +This page contains an incomplete overview of installation instructions for various robots. + +## Requirements + +### Skills + +Rooting robots is an advanced topic the same way working on a car, your electrical installation or any complex machinery is. +All these things require prior knowledge before attempting to do them or else they may fail catastrophically killing you and/or other people in the process. + +While messing up the robot root procedure likely won't harm you, it may still cause a **permanently bricked robot** or +at least annoy the people supporting other Valetudo users in their free time. + +Thus, to safely root your robot and install Valetudo, you will need prior knowledge in: +- GNU+Linux-based operating systems +- usage of a text-based shell (the Terminal) +- an understanding of how networks work, what an IP address is, what a webserver is, etc. +- and more. + +If you don't know these and don't want to research them yourself, consider asking a friend, relative, colleague or your +nearest computer repair shop for help as teaching these basics is beyond the scope of the Valetudo docs. + +It's also not feasible, since different people might start with different knowledge and therefore would require different information. +We can't mirror half of Wikipedia here. + + +### Software + +This guide expects you to run some **GNU+Linux distribution** such as Debian, Fedora, Arch, Ubuntu or similar. +You don't have to install it. Booting from a live USB/DVD will be sufficient. + +If you're running **Windows**, usage of the Windows Subsystem for Linux (WSL) is also often possible. If you haven't heard of that yet, +I'd strongly suggest researching it. It's basically the best of both worlds. + +**MacOS** is not supported and will cause all sorts of trouble during some rooting procedures due to e.g., the `md5sum` command +behaving differently from the one that you'd find in most linux distributions. + ## Dreame @@ -15,8 +50,11 @@ Dreame rooting is currently possible for * Dreame Z10 Pro * Dreame F9 * Dreame D9 +* Dreame D9 Pro * Xiaomi Vacuum Robot 1C * Xiaomi Vacuum Robot 1T +* Mova Z500 +* Dreame P2148 Xiaomi Mijia Ultra Slim It has been released with Dennis Giese's DEF CON 29 Talk [Robots with lasers and cameras but no security Liberating your vacuum](https://youtu.be/EWqFxQpRbv8?t=1525). For more information, head over to the [Dustbuilder](https://builder.dontvacuum.me/). @@ -32,7 +70,13 @@ What we're doing is basically just injecting a custom OTA update including hooks To do this, you'll only need a 3.3V USB to TTL Serial UART Adapter (like CP2102 or Pl2303) and dupont cables. Basic linux knowledge and a pry tool will help as well. -**Note: If this doesn't work on your robot, and it is an 1C, D9, F9 or Z500, your firmware might be too old. In that case, try [this guide](https://gist.github.com/stek29/5c44244ae190f3757a785f432536c22a).** + ![How to open a Dreame](./img/how_to_open_a_dreame.jpg) @@ -65,88 +109,96 @@ To calculate the password use the full serial number of your robot, which can be ![Dreame Dustbin Sticker](./img/dreame_dustbin_sticker.jpg) -To get the password, use the following [Calculator](https://gchq.github.io/CyberChef/#recipe=Find_/_Replace(%7B'option':'Regex','string':'(%5C%5Cn%7C%5C%5Cr)'%7D,'',true,false,true,false)MD5()Find_/_Replace(%7B'option':'Regex','string':'$'%7D,'%20%20-%5C%5Cn',false,false,false,false)To_Base64('A-Za-z0-9%2B/%3D')&input=UDIwMDkwMDAwRVUwMDAwMFpN) or enter the full SN (all uppercase) into this command on Linux -`echo -n "P20290000US00000ZM" | md5sum | base64` or the following commands on Mac -```` -echo -n "P20290000US00000ZM" | md5 -echo -n -e "MD5HASHONLY" -\n" | base64 -```` +To get the password, use the following [Calculator](https://gchq.github.io/CyberChef/#recipe=Find_/_Replace(%7B'option':'Regex','string':'(%5C%5Cn%7C%5C%5Cr)'%7D,'',true,false,true,false)MD5()Find_/_Replace(%7B'option':'Regex','string':'$'%7D,'%20%20-%5C%5Cn',false,false,false,false)To_Base64('A-Za-z0-9%2B/%3D')&input=UDIwMDkwMDAwRVUwMDAwMFpN) +or enter the full SN (all uppercase) into this shell command +`echo -n "P20290000US00000ZM" | md5sum | base64` Once logged in, build a patched firmware image for manual installation via the [Dustbuilder](https://builder.dontvacuum.me). -You’ll need to put in your email, serial number and SSH key if you have one. Make sure you settings match these +**Make sure that both `Prepackage valetudo` and `Patch DNS` are selected before clicking on `Create Job`.** +You will receive an email once it's built. Download the `tar.gz` file from the link in that mail to your laptop. -✅Patch DNS (requirement for valetudo deployment, disables real cloud!!) +With the `tar.gz` downloaded, head over to https://github.com/Hypfer/valetudo-helper-httpbridge +and download a matching binary for your laptops operating system. -✅Prepackage valetudo (only valid for manual install fw) +Now, connect the laptop to the Wi-Fi Access Point of the robot. If you can't see the robots Wi-Fi AP to connect to, it might have disabled itself because 30 minutes passed since the last boot. +In that case, press and hold the two outer buttons until it starts talking to you. -✅Preinstall Nano texteditor, curl, wget, htop, hexdump +The next step is to start the utility webserver. On Windows, a simple double-click on the exe should do the trick. **Don't close that window until you're done.** +The server will create a new `www` directory right next to itself as well as print out a few sample commands explaining how to download from and upload to it. -✅Build for manual installation (requires SSH to install) +Make sure that it is listening on an IP in the range of `192.168.5.0/24` and then copy the downloaded `tar.gz` to the newly created `www` folder. -Then accept at the bottom and `Create Job`. This will send your build to your email once it’s built. Download the `tar.gz` file to your laptop. +
+ -While you are waiting for that email, now is a good time to backup you calibration and identity data before rooting (**as you promised to do in Dustbuilder** ). -Copy and paste the output of the following commands in CLI into a text file somewhere besides your robot: -```` -grep "" /mnt/private/ULI/factory/* -grep "" /mnt/misc/*.json -grep "" /mnt/misc/*.yaml -cat /mnt/misc/*.txt -hexdump /mnt/misc/*.bin -```` +The easiest way of doing this is by creating a tar archive of everything important and then uploading it to your laptop, +which at this point should be connected to the robots Wi-Fi AP. -To get the new build file over to the robot, you'll need to spin up a temporary webserver (e.g. by using `python3 -m http.server`) in the directory where you downloaded your firmware image to, -connect the laptop to the robots WiFi access point and download the firmware image to the robot via e.g. `wget http:///dreame.vacuum.pxxxx_fw.tar.gz`. +To do that, head back to the UART shell and create a tar file of all the required files like so: -Note: If you can't see the robots Wi-Fi AP to connect to, it might have disabled itself because 30 minutes passed since the last boot. -In that case, press and hold the two outer buttons until it starts talking to you. +``` +tar cvf /tmp/backup.tar /mnt/private/ /mnt/misc/ /etc/OTA_Key_pub.pem /etc/publickey.pem +``` -After the successful download, make sure that the robot is docked, untar (`tar -xvzf dreame.vacuum.pxxxx_fw.tar.gz`) it and execute the `./install.sh` script. -The robot will then reboot on its own and greet you with a shell mentioning the Dustbuilder in the MOTD on successful root. +Then, look at the output of the `valetudo-helper-httpbridge` instance you've started previously. +It contains an example curl command usable for uploading that should look similar to this one: -Switch to the tmp folder `cd /tmp` and repeat the previous steps (from wget to install.sh) to also install the firmware on the second partition which you are now booted to. +``` +curl -X POST http://192.168.5.101:33671/upload -F 'file=@./file.tar' +``` -```` -cd /tmp -wget http:///dreame.vacuum.pxxxx_fw.tar.gz -tar -xzvf dreame.vacuum.pxxxx_fw.tar.gz -./install.sh -```` +Change the file parameter to `file=@/tmp/backup.tar`, execute the command and verify that the upload to your laptop +was successful. If everything worked out correctly, you should now see a backup.tar with a non-zero size in `www/uploads`. -The robot will reboot automatically after it has installed the update. Make sure that it is docked during this procedure -as otherwise the update might fail. +If you're experiencing issues, make sure that you've specified the correct port. -You now have a rooted Dreame vacuum robot running Valetudo. +
+ +🦆 - *this will be important later* + +After uploading the backup and storing it in a safe place, you can now download the firmware image file that you've +previously put in the `www` directory. `valetudo-helper-httpbridge` will tell you the correct command, which should look +similar to this: -Now, continue with the [getting started guide](https://valetudo.cloud/pages/general/getting-started.html#joining_wifi). +``` +wget http://192.168.5.101:33671/file.tar +``` +The `file.tar` part will of course be different. -**Important note:** +After downloading the firmware image tar to your working directory (`/tmp`), it should be untared: `tar -xvzf dreame.vacuum.pxxxx_fw.tar.gz`. +Now, make sure that the robot is docked and then run the newly extracted installation script: `./install.sh`. -Another way of backing up the calibration and identity data is by creating a tar like so: `cd / ; tar cvf /tmp/backup.tar /mnt/private/ /mnt/misc/`. -Since you need a temporary webserver to download the new firmware anyway, you can use the [python module uploadserver](https://pypi.org/project/uploadserver/) and upload the file backup.tar with curl. +The robot will install the rooted firmware image and then reboot **on its own**. Please be patient. -On your laptop run +After the robot has finished the installation, you should see a new MOTD (message of the day) on your UART shell. +It should look similar to this: -```` -python3 -m pip install --user uploadserver -```` +``` +build with dustbuilder (https://builder.dontvacuum.me) +Fri 04 Feb 2022 10:08:21 PM UTC +1099 +``` -to install the module and start the server with +If you see that MOTD, the rooting procedure was successful. +**However**, you're not done yet! -```` -python3 -m uploadserver -```` +The dreame robots rooted by this guide actually have two rootfs partitions. +It's a similar setup to the A/B System Partitions that enable seamless Android OS updates on recent (~2017 and newer) Android phones. -in the directory where you have downloaded your new firmware. -On the robot use curl to upload the backup.tar: +To ensure that you'll have a rooted system even in the unlikely event of a boot failure of the currently active partition, +you should flash both root partitions with a rooted firmware images. +To do that, simply scroll back up to the duck emoji 🦆 and continue from there a second time. -```` -curl -X POST http://>:8000/upload -F 'files=@/tmp/backup.tar' -```` -If successful you will find the backup.tar on your laptop in the directory where you started the webserver. +All done? Good. +You now have a rooted Dreame vacuum robot running Valetudo. -You can also create the tar after rooting and use `scp root@:/tmp/backup.tar .` to copy it to a safe location that isn't the robot. +Now continue with the [getting started guide](https://valetudo.cloud/pages/general/getting-started.html#joining_wifi). ## Roborock @@ -214,20 +266,3 @@ This method applies to the following robots: * Roborock S5 Max * Roborock S6 Pure * Roborock S4 Max - -## Viomi - -3irobotix is the manufacturer of vacuum robots sold under various brand names including -- Viomi -- Cecotec -- Prosenic -- Kyvol -- Neabot - -For now, only one vacuum robot is supported (WIP): -* Mijia STYJ02YM **viomi.vacuum.v7** - -To install Valetudo on your Viomi V7, follow the instructions found [here](https://valetudo.cloud/pages/installation/viomi.html). - -We're currently looking into the possibility of reflashing other brands to Viomi so that they work with Valetudo without -any additional code. diff --git a/docs/_pages/general/supported-robots.md b/docs/_pages/general/supported-robots.md index 5bef7add..08affcad 100644 --- a/docs/_pages/general/supported-robots.md +++ b/docs/_pages/general/supported-robots.md @@ -1,7 +1,7 @@ --- title: Supported Robots category: General -order: 8 +order: 9 --- # Supported Robots @@ -208,6 +208,7 @@ vSLAM and a small battery, though there are persistent maps and everything seems - [MapSegmentEditCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentEditCapability) - [MapSegmentRenameCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentRenameCapability) - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) + - [PendingMapChangeHandlingCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PendingMapChangeHandlingCapability) - [PersistentMapControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PersistentMapControlCapability) - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) - [SpeakerVolumeControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerVolumeControlCapability) @@ -252,7 +253,8 @@ aarch64 #### Comment -vSLAM :( +vSLAM + ToF offers a huge upgrade over only vSLAM, however it is still inferior to Lidar-based mapping. +On initial root, it might be required to do a factory reset so that the device.conf gets regenerated. @@ -270,7 +272,6 @@ vSLAM :( - [MapSegmentEditCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentEditCapability) - [MapSegmentRenameCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentRenameCapability) - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) - - [MappingPassCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MappingPassCapability) - [PendingMapChangeHandlingCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PendingMapChangeHandlingCapability) - [PersistentMapControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PersistentMapControlCapability) - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) @@ -401,6 +402,7 @@ armv7-lowmem - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) - [MappingPassCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MappingPassCapability) - [PendingMapChangeHandlingCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PendingMapChangeHandlingCapability) + - [QuirksCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#QuirksCapability) - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) - [SpeakerVolumeControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerVolumeControlCapability) - [TotalStatisticsCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#TotalStatisticsCapability) @@ -462,7 +464,6 @@ vSLAM :( - [MapSegmentEditCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentEditCapability) - [MapSegmentRenameCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentRenameCapability) - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) - - [MappingPassCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MappingPassCapability) - [PendingMapChangeHandlingCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PendingMapChangeHandlingCapability) - [PersistentMapControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PersistentMapControlCapability) - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) @@ -591,7 +592,77 @@ vSLAM :( - [MapSegmentEditCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentEditCapability) - [MapSegmentRenameCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentRenameCapability) - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) - - [MappingPassCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MappingPassCapability) + - [PendingMapChangeHandlingCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PendingMapChangeHandlingCapability) + - [PersistentMapControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PersistentMapControlCapability) + - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) + - [SpeakerVolumeControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerVolumeControlCapability) + - [TotalStatisticsCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#TotalStatisticsCapability) + - [VoicePackManagementCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#VoicePackManagementCapability) + - [WaterUsageControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#WaterUsageControlCapability) + - [WifiConfigurationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#WifiConfigurationCapability) + - [ZoneCleaningCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ZoneCleaningCapability) + + +### P2148 + +#### Valetudo Support + +good + + + +#### Developer Support + +yes + + + +#### Tested Working + +✔ + + + +#### Recommended + +This model is okay but has some issues that keep it from being fully recommendable + + + +#### Recommended Valetudo binary to use + +aarch64 + + + +#### Comment + +With its 5.5cm height and 32.3cm diameter, this robot offers a solution for some tricky homes. +As it is china exclusive, spare parts may be hard to find in the rest of the world. + +On initial root, it might be required to do a factory reset so that the device.conf gets regenerated. + +There is no reset button on this robot. Instead, press and hold the two buttons for +- <1s for the UART shell spawn +- >3s for Wi-Fi reset +- >5s for full factory reset + + + +#### This model supports the following capabilities: + - [BasicControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#BasicControlCapability) + - [CarpetModeControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#CarpetModeControlCapability) + - [CombinedVirtualRestrictionsCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#CombinedVirtualRestrictionsCapability) + - [ConsumableMonitoringCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ConsumableMonitoringCapability) + - [CurrentStatisticsCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#CurrentStatisticsCapability) + - [DoNotDisturbCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#DoNotDisturbCapability) + - [FanSpeedControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#FanSpeedControlCapability) + - [LocateCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#LocateCapability) + - [ManualControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ManualControlCapability) + - [MapResetCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapResetCapability) + - [MapSegmentEditCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentEditCapability) + - [MapSegmentRenameCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentRenameCapability) + - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) - [PendingMapChangeHandlingCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PendingMapChangeHandlingCapability) - [PersistentMapControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PersistentMapControlCapability) - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) @@ -1115,72 +1186,10 @@ Unfortunately, this model is lacking basic features such as a persistent map whi - [ZoneCleaningCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ZoneCleaningCapability) -## Viomi - -### V7 - -#### Valetudo Support - -meh - - - -#### Developer Support - -none - - - -#### Tested Working - -✔ - - - -#### Recommended - -This model has issues and therefore isn't recommended (see comment) - - - -#### Recommended Valetudo binary to use - -armv7 - - - -#### Comment - -This model is actually just a White-Label Product with a custom Miio Software stack which is EOL and therefore doesn't receive any meaningful software updates. - -Overall, it's just weird and annoying. - - - -#### This model supports the following capabilities: - - [BasicControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#BasicControlCapability) - - [CarpetModeControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#CarpetModeControlCapability) - - [CombinedVirtualRestrictionsCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#CombinedVirtualRestrictionsCapability) - - [ConsumableMonitoringCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ConsumableMonitoringCapability) - - [CurrentStatisticsCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#CurrentStatisticsCapability) - - [DoNotDisturbCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#DoNotDisturbCapability) - - [FanSpeedControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#FanSpeedControlCapability) - - [LocateCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#LocateCapability) - - [ManualControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ManualControlCapability) - - [MapResetCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapResetCapability) - - [MapSegmentEditCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentEditCapability) - - [MapSegmentRenameCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentRenameCapability) - - [MapSegmentationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#MapSegmentationCapability) - - [PersistentMapControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#PersistentMapControlCapability) - - [QuirksCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#QuirksCapability) - - [SpeakerTestCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerTestCapability) - - [SpeakerVolumeControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#SpeakerVolumeControlCapability) - - [VoicePackManagementCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#VoicePackManagementCapability) - - [WaterUsageControlCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#WaterUsageControlCapability) - - [WifiConfigurationCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#WifiConfigurationCapability) - - [ZoneCleaningCapability](https://valetudo.cloud/pages/general/capabilities-overview.html#ZoneCleaningCapability) - -




This page has been autogenerated.
+<<<<<<< HEAD +Autogeneration timestamp: 2022-09-04T06:35:31.431Z +======= Autogeneration timestamp: 2022-01-28T11:13:37.930Z +>>>>>>> master diff --git a/docs/_pages/general/upgrading.md b/docs/_pages/general/upgrading.md index e9930a92..b4643c9f 100644 --- a/docs/_pages/general/upgrading.md +++ b/docs/_pages/general/upgrading.md @@ -15,7 +15,7 @@ Below are manual upgrading instructions for older versions: If you're using an S5 or V1, the recommended way to upgrade Valetudo is to flash a new image. This requires you to have SSH access to the robot. -1. Select the `Build for manual installation (requires SSH to install)` option in [dustbuilder](https://builder.dontvacuum.me/). You will then receive a link to a tar.gz archive by email. +1. Select the `Build for manual installation (requires SSH to install)` option in the [Dustbuilder](https://builder.dontvacuum.me/). You will then receive a link to a tar.gz archive by email. 2. Login to your robot via SSH. 3. Download the tar.gz file to the `/mnt/data` folder and extract it: ```sh @@ -30,6 +30,7 @@ reboot ``` 5. Reconnect to your robot via SSH. You'll now be in system B, allowing you to update system A. Update system A (from system B) then reboot back into system A for normal operation: ```sh +cd /mnt/data ./install_a.sh rm -f reboot @@ -45,28 +46,13 @@ Just make sure that you try a full reflash **if you encounter any issues such as If you don't have ssh available, you will need to do a full factory reset to re-enable OTA updates on supported robots, and then follow the initial installation procedure. -## Upgrading Viomi vacuums - -1. SSH into the vacuum and kill valetudo: `killall valetudo` -2. Replace the old Valetudo binary in `/mnt/UDISK/valetudo` with the new one - - If you get a "Text file busy" error, it means Valetudo is still running. Try to kill it again. - - If the issue still occurs, delete the old binary before uploading the new one -3. If your init script (`/etc/init.d/valetudo`) is outdated or different than the one in this repository - ([`deployment/viomi/etc/init.d/valetudo`](https://github.com/Hypfer/Valetudo/blob/master/deployment/viomi/etc/init.d/valetudo)), - you need to update it as well - 1. Run `/etc/init.d/valetudo disable` - 2. Ensure that no files with "valetudo" in the name are still present under `/etc/rc.d`. If there are any, delete - them. - 2. Upload the new init script to `/etc/init.d/valetudo` - 3. Run `/etc/init.d/valetudo enable` -4. Reboot your vacuum: `reboot` ## Upgrading Dreame vacuums 1. SSH into the vacuum and kill valetudo: `killall valetudo` 2. Replace the old Valetudo binary in `/data/valetudo` with the new one - `wget https://github.com/Hypfer/Valetudo/releases/latest/download/valetudo-{armv7,armv7-lowmem,aarch64} -O /data/valetudo` - - Make sure to use the correct binary as documented in the [supported robots](valetudo.cloud/pages/general/supported-robots.html) section + - Make sure to use the correct binary as documented in the [supported robots](https://valetudo.cloud/pages/general/supported-robots.html) section - If you get a "Text file busy" error, it means Valetudo is still running. Try to kill it again. - If the issue still occurs, delete the old binary before uploading the new one 3. Reboot your vacuum: `reboot` diff --git a/docs/_pages/general/why-not-valetudo.md b/docs/_pages/general/why-not-valetudo.md new file mode 100644 index 00000000..8c28f373 --- /dev/null +++ b/docs/_pages/general/why-not-valetudo.md @@ -0,0 +1,137 @@ +--- +title: Why not Valetudo? +category: General +order: 7 +--- + +# Why not Valetudo? + +After having read through the [Why Valetudo?](https://valetudo.cloud/pages/general/why-valetudo.html) page, +you might also be wondering why you might **not** want to use Valetudo. +To answer those questions, here's a list of a few common reasons in an attempt to reduce the amount of some incredibly exhausting discussions. + + +## No multi-floor/multi-map support + +Due to technical limitations, Valetudo does not support multiple maps. +If you need multiple maps, Valetudo likely won't be an option for you. + +The topic has been evaluated many times already, however unfortunately it's not technically feasible with the currently +supported robot models and firmwares. (2022-07-17) + +If you need multiple floors vacuumed and want to use Valetudo, you may want to invest in a second robot. +With the current (2022-07-17) market (in Germany), 200€ should be more than enough to buy a factory new supported one even featuring LIDAR. + +Investing in a second robot also improves the usefulness of the unit, as having to manually carry the robot to another +floor very much degrades the benefits of a fully automated vacuum robot. + +If investing in a second robot is not possible in your situation, you'll likely be very unhappy with Valetudo. + +## You may not be the target audience + +While Valetudo may be used by anyone, five years of user interactions have shown that it works better for some demographics than others. + +One such demographic that seems to often run into trouble when using Valetudo is apple users. (I know, right?) +Specifically, those fully invested into the Apple Ecosystem and way of life. + +It should be clearly stated that of course there is no active effort to lock out people using apple products going on. +However, it seems that the "think different"-way of interaction with and understanding of the world is simply incompatible +with how Valetudo is built, supported and maintained. Thus, if you're a member of that group, you'll likely be very unhappy with Valetudo. + + +Another demographic that seems to struggle hard with usage of Valetudo are people suffering from an exceptionally short +attention span. As rooting a vacuum robot is an advanced topic, it will always require careful and mindful reading of +information available to get an understanding of how things work and need to be done. + +If you're a person that prefers jump-cutted videotutorials featuring little understanding and lots of no-thinking-required +copy-paste commands, you'll likely be very unhappy with Valetudo. + + +In conclusion, it should be noted that, being a passion project, there is no incentive for Valetudo to cater to +the needs of demographics that are usually only catered to to make money. If Valetudo was aimed at those demographics, +there would be ads, data collection, licensing fees and many more undesirable things built in. + + +## Only supported robots are supported + +While this may sound incredibly dumb, it unfortunately needs saying nonetheless. + +Only supported robots are supported. +Unsupported robots are not supported. + +If you have an unsupported robot, it is not supported. +There is no support for it because it is not supported. + +While there might be code in Valetudo that enables operation of a specific robot, it doesn't mean that it is also supported. +Support can only be provided for supported robots. + +To receive support, you will need a supported robot. +It is impossible to support an unsupported robot as - due to it being not supported - there simply is no knowledge available +that could be utilized to provide support. + +It is possible to use Valetudo on unsupported robots or in unsupported ways. +Just note that there will be no support for these unsupported scenarios. + + +## Valetudo is only available in english + +Valetudo does not feature any localization. Let me explain the reasoning behind this with a few examples. + +First, consider this car radio in a car made for the german market: + +![Bosch Car Radio](./img/car_radio.jpg) + +In fact, the radio is engineered by Bosch in Hildesheim. Still, the button isn't labeled `Karte`. + +Now, let's take a look at the Valetudo UI (Version 0.6.1): + +![Valetudo 0.6.1 UI](./img/valetudo-ui.png) + +Regarding overall complexity, it's comparable to the buttons on the radio. +It's even easier to understand, because there are a lot more icons.
+Considering that people do in fact manage to use their car radios even if their english skills may be lacking, +I'd say that **accessibility** isn't a problem here. + + +As a matter of fact, Internationalization isn't free. It always introduces more work, more complexity etc.
+Of course **accessibility** is often worth the effort, however since we've already established that this factor isn't relevant here, +we can take a look at a non-exhaustive list of downsides of i18n: + +* Getting support is harder when screenshots/error messages are in a language that isn't english, because supporters may not speak it +* Development of new features, refactoring etc. is always blocked by having to translate everything new to all languages +* Increased codebase complexity + * Harder to read + * Harder to work with +* Lots of initial work to translate everything + * Time/effort that could be spent better elsewhere + +Now, let us look at another real-world example of i18n. + +![Apple Shortcuts Example](./img/apple_shortcuts_example.png) + +This is a screenshot of Apple Shortcuts running on an iPhone set to the German locale. +It is just a basic HTTP PUT with a JSON payload. +For some reason however, "Header" as in "HTTP Header" was translated to "Überschrift" which means "Headline". +Even worse, "Request body" became "Haupttext anfordern" which translated back to english means "(to) request the main text"??? + +![Visual Studio 2017 Example](./img/visual_studio_2017_example.png) + +This is another example. Here we have the Integrated Development Environment Visual Studio 2017 made by Microsoft +attempting to open a project file that was created in an older version of Visual Studio. + +Instead of asking us if we want to change the target SDK of the project file - which is called solution in Visual Studio - +it is showing us a dialog titled "Lösungsaktionen prüfen" which translates back to "check actions to solve something". +Then there's a sub-header labelled "Projekte neu ausrichten" which translates to "realign projects" (plural). + +The only way I was able to decipher what that dialog even means was by opening the same project on a different system +with the locale being set to en-US. + + +In both examples, the actual meaning got lost in translation, which is a common issue. +Even with german being a common language and understanding of the HTTP protocol being fairly common as well. + +Preventing this is hard, because you will need someone who understands the project from a technical standpoint as well as speaks the language it should be translated to. +This is also required even if the translation is done by someone else, because you still have to validate what they did. + +As even huge corporations known for being user-friendly and also paired with insane budgets fail to do this all the time, +I don't think that it is actually a feasible task. diff --git a/docs/_pages/general/why-valetudo.md b/docs/_pages/general/why-valetudo.md index 659238bb..ef889e93 100644 --- a/docs/_pages/general/why-valetudo.md +++ b/docs/_pages/general/why-valetudo.md @@ -15,8 +15,6 @@ Using Valetudo only makes sense if you understand its goals and feel like they a It is perfectly fine to continue using the cloud if you don't really care about its downsides. Do not flame people for doing that. You can be a bit snarky about downtimes, lag and other cloud shenanigans though :) -Now, allow me to get preachy. - ## Goals ### Vendor-agnostic abstraction diff --git a/docs/_pages/img/valetudo_logo_small.svg b/docs/_pages/img/valetudo_logo_small.svg new file mode 100644 index 00000000..7785a040 --- /dev/null +++ b/docs/_pages/img/valetudo_logo_small.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/_pages/img/valetudo_logo_with_name.svg b/docs/_pages/img/valetudo_logo_with_name.svg new file mode 100644 index 00000000..cc33e08a --- /dev/null +++ b/docs/_pages/img/valetudo_logo_with_name.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/docs/_pages/important-files-and-folders.md b/docs/_pages/important-files-and-folders.md index d2482a60..563f6109 100644 --- a/docs/_pages/important-files-and-folders.md +++ b/docs/_pages/important-files-and-folders.md @@ -1,7 +1,7 @@ --- title: Roborock, Files to backup category: Misc -order: 32 +order: 33 --- ## Important Roborock Stuff @@ -15,7 +15,7 @@ These is a list of important files on the robot. I am mainly writing this down h Zones + Spots configuration, mqtt + other config -`/mnt/data/valetudo/config.json` +`/mnt/data/valetudo/valetudo_config.json` Status to keep map diff --git a/docs/_pages/installation/roborock-ota.md b/docs/_pages/installation/roborock-ota.md index 817a852a..53b65af2 100644 --- a/docs/_pages/installation/roborock-ota.md +++ b/docs/_pages/installation/roborock-ota.md @@ -31,87 +31,56 @@ Sadly though, this process has to be done by each user individually because host It is recommended to use the Dustbuilder to build your firmware image. It can be found here: [https://builder.dontvacuum.me/](https://builder.dontvacuum.me/) -The service is provided by Dennis who is also the reason, why Valetudo can exist in the first place. +In DustBuilder, make sure to use the "Build update package" option, as it is the only file type supported by valetudo-helper-miioota. -If you however don't trust us that's perfectly fine. You can use [https://github.com/zvldz/vacuum](https://github.com/zvldz/vacuum) to build the image yourself.
+The service is provided by Dennis who is also the reason, why Valetudo can exist in the first place. -The reason this guide switched to dustbuilder only is that it provides a controlled environment, which eliminates common support issues. +The reason this guide switched to Dustbuilder only is that it provides a controlled environment, which eliminates common support issues. The irony that this guide suggests using "the cloud" to uncloud your device is not lost on me. ## Flashing the firmware image -To flash the image we are going to use [python-miio](https://github.com/rytilahti/python-miio), which provides `mirobo` - a tool to control a vacuum cleaner from a terminal. - -First, we need to get it and for this we recommend to create a python virtual environment for it. -
- Dependencies (Click me) -
    -
  • python3
  • -
  • python3-pip
  • -
  • python3-venv
  • -
-
+Flashing the firmware .pkg file can easily be done by using [valetudo-helper-miioota](https://github.com/Hypfer/valetudo-helper-miioota), +which is a standalone tool that does the right thing. +Just connect your laptop to the robots Wi-Fi access point and use the tool to install the firmware. +A successful run should look similar to this: ``` -cd .. -mkdir flasher -cd flasher -python3 -m venv venv +./valetudo-helper-miioota install-firmware v11_2034.pkg +Starting installer. +If you experience issues, make sure to disable your firewall and/or VPN. +Also, make sure that the robot is docked during the firmware update procedure. +If the install still fails, try turning the robot off and back on again and/or moving the laptop closer to it. + +Robot discovery started... +Scan done. +Successfully discovered robot at 192.168.8.1 +Reading firmware image.. +Successfully read firmware image. Size: 78.62 MiB MD5Sum: fe820a713ec9efdfa3990b5d776e2cda + +Listing for firmware download requests on http://192.168.8.10:34505/firmware +Response from robot: [ 'ok' ] +Received firmware download request from ::ffff:192.168.8.1.. + +Download seems to have finished. +The robot should now install the firmware. It will take 5-10 minutes. +Exiting.. ``` -Now, when the virtual environment is ready we are going to activate it and install [miio](https://github.com/rytilahti/python-miio) python package which provides `mirobo`: - -``` -source venv/bin/activate -pip3 install wheel -pip3 install python-miio -cd .. -``` +Please keep the distance between your WiFi antenna and your robot as short as possible or the connection might get lost. -Flashing an image requires providing your robot's token. -To acquire it, connect to your robot's WiFi Access Point and run the following command: -`mirobo --debug discover --handshake true` +After the successful transfer of the image to the robot, the robot will start flashing the image. This will take about 5~10 minutes. +After the process is done, the robot will state that the update was successful. -You're looking for a similar line: -``` -INFO:miio.miioprotocol: IP 192.168.8.1 (ID: 0f90319a) - token: b'ffffffffffffffffffffffffffffffff' -``` +You can now return to the [getting started guide](https://valetudo.cloud/pages/general/getting-started.html#joining_wifi). -If your robot doesn't show up check if you have multiple connected network interfaces. Either disable all other (those not connected to your robot's WiFi) or use a VM which you explicitly connect to your host's WiFi interface. Another possibility is an internal firewall blocking it. On RedHat-based Linux systems using Firewalld (CentOS, Fedora, etc.), make sure the firewall zone for your connection to the robot's WiFi Access Point is set to "trusted" instead of "public". +### Troubleshooting -With token in out hand we can upload the firmware to the robot: -``` -mirobo --token XXXXXXXXXXXXXXXX --ip ROBOT_IP_ADDRESS update-firmware path/to/built/image.pkg -``` - -`ROBOT_IP_ADDRESS` is `192.168.8.1` by default but if you're upgrading Valetudo to a new version, you need to replace it with the robot's current IP address. -Also please keep the distance between your WiFi antenna and your robot as short as possible or the connection might get lost. - -After the successful transfer of the image to the robot, the robot will start flashing the image. This will take about 5~10 minutes. After the process is done, the robot will state that the update was successful. -You should then reboot the Robot either via ssh command `ssh root@192.168.8.1` and typing `reboot` or simply by taking it out of dock and push the ON switch to prevent valetudo stuck on LOADING STATE??? - -### Firmware Installation fails -#### ... before the download bar appears: - - * Warnings about lack of IP or Token - Check [miio's usage](https://python-miio.readthedocs.io/en/latest/discovery.html) * Firewall active? - Disable your personal firewall. - * Using a VM to flash the image? - Try to flash the image from your Host (just copy the firmware image) - * Token wrong? - Did you initiate a WiFi reset on the robot? Then you have to refetch the token, see above. + * Using a VM to flash the image? - Try to flash the image from your Host * Your PC does not know how to route, is more than one network interfaces active? Maybe disable LAN? - * Wrong IP address on your WiFi? - Check that DHCP is active on your WiFi device. - -#### ... after the download bar appeared: - * Did you make an update of the robot firmware via the Xiaomi App? Then go back to original using factory reset: while holding the plug button shortly press the reset button. * Distance between WiFi devices is to big. Try putting the robo near your PC. * Battery is lower than 20%. Please Charge. Place the Vacuum in the dock. - -## Connect your robot to your Wifi - -To connect the robot to your home Wifi, just connect to http://192.168.8.1 and use Valetudos settings dialog to enter your wifi credentials. Please note that only *WPA2-PSK* is supported. -After updating the Wifi settings, you should reboot your robot. - -## Open Valetudo -You need to get the IP of your robot (e.g. from your router) and connect to it using your browser e.g. http://192.168.Y.Z diff --git a/docs/_pages/installation/viomi.md b/docs/_pages/installation/viomi.md deleted file mode 100644 index c67f4ded..00000000 --- a/docs/_pages/installation/viomi.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Viomi -category: Installation -order: 11 ---- -# Viomi - -These pages guide you through the installation steps for viomi robots. -Support is still somewhat experimental, [see below](#current-state-of-viomi-support) for details. - -The default settings here will be for running Valetudo on the robot itself. -If you want to develop as well, check out the [Local Development section](#local-development-setup). - -There’s a [tool to automate rooting and Valetudo installation](https://github.com/rumpeltux/viomi-rooting/). - -Please give it a try and [file any issues that you encounter there](https://github.com/rumpeltux/viomi-rooting/issues). - -## Robot setup - -First, you need to [get root access to your Robot](https://github.com/rumpeltux/viomi-rooting/). - -If you decide to install Valetudo manually, you’ll need to set up the robot to talk to your host -instead of the xiaomi cloud: - -```shell -ssh root@vacuum -sed -i 's/110.43.0.8./127.00.00.1/g' /usr/bin/miio_client -for domain in "" de. ea. in. pv. ru. sg. st. tw. us.; do - echo "127.0.0.1 ${domain}ot.io.mi.com ${domain}ott.io.mi.com" >> /etc/hosts -done -reboot -``` - -## Deploying - -Run - - npm run build_armv7 - -And deploy the `valetudo` binary to your robot: - - scp valetudo root@vacuum:/mnt/UDISK/ - - # Setup init scripts (only needed once and only if not already done by rooting script) - (cd deployment/viomi; tar cv . | ssh root@vacuum "cd /; tar x") - -## Local Development Setup - -Follow the [development guide](https://valetudo.cloud/pages/development/building-and-modifying-valetudo.html). - -## Firmware updates - -You can perform firmware updates up to v3.5.3_0047 without risking root (see the -[firmware update analysis](https://itooktheredpill.irgendwo.org/2020/viomi-firmware-update-analysis/) -for details). - -**Important:** Make sure you use ssh-keys and don't rely on password login -otherwise your root access may be lost. - -To perform a firmware upgrade you currently need to: - -* [uninstall Valetudo](#uninstall-valetudo) (because the diskspace is needed for the upgrade) and -* use the Xiaomi Home App to perform the upgrade (because upgrades are - unsupported by Valetudo / only supported via cloud interface and there's - no public source for the binaries in the first place). -* [reinstall Valetudo](#deploying) - -## Uninstall Valetudo - -This will remove Valetudo, free the diskspace and re-enable the cloud interface. - -```shell -ssh root@vacuum -/etc/init.d/valetudo stop -rm /etc/init.d/valetudo /mnt/UDISK/valetudo -rm /overlay/usr/bin/miio_client -``` - -## Enable logging - -Add the following to the `system` section in `/etc/config/system` (adjust ip and port as necessary): - - option log_ip 192.168.1.10 - option log_port 8054 - option log_proto tcp - -After a reboot you can receive logs using netcat: - - netcat -l4 8054 - -See the [OpenWrt Runtime Logging Guide](https://openwrt.org/docs/guide-user/base-system/log.essentials) -for details. diff --git a/docs/_pages/integrations/mqtt.md b/docs/_pages/integrations/mqtt.md index 1a5d293b..b01d9788 100644 --- a/docs/_pages/integrations/mqtt.md +++ b/docs/_pages/integrations/mqtt.md @@ -63,7 +63,6 @@ Homie autodiscovery info is best viewed with something like [MQTT Explorer](http - [Consumables monitoring (`ConsumableMonitoringCapability`)](#consumablesmonitoringconsumablemonitoringcapability) - [Consumable (minutes) (``)](#consumableminutesconsumable-minutes) - [Consumable (percent) (``)](#consumablepercentconsumable-percent) - - [Refresh consumables (`refresh`)](#refreshconsumablesrefresh) - [Current Statistics (`CurrentStatisticsCapability`)](#currentstatisticscurrentstatisticscapability) - [Current Statistics Area (`area`)](#currentstatisticsareaarea) - [Current Statistics Time (`time`)](#currentstatisticstimetime) @@ -71,8 +70,7 @@ Homie autodiscovery info is best viewed with something like [MQTT Explorer](http - [Fan speed control (`FanSpeedControlCapability`)](#fanspeedcontrolfanspeedcontrolcapability) - [Fan speed (`preset`)](#fanspeedpreset) - [Go to location (`GoToLocationCapability`)](#gotolocationgotolocationcapability) - - [Go to location preset (`go`)](#gotolocationpresetgo) - - [Presets (`presets`)](#presetspresets) + - [Go to location (`go`)](#gotolocationgo) - [Locate (`LocateCapability`)](#locatelocatecapability) - [Locate (`locate`)](#locatelocate) - [Segment cleaning (`MapSegmentationCapability`)](#segmentcleaningmapsegmentationcapability) @@ -86,13 +84,12 @@ Homie autodiscovery info is best viewed with something like [MQTT Explorer](http - [Signal (`signal`)](#signalsignal) - [Wireless network (`ssid`)](#wirelessnetworkssid) - [Zone cleaning (`ZoneCleaningCapability`)](#zonecleaningzonecleaningcapability) - - [Presets (`presets`)](#presetspresets) - - [Start zone preset (`start`)](#startzonepresetstart) + - [Start zoned cleaning (`start`)](#startzonedcleaningstart) - [Map data](#mapdata) - [Map (`map`)](#mapmap) - [Map segments (`segments`)](#mapsegmentssegments) - [Raw map data (`map-data`)](#rawmapdatamap-data) - - [Raw map data with Home Assistant hack (`map-data-hass-hack`)](#rawmapdatawithhomeassistanthackmap-data-hass-hack) + - [Raw map data for Home Assistant (`map-data-hass`)](#rawmapdataforhomeassistantmap-data-hass) - [Status](#status) - [Attachment state (`AttachmentStateAttribute`)](#attachmentstateattachmentstateattribute) - [Dust bin (`dustbin`)](#dustbindustbin) @@ -122,14 +119,15 @@ Homie autodiscovery info is best viewed with something like [MQTT Explorer](http - [Consumable (percent) (`sensor.mqtt`)](#consumablepercentconsumable-percent) - [Current Statistics Area (`sensor.mqtt`)](#currentstatisticsareaarea) - [Current Statistics Time (`sensor.mqtt`)](#currentstatisticstimetime) +- [Dust bin attachment (`binary_sensor.mqtt`)](#dustbindustbin) - [Error description (`sensor.mqtt`)](#errordescriptionerror) -- [GoTo Locations (`sensor.mqtt`)](#gotolocationgotolocationcapability) -- [Map data (`camera.mqtt`)](#rawmapdatawithhomeassistanthackmap-data-hass-hack) +- [Map data (`camera.mqtt`)](#rawmapdataforhomeassistantmap-data-hass) - [Map segments (`sensor.mqtt`)](#mapsegmentssegments) +- [Mop attachment (`binary_sensor.mqtt`)](#mopmop) - [Vacuum (`vacuum.mqtt`)](#robot) - [Water grade (`select.mqtt`)](#watergradepreset) +- [Water tank attachment (`binary_sensor.mqtt`)](#watertankwatertank) - [Wi-Fi configuration (`sensor.mqtt`)](#wi-ficonfigurationwificonfigurationcapability) -- [Zone Presets (`sensor.mqtt`)](#zonecleaningzonecleaningcapability) # MQTT API reference @@ -239,18 +237,6 @@ Home Assistant components controlled by this property: -##### Refresh consumables (`refresh`) - -*Property, command, not retained* - -If set to `PERFORM`, it will attempt to refresh the consumables from the robot. Note that there's no need to do it manually, consumables are refreshed automatically every 30 seconds by default. - -- Command topic: `//ConsumableMonitoringCapability/refresh/set` -- Command response topic: `//ConsumableMonitoringCapability/refresh` -- Data type: [enum](https://homieiot.github.io/specification/#enum) (allowed payloads: `PERFORM`) - - - #### Current Statistics (`CurrentStatisticsCapability`) @@ -351,58 +337,29 @@ max *Node, capability: [GoToLocationCapability](/pages/general/capabilities-overview.html#gotolocationcapability)* -Home Assistant components controlled by this node: - -- GoTo Locations ([`sensor.mqtt`](https://www.home-assistant.io/integrations/sensor.mqtt/)) - -##### Go to location preset (`go`) +##### Go to location (`go`) *Property, command, not retained* -Use this handle to make the robot go to a configured preset location. It accepts one single preset UUID as a regular string. - -- Command topic: `//GoToLocationCapability/go/set` -- Command response topic: `//GoToLocationCapability/go` -- Data type: [string](https://homieiot.github.io/specification/#string) - - - -##### Presets (`presets`) - -*Property, readable, retained* - -This handle provides a set of configured Go-to-location presets as a JSON object. +This handle accepts a JSON object identical to the one used by the REST API. -- Read topic: `//GoToLocationCapability/presets` -- Data type: [string](https://homieiot.github.io/specification/#string) (JSON) +Please refer to the "General Help" section in Valetudo for more information. -Sample value: +Sample payload: ```json { - "a9666386-7041-4bd4-a823-ebefa48665eb": { - "__class": "ValetudoGoToLocation", - "metaData": {}, - "name": "SpotA", - "coordinates": { - "x": 2589, - "y": 2364 - }, - "id": "a9666386-7041-4bd4-a823-ebefa48665eb" - }, - "6c74ac84-dfe9-4c4c-8bec-836ff268d630": { - "__class": "ValetudoGoToLocation", - "metaData": {}, - "name": "SpotB", - "coordinates": { - "x": 2186, - "y": 2262 - }, - "id": "6c74ac84-dfe9-4c4c-8bec-836ff268d630" + "coordinates": { + "x": 50, + "y": 50 } } ``` +- Command topic: `//GoToLocationCapability/go/set` +- Command response topic: `//GoToLocationCapability/go` +- Data type: [string](https://homieiot.github.io/specification/#string) (format: `same json as the REST interface`) + @@ -433,14 +390,16 @@ Sample value: This handle accepts a JSON object identical to the one used by the REST API. +Please refer to the "General Help" section in Valetudo for more information. + Sample payload: ```json { "segment_ids": [ - "20", - "18", - "16" + "20", + "18", + "16" ], "iterations": 2, "customOrder": true @@ -581,40 +540,47 @@ Valetudo Wi-Fi *Node, capability: [ZoneCleaningCapability](/pages/general/capabilities-overview.html#zonecleaningcapability)* -Home Assistant components controlled by this node: - -- Zone Presets ([`sensor.mqtt`](https://www.home-assistant.io/integrations/sensor.mqtt/)) - -##### Presets (`presets`) +##### Start zoned cleaning (`start`) -*Property, readable, retained* +*Property, command, not retained* -This handles provides the list of configured zone presets as a JSON object. +This handle accepts a JSON object identical to the one used by the REST API. -- Read topic: `//ZoneCleaningCapability/presets` -- Data type: [string](https://homieiot.github.io/specification/#string) (JSON) +Please refer to the "General Help" section in Valetudo for more information. -Sample value: +Sample payload: ```json -{} +{ + "zones": [ + { + "iterations": 1, + "points": { + "pA": { + "x": 50, + "y": 50 + }, + "pB": { + "x": 100, + "y": 50 + }, + "pC": { + "x": 100, + "y": 100 + }, + "pD": { + "x": 50, + "y": 100 + } + } + } + ] +} ``` - - -##### Start zone preset (`start`) - -*Property, command, not retained* - -This handle accepts a zone preset **UUID** to start. You can retrieve them from the `/presets` handle. - -Sample value: -`25f6b7fe-0a28-477d-a1af-937ad91b2df4` - - - Command topic: `//ZoneCleaningCapability/start/set` - Command response topic: `//ZoneCleaningCapability/start` -- Data type: [string](https://homieiot.github.io/specification/#string) (JSON) +- Data type: [string](https://homieiot.github.io/specification/#string) (format: `same json as the REST interface`) @@ -648,13 +614,13 @@ ICBINV should be configured so that it publishes the map to this topic. -#### Raw map data with Home Assistant hack (`map-data-hass-hack`) +#### Raw map data for Home Assistant (`map-data-hass`) *Property, readable, retained* -This handle is added automatically if Home Assistant autodiscovery is enabled. It provides a map embedded in a PNG image that recommends installing the Valetudo Lovelace card. +This handle is added automatically if Home Assistant autodiscovery is enabled. It provides a map embedded in a PNG image that recommends installing the Valetudo Lovelace card. -- Read topic: `//MapData/map-data-hass-hack` +- Read topic: `//MapData/map-data-hass` - Data type: [string](https://homieiot.github.io/specification/#string) Home Assistant components controlled by this property: @@ -700,7 +666,7 @@ Status attributes managed by this node: *Property, readable, retained* -This handle reports whether the dust bin is installed. Attachments not compatible with your robot may be included (but set to `false`) and you can safely ignore them. +This handle reports whether the dust bin attachment is installed. - Read topic: `//AttachmentStateAttribute/dustbin` - Data type: [boolean](https://homieiot.github.io/specification/#boolean) @@ -711,13 +677,17 @@ Sample value: true ``` +Home Assistant components controlled by this property: + +- Dust bin attachment ([`binary_sensor.mqtt`](https://www.home-assistant.io/integrations/binary_sensor.mqtt/)) + ##### Mop (`mop`) *Property, readable, retained* -This handle reports whether the mop is installed. Attachments not compatible with your robot may be included (but set to `false`) and you can safely ignore them. +This handle reports whether the mop attachment is installed. - Read topic: `//AttachmentStateAttribute/mop` - Data type: [boolean](https://homieiot.github.io/specification/#boolean) @@ -728,13 +698,17 @@ Sample value: false ``` +Home Assistant components controlled by this property: + +- Mop attachment ([`binary_sensor.mqtt`](https://www.home-assistant.io/integrations/binary_sensor.mqtt/)) + ##### Water tank (`watertank`) *Property, readable, retained* -This handle reports whether the water tank is installed. Attachments not compatible with your robot may be included (but set to `false`) and you can safely ignore them. +This handle reports whether the water tank attachment is installed. - Read topic: `//AttachmentStateAttribute/watertank` - Data type: [boolean](https://homieiot.github.io/specification/#boolean) @@ -745,6 +719,10 @@ Sample value: true ``` +Home Assistant components controlled by this property: + +- Water tank attachment ([`binary_sensor.mqtt`](https://www.home-assistant.io/integrations/binary_sensor.mqtt/)) + diff --git a/docs/_pages/integrations/openhab-integration.md b/docs/_pages/integrations/openhab-integration.md index 212c05e3..450e3a3f 100644 --- a/docs/_pages/integrations/openhab-integration.md +++ b/docs/_pages/integrations/openhab-integration.md @@ -144,7 +144,7 @@ This is easy to fix from settings. 2. Find the item you want to change (fan speed/water grade/clean segments) 3. Click Add Metadata and select Command Options 4. Add your custom options in the `command=Friendly name` format, one per line. - For example, for `viomi.v8` fan speed presets: + For example, for fan speed presets: ``` low=Low diff --git a/docs/_pages/knowledge_base/supported-viomi-devices.md b/docs/_pages/knowledge_base/supported-viomi-devices.md deleted file mode 100644 index 8acf0b82..00000000 --- a/docs/_pages/knowledge_base/supported-viomi-devices.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Supported Viomi Devices -category: Archive -order: 9997 ---- -# Supported Viomi Devices -[Shenzhen 3irobotix Co.,Ltd.](http://www.3irobotics.com/en/) produces white-label vacuum robots. -They are sold under various brands. For example `Cecotec Conga` or `Viomi`. -Since they are basically the same products, hopefully, Valetudo will eventually support all of them. - - -For now however, there's only experimental support for the Viomi-branded ones which run a customized firmware -including a miio interface. - -If you want to find out more about robot vacuum research, -check out [Dennis' Vacuum Robot Overview](https://dontvacuum.me/robotinfo/). - -This is an incomplete list of supported viomi devices. Feel free to open a PR to extend this.
-If you want to see everything that is supported by the codebase, check out the autogenerated [supported robots](https://valetudo.cloud/pages/general/supported-robots.html) page. - - -## Table of Contents - -1. [CRL-200S](#CRL-200S) - -## CRL-200S
-This one is also known as the - -* Mijia STYJ02YM **viomi.vacuum.v7** - -and there are multiple Device IDs in the Mi ecosystem as well: - -* viomi.vacuum.v6 -* viomi.vacuum.v7 -* viomi.vacuum.v8 - -![CRL-200S Viomi V2 Top](./img/devices/3irobotix/CRL-200S-viomi-v2-top.jpg) - -### Features -These are the Hardware specs - -| Property | Value | Notes | -|------------------|----------|-------| -| Height | 9.45 cm | | -| Width | 35 cm | | -| Battery Capacity | 3200 mAh | | -| Dustbin Size | 600 ml | | -| Suction Power | 2000 Pa | | -| Climbing Ability | 20 mm | | -| Washable Filter | ❌ | | -| Mop Feature | ✔ | | -| Water Pump | ✔ | | diff --git a/docs/_pages/style-guide.md b/docs/_pages/style-guide.md new file mode 100644 index 00000000..32e0b1fe --- /dev/null +++ b/docs/_pages/style-guide.md @@ -0,0 +1,156 @@ +--- +title: Style Guide +category: Misc +order: 33 +--- +# Style Guide + +While I am by no means a designer, I figured that it would make sense to document some design choices for the sake +of consistency. + + +## General + +This project is called Valetudo with a capital V. + +It should always be capitalized.
+There also shouldn't be any spaces in between, as "vale tudo" is a style of mixed martial arts. + +## Logo + +### Full Logo + +This is the main logo including the full project name. + + +
+Valetudo Full Logo +
+ +The font used is Ubuntu Medium, +which nicely picks up the round-ish-ness of the Valetudo logo. + + +### Minimal Logo + +This is the minimal variant of the logo featuring only the actual logo part. +It is usually used for icons or when the full logo is simply too large to make sense. + +
+Valetudo Minimal Logo +
+ +The logo embodies both a V-shape for Valetudo and a round-ish shape to represent the roundness +of most vacuum robots. Furthermore, it features a styled reference to a LIDAR tower in the middle. + + +## Colors + +### Logo colors + +The two shades of blue used in the logo serve as the identity of the project and thus must never be altered. + +
+
+
+
#0076FF
+
+ +
+
+
#52AEFF
+
+
+ +### Text/Background colors + +This section needs some work. There hasn't been any decision yet. + +### Accent colors + +Valetudo's main use of color is the map renderer with the same blue used in the logo representing floor +and additional colors being used to distinguish different segments in the map. + +These colors may also be used to emphasize something or add color to other areas. +For example, the logviewer uses these to easily distinguish the different loglevels. + +To better match dark themes, the 20% darkened variant that can be seen on the right may also be used. + +
+
+
+
#0076FF
+
+ +
+
+
#005ECC
+
+
+ + +
+
+
+
#19A1A1
+
+ +
+
+
#148181
+
+
+ +
+
+
+
#7AC037
+
+ +
+
+
#629A2C
+
+
+ +
+
+
+
#DF5618
+
+ +
+
+
#B24513
+
+
+ +
+
+
+
#F7C841
+
+ +
+
+
#C6A034
+
+
+ +
+
+
+
#9966CC
+
+ +
+
+
#7A52A3
+
+
+ +## Fonts + +The font used by the full logo is Ubuntu Medium. + +Further choices of fonts are TBD. diff --git a/docs/_pages/troubleshooting.md b/docs/_pages/troubleshooting.md index 2830f930..3d145231 100644 --- a/docs/_pages/troubleshooting.md +++ b/docs/_pages/troubleshooting.md @@ -1,7 +1,7 @@ --- title: Troubleshooting category: Misc -order: 33 +order: 34 --- # Troubleshooting diff --git a/docs/assets/css/style.css b/docs/assets/css/style.css index fad0b8cd..e1e11684 100644 --- a/docs/assets/css/style.css +++ b/docs/assets/css/style.css @@ -1,31 +1,3 @@ -@font-face{ - font-family:'Noto Sans'; - font-weight:400; - font-style:normal; - src:url("../fonts/Noto-Sans-regular/Noto-Sans-regular.eot"); - src:url("../fonts/Noto-Sans-regular/Noto-Sans-regular.eot?#iefix") format("embedded-opentype"),local("Noto Sans"),local("Noto-Sans-regular"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.woff2") format("woff2"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.woff") format("woff"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.ttf") format("truetype"),url("../fonts/Noto-Sans-regular/Noto-Sans-regular.svg#NotoSans") format("svg") -} -@font-face{ - font-family:'Noto Sans'; - font-weight:700; - font-style:normal; - src:url("../fonts/Noto-Sans-700/Noto-Sans-700.eot"); - src:url("../fonts/Noto-Sans-700/Noto-Sans-700.eot?#iefix") format("embedded-opentype"),local("Noto Sans Bold"),local("Noto-Sans-700"),url("../fonts/Noto-Sans-700/Noto-Sans-700.woff2") format("woff2"),url("../fonts/Noto-Sans-700/Noto-Sans-700.woff") format("woff"),url("../fonts/Noto-Sans-700/Noto-Sans-700.ttf") format("truetype"),url("../fonts/Noto-Sans-700/Noto-Sans-700.svg#NotoSans") format("svg") -} -@font-face{ - font-family:'Noto Sans'; - font-weight:400; - font-style:italic; - src:url("../fonts/Noto-Sans-italic/Noto-Sans-italic.eot"); - src:url("../fonts/Noto-Sans-italic/Noto-Sans-italic.eot?#iefix") format("embedded-opentype"),local("Noto Sans Italic"),local("Noto-Sans-italic"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.woff2") format("woff2"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.woff") format("woff"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.ttf") format("truetype"),url("../fonts/Noto-Sans-italic/Noto-Sans-italic.svg#NotoSans") format("svg") -} -@font-face{ - font-family:'Noto Sans'; - font-weight:700; - font-style:italic; - src:url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot"); - src:url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.eot?#iefix") format("embedded-opentype"),local("Noto Sans Bold Italic"),local("Noto-Sans-700italic"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff2") format("woff2"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.woff") format("woff"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.ttf") format("truetype"),url("../fonts/Noto-Sans-700italic/Noto-Sans-700italic.svg#NotoSans") format("svg") -} .highlight table td{ padding:5px } @@ -254,7 +226,8 @@ p,ul,ol,table,pre,dl{ margin:0 0 20px } h1,h2,h3{ - line-height:1.1 + line-height:1.1; + margin-top: 2em } h1{ font-size:28px @@ -520,3 +493,12 @@ footer{ background-color: #f2dede; border-color: #ebccd1; } + +/* emphasis boxes */ +.emphasis-box { + margin-left: 1rem; + background-color: #eee; + padding: 1rem; + margin-bottom: 1rem; + border-radius: 5px; +} diff --git a/docs/index.md b/docs/index.md index 4e9f0b74..041f78b2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,32 +3,61 @@

Free your vacuum from the cloud

-Valetudo is a standalone binary, which runs on **rooted Vacuums of the Xiaomi ecosystem** and aims to enable the user to operate the robot vacuum without any Cloud Connection whatsoever. +Valetudo is the de-facto-standard open-source software solution for cloud-free vacuum robots empowering thousands of users.
+Since it was started in 2018, it has matured to a reliable fire-and-forget solution that just works. + +Valetudo is made, managed, maintained and more by me, +Sören Beye, with occasional contributions by +these awesome people.
+It would not exist without the ongoing work of Dennis Giese, +who is constantly providing us with new ways of liberating and gaining actual ownership of our robots. + +As there is no telemetry built-in and no commercial interest to change that, I can't tell you how many users exactly are there, +however judging by download counts and support group members, I'd guesstimate that there are a few thousand. + +If you want to learn more about why someone would want to use something like Valetudo, check out the [Why Valetudo?](https://valetudo.cloud/pages/general/why-valetudo.html) page. + +If you want to learn more about why someone would **not** want to use something like Valetudo, check out the [Why not Valetudo?](https://valetudo.cloud/pages/general/why-not-valetudo.html) page. + +To choose the right robot to buy, head over to [Buying supported robots](https://valetudo.cloud/pages/general/buying-supported-robots.html). + +If you want to learn more about why I'm building Valetudo, the answer is actually pretty simple:
+When I was looking for a vacuum robot for myself, I didn't find anything that matched what I was looking for.
+Thus, in a brief moment of hubris, I thought to myself: "How hard can it be?".
+Now, four years later, we're here and I'm quite happy with how it turned out. + +Valetudo is licensed under the Apache-2.0 open-source license, because you need to be able to know what your smart +devices are doing and also alter (some parts of) it without being dependent on some vendor and/or third party. +The only way of truly achieving that is by being able to see and modify the code. + +The Apache-2.0 license is a very permissive license and a lot of work is being shared for free here, so I trust people to not take +advantage of that and sell Valetudo; especially not as their own work.
+Please don't disappoint me. Thank you. + These are the Valetudo Docs. Simply use the navigation menu on the left to find what you're looking for. - -If you're missing something, or you've found something wrong or outdated, feel free to edit the page and open a PR. -You can also add new pages if you want to document something that isn't documented yet. +The [getting started guide](https://valetudo.cloud/pages/general/getting-started.html) is a good place to start. Also, make sure to check out the companion apps section. ### Screenshots -#### Phone/Mobile +### Phone/Mobile ![image](https://user-images.githubusercontent.com/974410/143459816-0a5fb9e5-d690-483e-99b0-84c76ef11eaf.png) ![image](https://user-images.githubusercontent.com/974410/143459878-184c7336-002c-4e04-a706-215499338fce.png) -![image](https://user-images.githubusercontent.com/974410/138561874-f5e5fee9-81dd-43fb-9de0-75263169a0e6.png) -![image](https://user-images.githubusercontent.com/974410/138561884-9633600b-3362-454b-b95d-90f8e5951971.png) +![image](https://user-images.githubusercontent.com/974410/152567792-73e4ba52-f39b-44fd-a0ae-18a5c4115e7f.png) +![image](https://user-images.githubusercontent.com/974410/152567884-b4c06af8-3bfe-4c12-976e-2e424f86df56.png) +### Tablet/Desktop -#### Tablet/Desktop +![image](https://user-images.githubusercontent.com/974410/152569273-23c4ee7e-310b-40f7-8762-eed661547dff.png) -![image](https://user-images.githubusercontent.com/974410/138562037-05bc5140-d7af-488b-8734-72e66b820192.png) +![image](https://user-images.githubusercontent.com/974410/152568144-4b237999-4373-44e3-9b29-b6498d7db81e.png) -![image](https://user-images.githubusercontent.com/974410/138561911-77aa8d10-3918-4eb7-96ff-8a6d0440dfce.png) +![image](https://user-images.githubusercontent.com/974410/152568471-c111328b-b3d5-4ea8-9a1f-21bb5ae987ca.png) ![image](https://user-images.githubusercontent.com/974410/138562111-3cbfe03c-7a19-4e57-9bfb-6b872239f432.png) @@ -38,14 +67,5 @@ Also, make sure to check out the companion apps section. * \#valetudo on irc.libera.chat ### Expectation Management -This project is the hobby of some random guy on the internet. There is no intent to monetize Valetudo now or in the future meaning that market share is irrelevant. -Therefore, this is run as a zero compromises project. - -This project is not user focussed. It is provided for free as open source to anyone but that's all. -User satisfaction is no goal of Valetudo. - -As Valetudo only exists because it is fun to maintain/improve/etc., any departure from this core policy would be the death of the project. -It could be a slow death with the values slowly eroding in favour of monetization/data stealing/etc. but it would be a death either way. - -I don't want Valetudo to die. I'm pretty sure that you don't want that either. -Thus, please be mindful of that fact next time you're angry about your ideas being rejected because they don't fit the projects goals. +This project is the hobby of some random guy on the internet who really does not care about market share.
+It does what I want it to do, so I'm happy with it. \ No newline at end of file diff --git a/frontend/.automated.eslintrc.json b/frontend/.automated.eslintrc.json new file mode 100644 index 00000000..a8bd7740 --- /dev/null +++ b/frontend/.automated.eslintrc.json @@ -0,0 +1,89 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:@typescript-eslint/recommended" + ], + "plugins": [ + "react", + "@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 12, + "sourceType": "module" + }, + "settings": { + "react": { + "version": "detect" + }, + "linkComponents": [ + "Hyperlink", + { + "name": "Link", + "linkAttribute": "to" + } + ] + }, + "rules": { + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "varsIgnorePattern": "^_", + "args": "none" + } + ], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "brace-style": [ + "error", + "1tbs" + ], + "no-trailing-spaces": [ + "error", + { + "ignoreComments": true + } + ], + "keyword-spacing": "error", + "eol-last": [ + "error", + "always" + ], + "no-multi-spaces": [ + "error", + { + "ignoreEOLComments": true + } + ], + "semi": [ + "error", + "always" + ], + "quotes": [ + "error", + "double" + ], + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-empty": "error" + } +} \ No newline at end of file diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index fd471067..746d17d2 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -44,6 +44,7 @@ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", "react/jsx-uses-react": "off", "react/react-in-jsx-scope": "off", "react/prop-types": "off" diff --git a/frontend/.pedantic.eslintrc.json b/frontend/.pedantic.eslintrc.json new file mode 100644 index 00000000..19318bc8 --- /dev/null +++ b/frontend/.pedantic.eslintrc.json @@ -0,0 +1,109 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:@typescript-eslint/recommended" + ], + "plugins": [ + "react", + "@typescript-eslint" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 12, + "sourceType": "module" + }, + "settings": { + "react": { + "version": "detect" + }, + "linkComponents": [ + "Hyperlink", + { + "name": "Link", + "linkAttribute": "to" + } + ] + }, + "rules": { + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "varsIgnorePattern": "^_", + "args": "none" + } + ], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off", + "react/prop-types": "off", + "brace-style": [ + "error", + "1tbs" + ], + "no-trailing-spaces": [ + "error", + { + "ignoreComments": true + } + ], + "keyword-spacing": "error", + "eol-last": [ + "error", + "always" + ], + "no-multi-spaces": [ + "error", + { + "ignoreEOLComments": true + } + ], + "semi": [ + "error", + "always" + ], + "quotes": [ + "error", + "double" + ], + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-empty": "error", + "no-magic-numbers": [ + "error", + { + "ignoreArrayIndexes": true, + "ignore": [ + -1, + 0, + 1, + 200, + 400, + 404, + 500, + 16, + 60, + 10, + 1000, + 1024 + ] + } + ] + } +} \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 2fbbfe2f..e90f6cde 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,12 +3,13 @@ "homepage": ".", "scripts": { "analyze": "source-map-explorer 'build/static/js/*.js'", - "build": "react-scripts build", + "build": "cross-env GENERATE_SOURCEMAP=false react-scripts build", "eject": "react-scripts eject", "watch": "cra-build-watch -p ''", "ts-check": "tsc --noEmit --skipLibCheck", - "lint": "eslint .", - "lint_fix": "eslint . --fix", + "lint": "eslint -c .automated.eslintrc.json .", + "lint_fix": "eslint -c .automated.eslintrc.json . --fix", + "lint_pedantic": "eslint -c .pedantic.eslintrc.json .", "prepare_commit": "npm run lint_fix && npm run ts-check" }, "eslintConfig": { @@ -30,35 +31,39 @@ ] }, "dependencies": { - "@emotion/react": "11.6.0", - "@emotion/styled": "11.6.0", - "@fontsource/roboto": "4.5.1", - "@mui/material": "5.2.0", - "@mui/icons-material": "5.2.0", - "@mui/lab": "5.0.0-alpha.48", - "axios": "0.24.0", - "color": "4.0.1", - "date-fns": "2.26.0", - "notistack": "2.0.3", - "react": "17.0.2", + "@fontsource/jetbrains-mono": "4.5.11", + "@fontsource/roboto": "4.5.8", + "@mui/material": "5.10.9", + "@mui/base": "5.0.0-alpha.81", + "@mui/icons-material": "5.10.9", + "@mui/lab": "5.0.0-alpha.82", + "@emotion/styled": "11.10.4", + "@emotion/react": "11.10.4", + "axios": "0.27.2", + "date-fns": "2.29.3", + "jsencrypt": "3.2.1", + "notistack": "2.0.5", + "react": "18.2.0", "react-div-100vh": "0.7.0", - "react-dom": "17.0.2", - "rehype-raw": "6.1.0", - "react-markdown": "7.1.0", + "react-dom": "18.2.0", + "reconnecting-eventsource": "1.5.2", + "rehype-raw": "6.1.1", + "react-markdown": "8.0.3", "remark-gfm": "3.0.1", - "react-query": "3.33.5", - "react-router-dom": "5.3.0", - "react-scripts": "4.0.3", - "semaphore": "^1.1.0", - "uuid": "8.3.2" + "react-query": "3.39.2", + "react-router-dom": "5.3.3", + "react-scripts": "5.0.1", + "semaphore": "1.1.0", + "use-long-press": "2.0.2", + "uuid": "9.0.0", + "zustand": "4.1.2" }, "devDependencies": { - "@types/color": "3.0.2", - "@types/react": "17.0.37", - "@types/react-dom": "17.0.11", - "@types/react-router-dom": "5.1.8", - "@types/uuid": "8.3.3", + "@types/react": "18.0.21", + "@types/react-dom": "18.0.6", + "@types/react-router-dom": "5.3.3", + "@types/uuid": "8.3.4", "tsutils": "3.21.0", - "cra-build-watch": "3.4.0" + "cra-build-watch": "git+https://npm@github.com/Hypfer/cra-build-watch.git#5.0.0" } } diff --git a/frontend/public/apple-touch-icon.png b/frontend/public/apple-touch-icon.png index 1a64c804..e30c0371 100644 Binary files a/frontend/public/apple-touch-icon.png and b/frontend/public/apple-touch-icon.png differ diff --git a/frontend/public/mapLayerRenderWebWorker.js b/frontend/public/mapLayerRenderWebWorker.js deleted file mode 100644 index 1711f8c0..00000000 --- a/frontend/public/mapLayerRenderWebWorker.js +++ /dev/null @@ -1,352 +0,0 @@ -/* eslint-disable */ - -/* - Unfortunately, we have to duplicate this rendering code for it to be available in a webworker, - because as of now 2021-10-06, this putting the worker into the public dir hack is the only - way to use a webworker with create-react-app - - See: https://github.com/facebook/create-react-app/issues/3660#issuecomment-602098962 - */ - -self.postMessage({ - ready: true -}); - -self.addEventListener( "message", ( evt ) => { - //According to SonarJS S2819, this might be problematic - //I honestly have no idea if this check is actually needed in a webworker context, but I'll do as the tool says. - if (evt.origin !== "") { - console.warn(`Received event with unexpected origin "${evt.origin}"`); - - return; - } - - const imageData = new ImageData( - new Uint8ClampedArray( evt.data.width * evt.data.height * 4 ), - evt.data.width, - evt.data.height - ); - - const colorFinder = new FourColorTheoremSolver(evt.data.mapLayers, evt.data.pixelSize); - - evt.data.mapLayers.sort((a,b) => { - return TYPE_SORT_MAPPING[a.type] - TYPE_SORT_MAPPING[b.type]; - }).forEach(layer => { - let color; - - switch (layer.type) { - case "floor": - color = evt.data.colors.floor; - break; - case "wall": - color = evt.data.colors.wall; - break; - case "segment": - color = evt.data.colors.segments[colorFinder.getColor((layer.metaData.segmentId ?? ""))]; - break; - } - - if (!color) { - //eslint-disable-next-line no-console - console.error(`Missing color for ${layer.type} with segment id '${layer.metaData.segmentId}'.`); - color = {r: 0, g: 0, b: 0}; - } - - for (let i = 0; i < layer.pixels.length; i = i + 2) { - const imgDataOffset = (layer.pixels[i] + layer.pixels[i+1] * evt.data.width) * 4; - - imageData.data[imgDataOffset] = color.r; - imageData.data[imgDataOffset + 1] = color.g; - imageData.data[imgDataOffset + 2] = color.b; - imageData.data[imgDataOffset + 3] = 255; - } - }); - - - self.postMessage( { - pixels: imageData.data.buffer, - width: evt.data.width, - height: evt.data.height, - }, [imageData.data.buffer] ); -} ); - -// This is important because it determines the draw order -const TYPE_SORT_MAPPING = { - "floor": 14, - "segment": 15, - "wall": 16 -}; - - - -class FourColorTheoremSolver { - /** - * This class determines how to color the different map segments contained in the given layers object. - * The resulting color mapping will ensure that no two adjacent segments share the same color. - * The map is evaluated row-by-row and column-by-column in order to find every pair of segments that are in "line of sight" of each other. - * Each pair of segments is then represented as an edge in a graph where the vertices represent the segments themselves. - * We then use a simple greedy algorithm to color all vertices so that none of its edges connect it to a vertex with the same color. - * - * @param {Array} layers - the data containing the map image (array of pixel offsets) - * @param {number} pixelSize - Used to calculate the resolution of the theorem. Assumes a robot diameter of 30cm and calculates the minimum size of a room. - */ - constructor(layers, pixelSize) { - /** - * @param {number} resolution - Minimal resolution of the map scanner in pixels. Any number higher than one will lead to this many pixels being skipped when finding segment boundaries. - * For example: If the robot measures 30cm in length/width, this should be set to 6, as no room can be smaller than 6 pixels. This of course implies that a pixel represents 5cm in the real world. - */ - const resolution = Math.floor(30 / pixelSize); - this.stepFunction = function (c) { - return c + resolution; - }; - var preparedLayers = this.preprocessLayers(layers); - if (preparedLayers !== undefined) { - var mapData = this.createPixelToSegmentMapping(preparedLayers); - this.areaGraph = this.buildGraph(mapData); - this.areaGraph.colorAllVertices(); - } - } - - /** - * @param {string} segmentId - ID of the segment you want to get the color for. - * The segment ID is extracted from the layer meta data in the first contructor parameter of this class. - * @returns {number} The segment color, represented as an integer. Starts at 0 and goes up the minimal number of colors required to color the map without collisions. - */ - getColor(segmentId) { - if (this.areaGraph === undefined) { - // Layer preprocessing seems to have failed. Just return a default value for any input. - return 0; - } - - var segmentFromGraph = this.areaGraph.getById(segmentId); - if (segmentFromGraph) { - return segmentFromGraph.color; - } else { - return 0; - } - } - - preprocessLayers(layers) { - var internalSegments = []; - var boundaries = { - minX: Infinity, - maxX: -Infinity, - minY: Infinity, - maxY: -Infinity, - }; - const filteredLayers = layers.filter((layer) => { - return layer.type === "segment"; - }); - if (filteredLayers.length <= 0) { - return undefined; - } - filteredLayers.forEach((layer) => { - var allPixels = []; - for (let index = 0; index < layer.pixels.length - 1; index += 2) { - var p = { - x: layer.pixels[index], - y: layer.pixels[index + 1], - }; - this.setBoundaries(boundaries, p); - allPixels.push(p); - } - internalSegments.push({ - segmentId: layer.metaData.segmentId, - name: layer.metaData.name, - pixels: allPixels, - }); - }); - return { - boundaries: boundaries, - segments: internalSegments, - }; - } - - setBoundaries(res, pixel) { - if (pixel.x < res.minX) { - res.minX = pixel.x; - } - if (pixel.y < res.minY) { - res.minY = pixel.y; - } - if (pixel.x > res.maxX) { - res.maxX = pixel.x; - } - if (pixel.y > res.maxY) { - res.maxY = pixel.y; - } - } - - createPixelToSegmentMapping(preparedLayers) { - var pixelData = this.create2DArray( - preparedLayers.boundaries.maxX + 1, - preparedLayers.boundaries.maxY + 1 - ); - var segmentIds = []; - preparedLayers.segments.forEach((seg) => { - segmentIds.push(seg.segmentId); - seg.pixels.forEach((p) => { - pixelData[p.x][p.y] = seg.segmentId; - }); - }); - return { - map: pixelData, - segmentIds: segmentIds, - boundaries: preparedLayers.boundaries, - }; - } - - buildGraph(mapData) { - var vertices = mapData.segmentIds.map((i) => { - return new MapAreaVertex(i); - }); - var graph = new MapAreaGraph(vertices); - this.traverseMap( - mapData.boundaries, - mapData.map, - (x, y, currentSegmentId, pixelData) => { - var newSegmentId = pixelData[x][y]; - graph.connectVertices(currentSegmentId, newSegmentId); - return newSegmentId !== undefined ? newSegmentId : currentSegmentId; - } - ); - return graph; - } - - traverseMap(boundaries, pixelData, func) { - // row-first traversal - for ( - let y = boundaries.minY; - y <= boundaries.maxY; - y = this.stepFunction(y) - ) { - var rowFirstSegmentId = undefined; - for ( - let x = boundaries.minX; - x <= boundaries.maxX; - x = this.stepFunction(x) - ) { - rowFirstSegmentId = func(x, y, rowFirstSegmentId, pixelData); - } - } - // column-first traversal - for ( - let x = boundaries.minX; - x <= boundaries.maxX; - x = this.stepFunction(x) - ) { - var colFirstSegmentId = undefined; - for ( - let y = boundaries.minY; - y <= boundaries.maxY; - y = this.stepFunction(y) - ) { - colFirstSegmentId = func(x, y, colFirstSegmentId, pixelData); - } - } - } - - /** - * Credit for this function goes to the authors of this StackOverflow answer: https://stackoverflow.com/a/966938 - * - * @param {number} length - */ - create2DArray(length) { - var arr = new Array(length || 0), - i = length; - if (arguments.length > 1) { - var args = Array.prototype.slice.call(arguments, 1); - while (i--) { - arr[length - 1 - i] = this.create2DArray.apply(this, args); - } - } - return arr; - } -} - -class MapAreaVertex { - constructor(id) { - this.id = id; - this.adjacentVertexIds = new Set(); - this.color = undefined; - } - - appendVertex(vertexId) { - if (vertexId !== undefined) { - this.adjacentVertexIds.add(vertexId); - } - } -} - -class MapAreaGraph { - constructor(vertices) { - this.vertices = vertices; - this.vertexLookup = new Map(); - this.vertices.forEach((v) => { - this.vertexLookup.set(v.id, v); - }); - } - - connectVertices(id1, id2) { - if (id1 !== undefined && id2 !== undefined && id1 !== id2) { - if (this.vertexLookup.has(id1)) { - this.vertexLookup.get(id1).appendVertex(id2); - } - if (this.vertexLookup.has(id2)) { - this.vertexLookup.get(id2).appendVertex(id1); - } - } - } - - /** - * Color the graphs vertices using a greedy algorithm. Any vertices that have already been assigned a color will not be changed. - * Color assignment will start with the vertex that is connected with the highest number of edges. In most cases, this will - * naturally lead to a distribution where only four colors are required for the whole graph. This is relevant for maps with a high - * number of segments, as the naive, greedy algorithm tends to require a fifth color when starting coloring in a segment far from the map's center. - * - */ - colorAllVertices() { - this.vertices - .sort((l, r) => { - return r.adjacentVertexIds.size - l.adjacentVertexIds.size; - }) - .forEach((v) => { - if (v.adjacentVertexIds.size <= 0) { - v.color = 0; - } else { - var adjs = this.getAdjacentVertices(v); - var existingColors = adjs - .filter((vert) => { - return vert.color !== undefined; - }) - .map((vert) => { - return vert.color; - }); - v.color = this.lowestColor(existingColors); - } - }); - } - - getAdjacentVertices(vertex) { - return Array.from(vertex.adjacentVertexIds).map((id) => { - return this.getById(id); - }); - } - - getById(id) { - return this.vertices.find((v) => { - return v.id === id; - }); - } - - lowestColor(colors) { - if (colors.length <= 0) { - return 0; - } - for (let index = 0; index < colors.length + 1; index++) { - if (!colors.includes(index)) { - return index; - } - } - } -} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 77bda82a..c3be83f2 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -12,6 +12,7 @@ import "@fontsource/roboto/300.css"; import "@fontsource/roboto/400.css"; import "@fontsource/roboto/500.css"; import "@fontsource/roboto/700.css"; +import "@fontsource/jetbrains-mono/200.css"; const queryClient = new QueryClient(); diff --git a/frontend/src/ProvisioningPage.tsx b/frontend/src/ProvisioningPage.tsx index 22fb0cfd..d625d6cc 100644 --- a/frontend/src/ProvisioningPage.tsx +++ b/frontend/src/ProvisioningPage.tsx @@ -39,7 +39,11 @@ const ProvisioningPage = (): JSX.Element => { const { mutate: updateWifiConfiguration, isLoading: wifiConfigurationUpdating - } = useWifiConfigurationMutation(); + } = useWifiConfigurationMutation({ + onSuccess: () => { + setFinalDialogOpen(true); + } + }); const [newSSID, setNewSSID] = React.useState(""); const [newPSK, setNewPSK] = React.useState(""); @@ -192,7 +196,6 @@ const ProvisioningPage = (): JSX.Element => { setConfirmationDialogOpen(false); }} onAccept={() => { - setFinalDialogOpen(true); updateWifiConfiguration({ ssid: newSSID, credentials: { @@ -206,7 +209,10 @@ const ProvisioningPage = (): JSX.Element => { Are you sure you want to apply the Wi-Fi settings?
- Hint: You can always revert back to the integrated Wifi Hotspot. +
+ Hint: +
+ You can always revert back to the integrated Wifi Hotspot. Check the documentation supplied with your robot for instructions on how to do so.
diff --git a/frontend/src/api/RawRobotState.ts b/frontend/src/api/RawRobotState.ts index deccac1c..4658fc66 100644 --- a/frontend/src/api/RawRobotState.ts +++ b/frontend/src/api/RawRobotState.ts @@ -15,7 +15,7 @@ export enum RobotAttributeClass { BatteryState = "BatteryStateAttribute", PresetSelectionState = "PresetSelectionStateAttribute", AttachmentState = "AttachmentStateAttribute", - OperationModeState = "OperationModeStateAttribute" + DockStatusState = "DockStatusStateAttribute" } export interface StatusState { @@ -43,34 +43,34 @@ export interface BatteryState { export interface PresetSelectionState { __class: RobotAttributeClass.PresetSelectionState; metaData: Record; - type: "fan_speed" | "water_grade"; - value: "off" | "min" | "low" | "medium" | "high" | "max" | "turbo" | "custom"; + type: "fan_speed" | "water_grade" | "operation_mode"; + value: "off" | "min" | "low" | "medium" | "high" | "max" | "turbo" | "custom" | "vacuum" | "mop" | "vacuum_and_mop"; customValue?: number; } +export type AttachmentStateAttributeType = "dustbin" | "watertank" | "mop"; + export interface AttachmentState { __class: RobotAttributeClass.AttachmentState; - type: "dustbin" | "watertank" | "mop"; + type: AttachmentStateAttributeType; attached: boolean; } -export interface OperationModeState { - __class: RobotAttributeClass.OperationModeState; - value: "vacuum" | "mop" | "vacuum_and_mop"; +export interface DockStatusState { + __class: RobotAttributeClass.DockStatusState; + metaData: Record; + value: + | "error" + | "idle" + | "pause" + | "emptying" + | "cleaning" + | "drying"; } -// export interface ConsumableState { -// type: 'filter' | 'brush' | 'sensor' | 'mop'; -// subType: 'none' | 'all' | 'main' | 'side_left' | 'side_right'; -// remaining: { -// value: number; -// unit: 'minutes' | 'percent'; -// }; -// } - export type RobotAttribute = | StatusState | BatteryState | PresetSelectionState | AttachmentState - | OperationModeState; + | DockStatusState; diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index ebc47fd1..bce01dfd 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -1,4 +1,5 @@ import axios from "axios"; +import { JSEncrypt } from "jsencrypt"; import { RawMapData } from "./RawMapData"; import { PresetSelectionState, RobotAttribute } from "./RawRobotState"; import { @@ -8,7 +9,6 @@ import { ConsumableId, ConsumableState, DoNotDisturbConfiguration, - GoToLocation, HTTPBasicAuthConfiguration, LogLevelResponse, ManualControlInteraction, @@ -20,11 +20,15 @@ import { MapSegmentRenameRequestParameters, MQTTConfiguration, MQTTProperties, + MQTTStatus, + NetworkAdvertisementConfiguration, + NetworkAdvertisementProperties, NTPClientConfiguration, NTPClientState, Point, Quirk, RobotInformation, + RobotProperties, Segment, SetLogLevelRequest, SetQuirkValueCommand, @@ -44,14 +48,15 @@ import { ValetudoVersion, VoicePackManagementCommand, VoicePackManagementStatus, - WifiConfiguration, + WifiConfiguration, WifiConfigurationProperties, + WifiProvisioningEncryptionKey, WifiStatus, Zone, - ZonePreset, ZoneProperties, } from "./types"; import { floorObject } from "./utils"; import {preprocessMap} from "./mapUtils"; +import ReconnectingEventSource from "reconnecting-eventsource"; export const valetudoAPI = axios.create({ baseURL: "./api/v2", @@ -105,8 +110,9 @@ const subscribeToSSE = ( return tracker(); } - const source = new EventSource(valetudoAPI.defaults.baseURL + endpoint, { + const source = new ReconnectingEventSource(valetudoAPI.defaults.baseURL + endpoint, { withCredentials: true, + max_retry_time: 30000 }); source.addEventListener(event, (event: any) => { @@ -180,7 +186,7 @@ export const subscribeToStateAttributes = ( }; export const fetchPresetSelections = async ( - capability: Capability.FanSpeedControl | Capability.WaterUsageControl + capability: Capability.FanSpeedControl | Capability.WaterUsageControl | Capability.OperationModeControl ): Promise => { return valetudoAPI .get( @@ -192,7 +198,7 @@ export const fetchPresetSelections = async ( }; export const updatePresetSelection = async ( - capability: Capability.FanSpeedControl | Capability.WaterUsageControl, + capability: Capability.FanSpeedControl | Capability.WaterUsageControl | Capability.OperationModeControl, level: PresetSelectionState["value"] ): Promise => { await valetudoAPI.put(`/robot/capabilities/${capability}/preset`, { @@ -222,16 +228,6 @@ export const sendGoToCommand = async (point: Point): Promise => { ); }; -export const fetchZonePresets = async (): Promise => { - return valetudoAPI - .get>( - `/robot/capabilities/${Capability.ZoneCleaning}/presets` - ) - .then(({data}) => { - return Object.values(data); - }); -}; - export const fetchZoneProperties = async (): Promise => { return valetudoAPI .get( @@ -242,15 +238,6 @@ export const fetchZoneProperties = async (): Promise => { }); }; -export const sendCleanZonePresetCommand = async (id: string): Promise => { - await valetudoAPI.put( - `/robot/capabilities/${Capability.ZoneCleaning}/presets/${id}`, - { - action: "clean", - } - ); -}; - export const sendCleanTemporaryZonesCommand = async ( zones: Zone[] ): Promise => { @@ -335,27 +322,6 @@ export const sendRenameSegmentCommand = async ( ); }; -export const fetchGoToLocationPresets = async (): Promise => { - return valetudoAPI - .get>( - `/robot/capabilities/${Capability.GoToLocation}/presets` - ) - .then(({data}) => { - return Object.values(data); - }); -}; - -export const sendGoToLocationPresetCommand = async ( - id: string -): Promise => { - await valetudoAPI.put( - `/robot/capabilities/${Capability.GoToLocation}/presets/${id}`, - { - action: "goto", - } - ); -}; - export const sendLocateCommand = async (): Promise => { await valetudoAPI.put(`/robot/capabilities/${Capability.Locate}`, { action: "locate", @@ -445,7 +411,7 @@ export const sendValetudoLogLevel = async (logLevel: SetLogLevelRequest): Promis await valetudoAPI .put("/valetudo/log/level", logLevel) .then(({ status }) => { - if (status !== 202) { + if (status !== 200) { throw new Error("Could not set new log level"); } }); @@ -479,15 +445,23 @@ export const sendMQTTConfiguration = async (mqttConfiguration: MQTTConfiguration return valetudoAPI .put("/valetudo/config/interfaces/mqtt", mqttConfiguration) .then(({status}) => { - if (status !== 202) { + if (status !== 200) { throw new Error("Could not update MQTT configuration"); } }); }; +export const fetchMQTTStatus = async (): Promise => { + return valetudoAPI + .get("/mqtt/status") + .then(({data}) => { + return data; + }); +}; + export const fetchMQTTProperties = async (): Promise => { return valetudoAPI - .get("/valetudo/config/interfaces/mqtt/properties") + .get("/mqtt/properties") .then(({data}) => { return data; }); @@ -505,12 +479,38 @@ export const sendHTTPBasicAuthConfiguration = async (configuration: HTTPBasicAut return valetudoAPI .put("/valetudo/config/interfaces/http/auth/basic", configuration) .then(({status}) => { - if (status !== 201) { + if (status !== 200) { throw new Error("Could not update HTTP basic auth configuration"); } }); }; +export const fetchNetworkAdvertisementConfiguration = async (): Promise => { + return valetudoAPI + .get("/networkadvertisement/config") + .then(({data}) => { + return data; + }); +}; + +export const sendNetworkAdvertisementConfiguration = async (configuration: NetworkAdvertisementConfiguration): Promise => { + return valetudoAPI + .put("/networkadvertisement/config", configuration) + .then(({status}) => { + if (status !== 200) { + throw new Error("Could not update NetworkAdvertisement configuration"); + } + }); +}; + +export const fetchNetworkAdvertisementProperties = async (): Promise => { + return valetudoAPI + .get("/networkadvertisement/properties") + .then(({data}) => { + return data; + }); +}; + export const fetchNTPClientState = async (): Promise => { return valetudoAPI .get("/ntpclient/state") @@ -531,7 +531,7 @@ export const sendNTPClientConfiguration = async (configuration: NTPClientConfigu return valetudoAPI .put("/ntpclient/config", configuration) .then(({status}) => { - if (status !== 202) { + if (status !== 200) { throw new Error("Could not update NTP client configuration"); } }); @@ -549,7 +549,7 @@ export const deleteTimer = async (id: string): Promise => { export const sendTimerCreation = async (timerData: Timer): Promise => { await valetudoAPI.post("/timers", timerData).then(({ status }) => { - if (status !== 201) { + if (status !== 200) { throw new Error("Could not create timer"); } }); @@ -557,7 +557,7 @@ export const sendTimerCreation = async (timerData: Timer): Promise => { export const sendTimerUpdate = async (timerData: Timer): Promise => { await valetudoAPI - .post(`/timers/${timerData.id}`, timerData) + .put(`/timers/${timerData.id}`, timerData) .then(({ status }) => { if (status !== 200) { throw new Error("Could not update timer"); @@ -746,9 +746,32 @@ export const fetchWifiStatus = async (): Promise => { }); }; +export const fetchWifiConfigurationProperties = async (): Promise => { + return valetudoAPI + .get(`/robot/capabilities/${Capability.WifiConfiguration}/properties`) + .then(({ data }) => { + return data; + }); +}; + + export const sendWifiConfiguration = async (configuration: WifiConfiguration): Promise => { + const encryptionKey = await fetchWifiProvisioningEncryptionKey(); + + const cipher = new JSEncrypt(); + cipher.setPublicKey(encryptionKey.publicKey); + + const encryptedPayload = cipher.encrypt(JSON.stringify(configuration)); + + if (!encryptedPayload) { + throw new Error("Failed to encrypt Wi-Fi credentials"); + } + await valetudoAPI - .put(`/robot/capabilities/${Capability.WifiConfiguration}`, configuration) + .put(`/robot/capabilities/${Capability.WifiConfiguration}`, { + encryption: "rsa", + payload: encryptedPayload + }) .then(({ status }) => { if (status !== 200) { throw new Error("Could not set Wifi configuration"); @@ -756,6 +779,14 @@ export const sendWifiConfiguration = async (configuration: WifiConfiguration): P }); }; +export const fetchWifiProvisioningEncryptionKey = async (): Promise => { + return valetudoAPI + .get(`/robot/capabilities/${Capability.WifiConfiguration}/getPublicKeyForProvisioning`) + .then(({ data }) => { + return data; + }); +}; + export const fetchManualControlState = async (): Promise => { return valetudoAPI .get(`/robot/capabilities/${Capability.ManualControl}`) @@ -869,3 +900,35 @@ export const sendSetQuirkValueCommand = async (command: SetQuirkValueCommand): P } ); }; + +export const fetchRobotProperties = async (): Promise => { + return valetudoAPI + .get("/robot/properties") + .then(({ data }) => { + return data; + }); +}; + +export type MopDockCleanManualTriggerCommand = "start" | "stop"; +export const sendMopDockCleanManualTriggerCommand = async ( + command: MopDockCleanManualTriggerCommand +): Promise => { + await valetudoAPI.put( + `/robot/capabilities/${Capability.MopDockCleanManualTrigger}`, + { + action: command, + } + ); +}; + +export type MopDockDryManualTriggerCommand = "start" | "stop"; +export const sendMopDockDryManualTriggerCommand = async ( + command: MopDockDryManualTriggerCommand +): Promise => { + await valetudoAPI.put( + `/robot/capabilities/${Capability.MopDockDryManualTrigger}`, + { + action: command, + } + ); +}; diff --git a/frontend/src/api/hooks.ts b/frontend/src/api/hooks.ts index dd417ad2..92dad3f3 100644 --- a/frontend/src/api/hooks.ts +++ b/frontend/src/api/hooks.ts @@ -19,7 +19,6 @@ import { fetchCurrentStatistics, fetchCurrentStatisticsProperties, fetchDoNotDisturbConfiguration, - fetchGoToLocationPresets, fetchHTTPBasicAuthConfiguration, fetchKeyLockState, fetchManualControlProperties, @@ -49,7 +48,6 @@ import { fetchValetudoLogLevel, fetchVoicePackManagementState, fetchWifiStatus, - fetchZonePresets, fetchZoneProperties, sendAutoEmptyDockAutoEmptyControlEnable, sendAutoEmptyDockManualTriggerCommand, @@ -57,12 +55,10 @@ import { sendCarpetModeEnable, sendCleanSegmentsCommand, sendCleanTemporaryZonesCommand, - sendCleanZonePresetCommand, sendCombinedVirtualRestrictionsUpdate, sendConsumableReset, sendDoNotDisturbConfiguration, sendGoToCommand, - sendGoToLocationPresetCommand, sendHTTPBasicAuthConfiguration, sendJoinSegmentsCommand, sendKeyLockEnable, @@ -91,6 +87,14 @@ import { fetchValetudoInformation, fetchQuirks, sendSetQuirkValueCommand, + fetchRobotProperties, + fetchMQTTStatus, + fetchNetworkAdvertisementConfiguration, + fetchNetworkAdvertisementProperties, + sendNetworkAdvertisementConfiguration, + sendMopDockDryManualTriggerCommand, + sendMopDockCleanManualTriggerCommand, + MopDockCleanManualTriggerCommand, MopDockDryManualTriggerCommand, fetchWifiConfigurationProperties, } from "./client"; import { PresetSelectionState, @@ -111,6 +115,7 @@ import { MapSegmentEditSplitRequestParameters, MapSegmentRenameRequestParameters, MQTTConfiguration, + NetworkAdvertisementConfiguration, NTPClientConfiguration, NTPClientState, Point, @@ -118,6 +123,7 @@ import { Timer, ValetudoEventInteractionContext, VoicePackManagementCommand, + WifiConfiguration, Zone, } from "./types"; import {MutationFunction} from "react-query/types/core/types"; @@ -128,11 +134,9 @@ enum CacheKey { Consumables = "consumables", Attributes = "attributes", PresetSelections = "preset_selections", - ZonePresets = "zone_presets", ZoneProperties = "zone_properties", Segments = "segments", MapSegmentationProperties = "map_segmentation_properties", - GoToLocationPresets = "go_to_location_presets", PersistentData = "persistent_data", RobotInformation = "robot_information", ValetudoInformation = "valetudo_information", @@ -143,8 +147,11 @@ enum CacheKey { SystemHostInfo = "system_host_info", SystemRuntimeInfo = "system_runtime_info", MQTTConfiguration = "mqtt_configuration", + MQTTStatus = "mqtt_status", MQTTProperties = "mqtt_properties", HTTPBasicAuth = "http_basic_auth", + NetworkAdvertisementConfiguration = "network_advertisement_configuration", + NetworkAdvertisementProperties = "network_advertisement_properties", NTPClientState = "ntp_client_state", NTPClientConfiguration = "ntp_client_configuration", Timers = "timers", @@ -156,6 +163,7 @@ enum CacheKey { AutoEmptyDockAutoEmpty = "auto_empty_dock_auto_empty", DoNotDisturb = "do_not_disturb", WifiStatus = "wifi_status", + WifiConfigurationProperties = "wifi_configuration_properties", ManualControl = "manual_control", ManualControlProperties = "manual_control_properties", CombinedVirtualRestrictionsProperties = "combined_virtual_restrictions_properties", @@ -164,7 +172,8 @@ enum CacheKey { CurrentStatisticsProperties = "current_statistics_properties", TotalStatistics = "total_statistics", TotalStatisticsProperties = "total_statistics_properties", - Quirks = "quirks" + Quirks = "quirks", + RobotProperties = "robot_properties" } const useOnCommandError = (capability: Capability | string): ((error: unknown) => void) => { @@ -293,7 +302,7 @@ export function useRobotStatusQuery(select?: (status: StatusState) => any) { } export const usePresetSelectionsQuery = ( - capability: Capability.FanSpeedControl | Capability.WaterUsageControl + capability: Capability.FanSpeedControl | Capability.WaterUsageControl | Capability.OperationModeControl ) => { return useQuery( [CacheKey.PresetSelections, capability], @@ -310,9 +319,10 @@ export const capabilityToPresetType: Record = { [Capability.FanSpeedControl]: "fan_speed", [Capability.WaterUsageControl]: "water_grade", + [Capability.OperationModeControl]: "operation_mode", }; export const usePresetSelectionMutation = ( - capability: Capability.FanSpeedControl | Capability.WaterUsageControl + capability: Capability.FanSpeedControl | Capability.WaterUsageControl | Capability.OperationModeControl ) => { const queryClient = useQueryClient(); const onError = useOnCommandError(capability); @@ -376,39 +386,12 @@ export const useGoToMutation = ( ); }; -export const useZonePresetsQuery = () => { - return useQuery(CacheKey.ZonePresets, fetchZonePresets); -}; - export const useZonePropertiesQuery = () => { return useQuery(CacheKey.ZoneProperties, fetchZoneProperties, { staleTime: Infinity, }); }; -export const useCleanZonePresetMutation = ( - options?: UseMutationOptions -) => { - const queryClient = useQueryClient(); - const onError = useOnCommandError(Capability.ZoneCleaning); - - return useMutation( - (id: string) => { - return sendCleanZonePresetCommand(id).then(fetchStateAttributes); - }, - { - onError, - ...options, - async onSuccess(data, ...args) { - queryClient.setQueryData(CacheKey.Attributes, data, { - updatedAt: Date.now(), - }); - await options?.onSuccess?.(data, ...args); - }, - } - ); -}; - export const useCleanTemporaryZonesMutation = ( options?: UseMutationOptions ) => { @@ -436,9 +419,12 @@ export const useSegmentsQuery = () => { return useQuery(CacheKey.Segments, fetchSegments); }; -export const useMapSegmentationPropertiesQuery = () => { +// As conditional hooks aren't allowed, this query needs a way to be disabled but referenced +// for cases where a component might need the properties but only if the capability exists +export const useMapSegmentationPropertiesQuery = (enabled?: boolean) => { return useQuery(CacheKey.MapSegmentationProperties, fetchMapSegmentationProperties, { - staleTime: Infinity + staleTime: Infinity, + enabled: enabled ?? true }); }; @@ -534,33 +520,6 @@ export const useRenameSegmentMutation = ( ); }; -export const useGoToLocationPresetsQuery = () => { - return useQuery(CacheKey.GoToLocationPresets, fetchGoToLocationPresets); -}; - -export const useGoToLocationPresetMutation = ( - options?: UseMutationOptions -) => { - const queryClient = useQueryClient(); - const onError = useOnCommandError(Capability.ZoneCleaning); - - return useMutation( - (id: string) => { - return sendGoToLocationPresetCommand(id).then(fetchStateAttributes); - }, - { - onError, - ...options, - async onSuccess(data, ...args) { - queryClient.setQueryData(CacheKey.Attributes, data, { - updatedAt: Date.now(), - }); - await options?.onSuccess?.(data, ...args); - }, - } - ); -}; - export const useLocateMutation = () => { const onError = useOnCommandError(Capability.Locate); @@ -645,6 +604,13 @@ export const useMQTTConfigurationMutation = () => { ); }; +export const useMQTTStatusQuery = () => { + return useQuery(CacheKey.MQTTStatus, fetchMQTTStatus, { + staleTime: 5_000, + refetchInterval: 5_000 + }); +}; + export const useMQTTPropertiesQuery = () => { return useQuery(CacheKey.MQTTProperties, fetchMQTTProperties, { staleTime: Infinity, @@ -667,6 +633,28 @@ export const useHTTPBasicAuthConfigurationMutation = () => { ); }; +export const useNetworkAdvertisementConfigurationQuery = () => { + return useQuery(CacheKey.NetworkAdvertisementConfiguration, fetchNetworkAdvertisementConfiguration, { + staleTime: Infinity, + }); +}; + +export const useNetworkAdvertisementConfigurationMutation = () => { + return useValetudoFetchingMutation( + useOnSettingsChangeError("Network Advertisement"), + CacheKey.NetworkAdvertisementConfiguration, + (networkAdvertisementConfiguration: NetworkAdvertisementConfiguration) => { + return sendNetworkAdvertisementConfiguration(networkAdvertisementConfiguration).then(fetchNetworkAdvertisementConfiguration); + } + ); +}; + +export const useNetworkAdvertisementPropertiesQuery = () => { + return useQuery(CacheKey.NetworkAdvertisementProperties, fetchNetworkAdvertisementProperties, { + staleTime: Infinity, + }); +}; + export const useNTPClientStateQuery = () => { return useQuery(CacheKey.NTPClientState, fetchNTPClientState, { staleTime: 5_000, @@ -932,7 +920,15 @@ export const useWifiStatusQuery = () => { }); }; -export const useWifiConfigurationMutation = () => { +export const useWifiConfigurationPropertiesQuery = () => { + return useQuery(CacheKey.WifiConfigurationProperties, fetchWifiConfigurationProperties, { + staleTime: Infinity + }); +}; + +export const useWifiConfigurationMutation = ( + options?: UseMutationOptions +) => { const { refetch: refetchWifiStatus, } = useWifiStatusQuery(); @@ -941,8 +937,12 @@ export const useWifiConfigurationMutation = () => { sendWifiConfiguration, { onError: useOnCommandError(Capability.WifiConfiguration), - onSuccess() { - refetchWifiStatus().catch(() => {/*intentional*/}); + async onSuccess(data, ...args) { + refetchWifiStatus().catch(() => { + /*intentional*/ + }); + + await options?.onSuccess?.(data, ...args); } } ); @@ -1068,3 +1068,47 @@ export const useSetQuirkValueMutation = () => { } ); }; + +export const useRobotPropertiesQuery = () => { + return useQuery(CacheKey.RobotProperties, fetchRobotProperties, { + staleTime: Infinity, + }); +}; + +export const useMopDockCleanManualTriggerMutation = () => { + const queryClient = useQueryClient(); + const onError = useOnCommandError(Capability.MopDockCleanManualTrigger); + + return useMutation( + (command: MopDockCleanManualTriggerCommand) => { + return sendMopDockCleanManualTriggerCommand(command).then(fetchStateAttributes); + }, + { + onError, + onSuccess(data) { + queryClient.setQueryData(CacheKey.Attributes, data, { + updatedAt: Date.now(), + }); + }, + } + ); +}; + +export const useMopDockDryManualTriggerMutation = () => { + const queryClient = useQueryClient(); + const onError = useOnCommandError(Capability.MopDockDryManualTrigger); + + return useMutation( + (command: MopDockDryManualTriggerCommand) => { + return sendMopDockDryManualTriggerCommand(command).then(fetchStateAttributes); + }, + { + onError, + onSuccess(data) { + queryClient.setQueryData(CacheKey.Attributes, data, { + updatedAt: Date.now(), + }); + }, + } + ); +}; diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index 7c6a36be..c1b5979d 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -1,3 +1,5 @@ +import {AttachmentStateAttributeType} from "./RawRobotState"; + export enum Capability { AutoEmptyDockAutoEmptyControl = "AutoEmptyDockAutoEmptyControlCapability", AutoEmptyDockManualTrigger = "AutoEmptyDockManualTriggerCapability", @@ -18,8 +20,10 @@ export enum Capability { MapSegmentation = "MapSegmentationCapability", MapSnapshot = "MapSnapshotCapability", MappingPass = "MappingPassCapability", + MopDockCleanManualTrigger = "MopDockCleanManualTriggerCapability", + MopDockDryManualTrigger = "MopDockDryManualTriggerCapability", + OperationModeControl = "OperationModeControlCapability", PersistentMapControl = "PersistentMapControlCapability", - SensorCalibration = "SensorCalibrationCapability", SpeakerTest = "SpeakerTestCapability", SpeakerVolumeControl = "SpeakerVolumeControlCapability", TotalStatistics = "TotalStatisticsCapability", @@ -45,12 +49,6 @@ export interface Zone { iterations: number; } -export interface ZonePreset { - id: string; - name: string; - zones: Zone[]; -} - export interface ZoneProperties { zoneCount: { min: number; @@ -70,12 +68,6 @@ export interface MapSegmentationProperties { customOrderSupport: boolean; } -export interface GoToLocation { - id: string; - name: string; - coordinates: Point; -} - export interface Segment { id: string; name?: string; @@ -84,11 +76,15 @@ export interface Segment { export interface RobotInformation { manufacturer: string; modelName: string; + modelDetails: { + supportedAttachments: Array; + } implementation: string; } export interface ValetudoInformation { embedded: boolean; + systemId: string; } export interface ValetudoVersion { @@ -222,6 +218,29 @@ export interface MQTTConfiguration { cleanAutoconfOnShutdown: boolean; }; }; + optionalExposedCapabilities: Array; +} + +export interface MQTTStatus { + state: "init" | "ready" | "disconnected" | "lost" | "alert", + stats: { + messages: { + count: { + received: number; + sent: number; + }, + bytes: { + received: number; + sent: number; + } + }, + connection: { + connects: number; + disconnects: number; + reconnects: number; + errors: number; + } + } } export interface MQTTProperties { @@ -234,6 +253,7 @@ export interface MQTTProperties { topicPrefix: string; }; }; + optionalExposableCapabilities: Array; } export interface HTTPBasicAuthConfiguration { @@ -242,6 +262,15 @@ export interface HTTPBasicAuthConfiguration { password: string; } +export interface NetworkAdvertisementConfiguration { + enabled: boolean; +} + +export interface NetworkAdvertisementProperties { + port: number; + zeroconfHostname: string; +} + export interface NTPClientState { __class: "ValetudoNTPClientDisabledState" | "ValetudoNTPClientEnabledState" | "ValetudoNTPClientErrorState" | "ValetudoNTPClientSyncedState"; timestamp: string; @@ -358,6 +387,15 @@ export interface WifiStatus { }; } +export interface WifiConfigurationProperties { + provisionedReconfigurationSupported: boolean; +} + +export interface WifiProvisioningEncryptionKey { + type: "rsa"; + publicKey: string; +} + export type ManualControlAction = "enable" | "disable" | "move"; export type ManualControlCommand = "forward" | "backward" | "rotate_clockwise" | "rotate_counterclockwise"; @@ -439,3 +477,7 @@ export interface SetQuirkValueCommand { id: string, value: string } + +export interface RobotProperties { + firmwareVersion: string +} diff --git a/frontend/src/components/IntegrationHelpDialog.tsx b/frontend/src/components/IntegrationHelpDialog.tsx new file mode 100644 index 00000000..a71f55e0 --- /dev/null +++ b/frontend/src/components/IntegrationHelpDialog.tsx @@ -0,0 +1,84 @@ +import React from "react"; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Typography +} from "@mui/material"; +import InfoBox from "./InfoBox"; + +const IntegrationHelpDialog: React.FunctionComponent<{ + dialogOpen: boolean, + setDialogOpen: (newOpen: boolean) => void, + helperText: string, + coordinatesWarning: boolean, + payload: string +}> = ({ + dialogOpen, + setDialogOpen, + helperText, + coordinatesWarning, + payload +}): JSX.Element => { + return ( + { + setDialogOpen(false); + }} + open={dialogOpen} + + style={{userSelect: "none"}} + > + + Connect with other applications + + + + {helperText} + + { + coordinatesWarning && + + + Please note that the coordinates displayed here can become invalid if the underlying map changes. + + + } +
+
+                            {payload}
+                        
+
+
+
+ + + + +
+ ); +}; + +export default IntegrationHelpDialog; diff --git a/frontend/src/components/LogViewer.module.css b/frontend/src/components/LogViewer.module.css index 12861ccb..bb22bd4a 100644 --- a/frontend/src/components/LogViewer.module.css +++ b/frontend/src/components/LogViewer.module.css @@ -31,7 +31,8 @@ } .content { - font-family: monospace; + font-family: "JetBrains Mono",monospace; + font-weight: 200; white-space: pre-wrap; width: 100%; overflow-wrap: anywhere; diff --git a/frontend/src/components/LogViewer.tsx b/frontend/src/components/LogViewer.tsx index 517fc184..90c3a71f 100644 --- a/frontend/src/components/LogViewer.tsx +++ b/frontend/src/components/LogViewer.tsx @@ -28,20 +28,35 @@ function getLoglevelCssClass(level : LogLevel) { const LogViewer: FunctionComponent = (props) => { const logRef = React.useRef(null); + const [scrolledToBottom, setScrolledToBottom] = React.useState(true); const {logLines} = props; React.useEffect(() => { const currentLogRef = logRef.current; if (currentLogRef) { - const elem = currentLogRef as HTMLTextAreaElement; - elem.scrollTop = elem.scrollHeight; + const elem = currentLogRef as HTMLElement; + + if (scrolledToBottom) { + elem.scrollTop = elem.scrollHeight; + } } - }); + }, [logLines, scrolledToBottom]); return ( <>
-
+
{ + const currentLogRef = logRef.current; + if (currentLogRef) { + const elem = currentLogRef as HTMLElement; + + setScrolledToBottom(elem.scrollHeight - Math.abs(elem.scrollTop) === elem.clientHeight); + } + }} + > { logLines.map((line, i) => { return ( //The trailing spaces in the metadata section are important for copy-pasting diff --git a/frontend/src/components/ReloadableCard.tsx b/frontend/src/components/ReloadableCard.tsx index 01397e3e..0960acec 100644 --- a/frontend/src/components/ReloadableCard.tsx +++ b/frontend/src/components/ReloadableCard.tsx @@ -18,8 +18,8 @@ interface ReloadableCardProps { children: React.ReactNode; loading?: boolean; divider?: boolean; - boxShadow?: number, - helpText?: string + boxShadow?: number; + helpText?: string; } const ReloadableCard: FunctionComponent = ({ @@ -30,7 +30,7 @@ const ReloadableCard: FunctionComponent = ({ loading = false, divider = true, boxShadow, - helpText + helpText, }): JSX.Element => { const [helpDialogOpen, setHelpDialogOpen] = React.useState(false); diff --git a/frontend/src/components/TextInformationGrid.tsx b/frontend/src/components/TextInformationGrid.tsx new file mode 100644 index 00000000..f5187011 --- /dev/null +++ b/frontend/src/components/TextInformationGrid.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import {Grid, Typography} from "@mui/material"; + +const TextInformationGrid: React.FunctionComponent<{ items: Array<{ header: string, body: string }> }> = ({ + items +}): JSX.Element => { + return ( + + {items.map((item) => { + return ( + + + {item.header} + + {item.body} + + ); + })} + + ); +}; + +export default TextInformationGrid; diff --git a/frontend/src/components/ValetudoAppBar.tsx b/frontend/src/components/ValetudoAppBar.tsx index ea03126e..50c2b98a 100644 --- a/frontend/src/components/ValetudoAppBar.tsx +++ b/frontend/src/components/ValetudoAppBar.tsx @@ -29,7 +29,6 @@ import { Power as PowerIcon, SystemUpdateAlt as UpdaterIcon, SettingsRemote as SettingsRemoteIcon, - Elderly as OldFrontendIcon, GitHub as GithubIcon, Favorite as DonateIcon, MenuBook as DocsIcon, @@ -123,9 +122,9 @@ const menuTree: Array = [ { kind: "MenuEntry", routeMatch: "/settings/map_management", - title: "Map Management", + title: "Map", menuIcon: MapManagementIcon, - menuText: "Map Management", + menuText: "Map", requiredCapabilities: { capabilities: [ Capability.PersistentMapControl, @@ -152,6 +151,12 @@ const menuTree: Array = [ title: "Virtual Restriction Management", parentRoute: "/settings/map_management" }, + { + kind: "MenuSubEntry", + routeMatch: "/settings/map_management/robot_coverage", + title: "Robot Coverage Map", + parentRoute: "/settings/map_management" + }, { kind: "MenuEntry", routeMatch: "/settings/connectivity", @@ -171,6 +176,12 @@ const menuTree: Array = [ title: "MQTT Connectivity", parentRoute: "/settings/connectivity" }, + { + kind: "MenuSubEntry", + routeMatch: "/settings/connectivity/networkadvertisement", + title: "Network Advertisement", + parentRoute: "/settings/connectivity" + }, { kind: "MenuSubEntry", routeMatch: "/settings/connectivity/ntp", @@ -388,29 +399,20 @@ const ValetudoAppBar: React.FunctionComponent<{ paletteMode: PaletteMode, setPal component="a" href="./swagger/" target="_blank" + rel="noopener" > - - - - - - @@ -433,6 +435,7 @@ const ValetudoAppBar: React.FunctionComponent<{ paletteMode: PaletteMode, setPal component="a" href="https://github.com/Hypfer/Valetudo" target="_blank" + rel="noopener" > @@ -444,6 +447,7 @@ const ValetudoAppBar: React.FunctionComponent<{ paletteMode: PaletteMode, setPal component="a" href="https://github.com/sponsors/Hypfer" target="_blank" + rel="noopener" > diff --git a/frontend/src/components/ValetudoEvents.module.css b/frontend/src/components/ValetudoEvents.module.css new file mode 100644 index 00000000..969a82a4 --- /dev/null +++ b/frontend/src/components/ValetudoEvents.module.css @@ -0,0 +1,67 @@ +.eventContainer { + overflow-y: auto; + padding-right: 0.5rem; + max-height: 75vh; +} + +@media print, screen and (max-height: 730px) { + .eventContainer { + max-height: 70vh; + } +} + +@media print, screen and (max-height: 610px) { + .eventContainer { + max-height: 65vh; + } +} + + +@media print, screen and (max-height: 610px) { + .eventContainer { + max-height: 65vh; + } +} + +@media print, screen and (max-height: 520px) { + .eventContainer { + max-height: 60vh; + } +} + +@media print, screen and (max-height: 460px) { + .eventContainer { + max-height: 55vh; + } +} + +@media print, screen and (max-height: 410px) { + .eventContainer { + max-height: 50vh; + } +} + +@media print, screen and (max-height: 370px) { + .eventContainer { + max-height: 45vh; + } +} + +@media print, screen and (max-height: 330px) { + .eventContainer { + max-height: 40vh; + } +} + +@media print, screen and (max-height: 310px) { + .eventContainer { + max-height: 35vh; + } +} + +@media print, screen and (max-height: 280px) { + .eventContainer { + max-height: 30vh; + } +} + diff --git a/frontend/src/components/ValetudoEvents.tsx b/frontend/src/components/ValetudoEvents.tsx index 3a5fa332..739dab5a 100644 --- a/frontend/src/components/ValetudoEvents.tsx +++ b/frontend/src/components/ValetudoEvents.tsx @@ -1,9 +1,10 @@ import React from "react"; -import {Badge, Divider, IconButton, Popover, Stack, Typography} from "@mui/material"; +import {Badge, Button, Divider, IconButton, Popover, Stack, Typography} from "@mui/material"; import {Notifications as NotificationsIcon} from "@mui/icons-material"; import {useValetudoEventsInteraction, useValetudoEventsQuery} from "../api"; import {eventControls} from "./ValetudoEventControls"; import ReloadableCard from "./ReloadableCard"; +import styles from "./ValetudoEvents.module.css"; const ValetudoEvents = (): JSX.Element => { const { @@ -48,11 +49,11 @@ const ValetudoEvents = (): JSX.Element => { }, [eventData, eventDataError, eventDataLoading]); const popoverContent = React.useMemo(() => { - const events = eventData && eventData.length ? eventData.map(event => { + const events = eventData && eventData.length ? eventData.map((event, i) => { const EventControl = eventControls[event.__class] || eventControls.Default; return ( - + { i > 0 && } { interactWithEvent({ id: event.id, @@ -68,12 +69,34 @@ const ValetudoEvents = (): JSX.Element => { ); return ( - { - return eventDataRefetch(); - }}> - - {events} - + { + return eventDataRefetch(); + }} + > + +
+ + {events} + +
+ +
); }, [eventData, eventDataFetching, eventDataRefetch, interactWithEvent]); diff --git a/frontend/src/components/list_menu/ButtonListMenuItem.tsx b/frontend/src/components/list_menu/ButtonListMenuItem.tsx index d6de5f04..1769a6f5 100644 --- a/frontend/src/components/list_menu/ButtonListMenuItem.tsx +++ b/frontend/src/components/list_menu/ButtonListMenuItem.tsx @@ -9,20 +9,21 @@ export const ButtonListMenuItem: React.FunctionComponent<{ icon: JSX.Element, buttonLabel: string, buttonIsDangerous?: boolean, - confirmationDialogTitle: string, - confirmationDialogBody: string, - dialogAction: () => void, - dialogActionLoading: boolean + confirmationDialog?: { + title: string, + body: string, + } + action: () => void, + actionLoading: boolean, }> = ({ primaryLabel, secondaryLabel, icon, buttonLabel, buttonIsDangerous, - confirmationDialogTitle, - confirmationDialogBody, - dialogAction, - dialogActionLoading + confirmationDialog, + action, + actionLoading, }): JSX.Element => { const [dialogOpen, setDialogOpen] = React.useState(false); @@ -38,13 +39,21 @@ export const ButtonListMenuItem: React.FunctionComponent<{ {icon} - + { - setDialogOpen(true); + if (confirmationDialog) { + setDialogOpen(true); + } else { + action(); + } }} sx={{ mt: 1, @@ -55,15 +64,18 @@ export const ButtonListMenuItem: React.FunctionComponent<{ {buttonLabel}
- { - setDialogOpen(false); - }} - onAccept={dialogAction} - /> + { + confirmationDialog !== undefined && + { + setDialogOpen(false); + }} + onAccept={action} + /> + } ); }; diff --git a/frontend/src/components/list_menu/LinkListMenuItem.tsx b/frontend/src/components/list_menu/LinkListMenuItem.tsx index 1d592019..f6c94b02 100644 --- a/frontend/src/components/list_menu/LinkListMenuItem.tsx +++ b/frontend/src/components/list_menu/LinkListMenuItem.tsx @@ -35,7 +35,11 @@ export const LinkListMenuItem: React.FunctionComponent<{ {icon} - + ); }; diff --git a/frontend/src/components/list_menu/ListMenu.tsx b/frontend/src/components/list_menu/ListMenu.tsx index 5d313949..dea17a34 100644 --- a/frontend/src/components/list_menu/ListMenu.tsx +++ b/frontend/src/components/list_menu/ListMenu.tsx @@ -1,4 +1,3 @@ -import PaperContainer from "../PaperContainer"; import {Divider, Grid, IconButton, List, ListItemText} from "@mui/material"; import React from "react"; import {SpacerListMenuItem} from "./SpacerListMenuItem"; @@ -10,18 +9,21 @@ export const ListMenu: React.FunctionComponent<{ primaryHeader: string, secondaryHeader: string, listItems: Array, - helpText?: string + helpText?: string, + style?: React.CSSProperties, }> = ({ primaryHeader, secondaryHeader, listItems, - helpText + helpText, + style }): JSX.Element => { const [helpDialogOpen, setHelpDialogOpen] = React.useState(false); return ( - + <> } - + ); }; diff --git a/frontend/src/components/list_menu/ToggleSwitchListMenuItem.tsx b/frontend/src/components/list_menu/ToggleSwitchListMenuItem.tsx index 54e9c05b..f549c806 100644 --- a/frontend/src/components/list_menu/ToggleSwitchListMenuItem.tsx +++ b/frontend/src/components/list_menu/ToggleSwitchListMenuItem.tsx @@ -47,7 +47,11 @@ export const ToggleSwitchListMenuItem: React.FunctionComponent<{ {icon} - + {toggle} ); diff --git a/frontend/src/controls/Attachments.tsx b/frontend/src/controls/Attachments.tsx index 116c169f..cdb825b4 100644 --- a/frontend/src/controls/Attachments.tsx +++ b/frontend/src/controls/Attachments.tsx @@ -6,7 +6,7 @@ import {Box, Grid, Paper, Typography, ToggleButton, ToggleButtonGroup} from "@mu import React from "react"; import LoadingFade from "../components/LoadingFade"; -const Attachments = (): JSX.Element => { +const Attachments = (): JSX.Element | null => { const { data: attachments, isLoading: isAttachmentLoading, @@ -44,29 +44,31 @@ const Attachments = (): JSX.Element => { }, [attachments, isAttachmentError]); return ( - - - - - - - Attachments - + + + + + + + + Attachments + + + + + - - + + {attachmentDetails} - - - {attachmentDetails} - - - - + + + + ); }; diff --git a/frontend/src/controls/BasicControls.tsx b/frontend/src/controls/BasicControls.tsx index a6365209..294d8180 100644 --- a/frontend/src/controls/BasicControls.tsx +++ b/frontend/src/controls/BasicControls.tsx @@ -2,6 +2,7 @@ import { Box, Button, ButtonGroup, + DialogContentText, Grid, Paper, Typography, @@ -20,6 +21,9 @@ import { SvgIconComponent, } from "@mui/icons-material"; import React from "react"; +import LoadingFade from "../components/LoadingFade"; +import ConfirmationDialog from "../components/ConfirmationDialog"; +import {usePendingMapAction} from "../map/Map"; const StartStates: StatusState["value"][] = ["idle", "docked", "paused", "error"]; const PauseStates: StatusState["value"][] = ["cleaning", "returning", "moving"]; @@ -32,27 +36,48 @@ interface CommandButton { } const BasicControls = (): JSX.Element => { - const { data: status } = useRobotStatusQuery(); + const [startConfirmationDialogOpen, setStartConfirmationDialogOpen] = React.useState(false); + const { data: status, isLoading: statusLoading } = useRobotStatusQuery(); const { mutate: executeBasicControlCommand, isLoading: basicControlIsExecuting } = useBasicControlMutation(); + const { + hasPendingMapAction: hasPendingMapAction + } = usePendingMapAction(); + const isLoading = basicControlIsExecuting; const sendCommand = (command: BasicControlCommand) => { - return () => { + if (command === "start" && hasPendingMapAction) { + setStartConfirmationDialogOpen(true); + } else { executeBasicControlCommand(command); - }; + } }; + if (statusLoading) { + return ( + + + + + + + + ); + } + if (status === undefined) { return ( - - - Error loading basic controls - - + + + + Error loading basic controls + + + ); } @@ -79,42 +104,67 @@ const BasicControls = (): JSX.Element => { }, { command: "home", - enabled: state === "idle" || state === "error", + enabled: state === "idle" || state === "error" || state === "paused", Icon: HomeIcon, label: "Dock", }, ]; return ( - - - - - - {buttons.map(({ label, command, enabled, Icon }) => { - return ( + <> + + + + + + + {buttons.map(({ label, command, enabled, Icon }) => { + return ( + + + ); + })} + + + + + + - - ); - })} - - - - - + { + setStartConfirmationDialogOpen(false); + }} + onAccept={() => { + executeBasicControlCommand("start"); + }}> + + You currently have a pending MapAction. +
+
+ Hint: +
+ You might instead be looking for the button on the bottom right of the map. +
+
+ ); }; diff --git a/frontend/src/controls/ControlsBody.tsx b/frontend/src/controls/ControlsBody.tsx index d34da5b7..e1aa0b72 100644 --- a/frontend/src/controls/ControlsBody.tsx +++ b/frontend/src/controls/ControlsBody.tsx @@ -1,16 +1,18 @@ import {Grid} from "@mui/material"; -import {Opacity as WaterUsageIcon,} from "@mui/icons-material"; -import {Capability} from "../api"; +import { + Opacity as WaterUsageIcon, + AppRegistration as OperationModeIcon, +} from "@mui/icons-material"; +import {Capability, useRobotInformationQuery} from "../api"; import {useCapabilitiesSupported} from "../CapabilitiesProvider"; import BasicControls from "./BasicControls"; -import GoToLocationPresets from "./GoToLocationPresets"; import PresetSelectionControl from "./PresetSelection"; import RobotStatus from "./RobotStatus"; -import ZonePresets from "./ZonePresets"; import Dock from "./Dock"; import CurrentStatistics from "./CurrentStatistics"; import Attachments from "./Attachments"; import {FanSpeedIcon} from "../components/CustomIcons"; +import React from "react"; const ControlsBody = (): JSX.Element => { @@ -18,77 +20,78 @@ const ControlsBody = (): JSX.Element => { basicControls, fanSpeed, waterControl, - goToLocation, - zoneCleaning, + operationMode, triggerEmptySupported, + mopDockCleanTriggerSupported, + mopDockDryTriggerSupported, currentStatistics, ] = useCapabilitiesSupported( Capability.BasicControl, Capability.FanSpeedControl, Capability.WaterUsageControl, - Capability.GoToLocation, - Capability.ZoneCleaning, + Capability.OperationModeControl, Capability.AutoEmptyDockManualTrigger, + Capability.MopDockCleanManualTrigger, + Capability.MopDockDryManualTrigger, Capability.CurrentStatistics ); + const { + data: robotInformation, + } = useRobotInformationQuery(); + + return ( - {basicControls && ( - - - + {basicControls && } + + + + {operationMode && ( + + } + /> )} - - - + {fanSpeed && ( - - - } - /> - + + } + /> )} {waterControl && ( - - } - /> - + } + /> )} - {triggerEmptySupported && ( - - - - )} - {goToLocation && ( - - - - )} - {zoneCleaning && ( - - - - )} - - - + + { + (triggerEmptySupported || mopDockCleanTriggerSupported || mopDockDryTriggerSupported) && + + + } + { - currentStatistics && ( - - - - ) + robotInformation && + robotInformation.modelDetails.supportedAttachments.length > 0 && + + } + + {currentStatistics && } ); }; diff --git a/frontend/src/controls/CurrentStatistics.tsx b/frontend/src/controls/CurrentStatistics.tsx index c719137e..13cf236a 100644 --- a/frontend/src/controls/CurrentStatistics.tsx +++ b/frontend/src/controls/CurrentStatistics.tsx @@ -50,30 +50,32 @@ const CurrentStatistics = (): JSX.Element => { ]); return ( - - - - - - - - Current Statistics - + + + + + + + + + Current Statistics + + + + + - - + + {body} - - - {body} - - - - + + + + ); }; diff --git a/frontend/src/controls/Dock.tsx b/frontend/src/controls/Dock.tsx index 9551677f..5d56f99d 100644 --- a/frontend/src/controls/Dock.tsx +++ b/frontend/src/controls/Dock.tsx @@ -1,13 +1,33 @@ -import {Capability, useAutoEmptyDockManualTriggerMutation, useRobotStatusQuery} from "../api"; +import { + Capability, + RobotAttributeClass, + useAutoEmptyDockManualTriggerMutation, + useMopDockCleanManualTriggerMutation, + useMopDockDryManualTriggerMutation, + useRobotAttributeQuery, + useRobotStatusQuery +} from "../api"; import {useCapabilitiesSupported} from "../CapabilitiesProvider"; import {Box, Button, Grid, Icon, Paper, styled, Typography} from "@mui/material"; import { - RestoreFromTrash as EmptyIcon + RestoreFromTrash as EmptyIcon, + Water as CleanMopIcon, + WindPower as DryMopIcon, } from "@mui/icons-material"; import React from "react"; +import LoadingFade from "../components/LoadingFade"; const Dock = (): JSX.Element => { - const { data: status } = useRobotStatusQuery(); + const { data: robotStatus, isLoading: isRobotStatusLoading } = useRobotStatusQuery(); + const { + data: dockStatus, + isLoading: isDockStatusLoading, + } = useRobotAttributeQuery(RobotAttributeClass.DockStatusState); + const { + data: attachments, + isLoading: isAttachmentLoading, + } = useRobotAttributeQuery(RobotAttributeClass.AttachmentState); + const isLoading = isRobotStatusLoading || isDockStatusLoading || isAttachmentLoading; const StyledIcon = styled(Icon)(({ theme }) => { return { @@ -16,53 +36,132 @@ const Dock = (): JSX.Element => { }; }); - const [triggerEmptySupported] = useCapabilitiesSupported(Capability.AutoEmptyDockManualTrigger); + const [ + triggerEmptySupported, + mopDockCleanTriggerSupported, + mopDockDryTriggerSupported, + ] = useCapabilitiesSupported( + Capability.AutoEmptyDockManualTrigger, + Capability.MopDockCleanManualTrigger, + Capability.MopDockDryManualTrigger, + ); + const { mutate: triggerDockEmpty, isLoading: emptyIsExecuting, } = useAutoEmptyDockManualTriggerMutation(); + const { + mutate: triggerMopDockCleanCommand, + isLoading: mopDockCleanCommandExecuting, + } = useMopDockCleanManualTriggerMutation(); + const { + mutate: triggerMopDockDryCommand, + isLoading: mopDockDryCommandExecuting, + } = useMopDockDryManualTriggerMutation(); + + + const dockStatusIsRelevant = mopDockCleanTriggerSupported || mopDockDryTriggerSupported; + const commandIsExecuting = emptyIsExecuting || mopDockCleanCommandExecuting || mopDockDryCommandExecuting; + const mopAttachmentAttached = attachments?.find(a => { + return a.type === "mop"; + })?.attached === true; - if (status === undefined) { + if (isLoading) { return ( - - - Error loading dock controls - - + + + + + + + ); } - const { value: state } = status; + if (robotStatus === undefined || (dockStatusIsRelevant && dockStatus?.length !== 1)) { + return ( + + + + Error loading dock controls + + + + ); + } + + const { value: robotState } = robotStatus; + const { value: dockState } = dockStatus?.[0] ?? {value: "idle"}; return ( - - - - - Dock - - { - triggerEmptySupported && - - - - + + + + + + Dock - } + + { + mopDockCleanTriggerSupported && + + + + } + { + mopDockDryTriggerSupported && + + + + } + { + triggerEmptySupported && + + + + } + + + + + ); }; diff --git a/frontend/src/controls/GoToLocationPresets.tsx b/frontend/src/controls/GoToLocationPresets.tsx deleted file mode 100644 index c89bd00a..00000000 --- a/frontend/src/controls/GoToLocationPresets.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import { - Box, - Button, - CircularProgress, - FormControl, - FormHelperText, - Grid, - MenuItem, - Paper, - Select, - SelectChangeEvent, - styled, - Typography, -} from "@mui/material"; -import React from "react"; -import { - Capability, - useGoToLocationPresetMutation, - useGoToLocationPresetsQuery, - useRobotStatusQuery, -} from "../api"; - -const StyledFormControl = styled(FormControl)({ - minWidth: 120, -}); - -const GoToLocationPresets = (): JSX.Element => { - const { data: status } = useRobotStatusQuery((status) => { - return status.value; - }); - const { - data: goToLocations, - isLoading: goToLocationPresetsLoading, - isError: goToLocationPresetLoadError, - } = useGoToLocationPresetsQuery(); - const { - isLoading: goToLocationPresetIsExecuting, - mutate: goToLocationPreset - } = useGoToLocationPresetMutation({ - onSuccess() { - setSelected(""); - }, - }); - const [selected, setSelected] = React.useState(""); - - const handleChange = React.useCallback( - (event: SelectChangeEvent) => { - setSelected(event.target.value); - }, - [] - ); - - const canGo = status === "idle" || status === "docked"; - - const handleGo = React.useCallback(() => { - if (selected === "" || !canGo) { - return; - } - - goToLocationPreset(selected); - }, [canGo, goToLocationPreset, selected]); - - const body = React.useMemo(() => { - if (goToLocationPresetsLoading) { - return ( - - - - ); - } - - if (goToLocationPresetLoadError || goToLocations === undefined) { - return ( - - - Error loading {Capability.GoToLocation} - - - ); - } - - return ( - <> - - - - {!canGo && selected !== "" && ( - Can only go to location when idle - )} - - - - - - - - - ); - }, [ - canGo, - handleChange, - handleGo, - goToLocationPresetIsExecuting, - goToLocationPresetLoadError, - goToLocationPresetsLoading, - goToLocations, - selected, - ]); - - return ( - - - - - Go to - - {body} - - - - ); -}; - -export default GoToLocationPresets; diff --git a/frontend/src/controls/MobileControls.tsx b/frontend/src/controls/MobileControls.tsx index 45f1377b..8f972aed 100644 --- a/frontend/src/controls/MobileControls.tsx +++ b/frontend/src/controls/MobileControls.tsx @@ -1,4 +1,4 @@ -import {Box, Divider, Grid, Icon, Paper, styled} from "@mui/material"; +import {Box, Grid, Icon, Paper, styled} from "@mui/material"; import ControlsBody from "./ControlsBody"; import {ReactComponent as Logo} from "../assets/icons/valetudo_logo_with_name.svg"; import {ExpandLess as OpenIcon, ExpandMore as CloseIcon,} from "@mui/icons-material"; @@ -13,9 +13,20 @@ const MobileControls: React.FunctionComponent<{ open: boolean, setOpen: (newOpen fontSize: "2.5em" }; }); - const Sheet = styled(Box)(({ theme }) => { + const ControlsSheetContainer = styled(Box)(({ theme }) => { + const color = theme.palette.mode === "light" ? "#ededed" : "#242424"; + return { - backgroundColor: theme.palette.background.default, + backgroundColor: color, + borderColor: color, + borderTopWidth: "4px", + borderLeftWidth: "1px", + borderRightWidth: "1px", + borderBottomWidth: "1px", + borderStyle: "solid", + borderTopLeftRadius: "4px", + borderTopRightRadius: "4px", + paddingTop: "0.125rem", }; }); @@ -24,6 +35,19 @@ const MobileControls: React.FunctionComponent<{ open: boolean, setOpen: (newOpen + + + + + - - - - ); }; diff --git a/frontend/src/controls/PresetSelection.tsx b/frontend/src/controls/PresetSelection.tsx index 79816afd..343a097f 100644 --- a/frontend/src/controls/PresetSelection.tsx +++ b/frontend/src/controls/PresetSelection.tsx @@ -1,15 +1,5 @@ -import { - Box, - CircularProgress, - Grid, - Icon, - Mark, - Paper, - Slider, - sliderClasses, - styled, - Typography, -} from "@mui/material"; +import {Box, CircularProgress, Grid, Icon, Paper, Slider, sliderClasses, styled, Typography,} from "@mui/material"; +import {Mark} from "@mui/base"; import React from "react"; import { Capability, @@ -51,15 +41,30 @@ const DiscreteSlider = styled(Slider)(({ theme }) => { }; }); -const order = ["off", "min", "low", "medium", "high", "max", "turbo"]; +const order = ["off", "min", "low", "medium", "high", "max", "turbo", "vacuum", "vacuum_and_mop", "mop"]; const sortPresets = (presets: PresetSelectionState["value"][]) => { return [...presets].sort((a, b) => { return order.indexOf(a) - order.indexOf(b); }); }; +const friendlyNames = { + "off": "Off", + "min": "Min", + "low": "Low", + "medium": "Medium", + "high": "High", + "max": "Max", + "turbo": "Turbo", + + "custom": "Custom", + + "vacuum_and_mop": "Vacuum & Mop", + "vacuum": "Vacuum", + "mop": "Mop" +}; export interface PresetSelectionProps { - capability: Capability.FanSpeedControl | Capability.WaterUsageControl; + capability: Capability.FanSpeedControl | Capability.WaterUsageControl | Capability.OperationModeControl; label: string; icon: JSX.Element; } @@ -109,7 +114,7 @@ const PresetSelectionControl = (props: PresetSelectionProps): JSX.Element => { return filteredPresets.map((preset, index) => { return { value: index, - label: preset, + label: friendlyNames[preset], }; }); }, [filteredPresets]); @@ -132,7 +137,7 @@ const PresetSelectionControl = (props: PresetSelectionProps): JSX.Element => { } return ( - + { min={0} max={marks.length - 1} marks={marks} + track={capability !== Capability.OperationModeControl ? "normal" : false} /> ); @@ -158,66 +164,68 @@ const PresetSelectionControl = (props: PresetSelectionProps): JSX.Element => { ]); return ( - - - - { - setPresetSelectionSliderOpen(!presetSelectionSliderOpen); - }} - style={{cursor: "pointer"}} - > - {icon} - - - {label} - - - - - + + + + { + setPresetSelectionSliderOpen(!presetSelectionSliderOpen); }} + style={{cursor: "pointer"}} > - - { - !selectPresetIsLoading && - - - {preset?.value} - + {icon} + + + {label} + + + + + + + + { + !selectPresetIsLoading && + + + {preset?.value ? friendlyNames[preset.value] : ""} + + + } + + + - } - - - - + - - - {body} - - - - + + {body} + + + + + ); }; diff --git a/frontend/src/controls/RobotStatus.tsx b/frontend/src/controls/RobotStatus.tsx index 58f9d6d1..4a0c4ae9 100644 --- a/frontend/src/controls/RobotStatus.tsx +++ b/frontend/src/controls/RobotStatus.tsx @@ -124,28 +124,30 @@ const RobotStatus = (): JSX.Element => { }, [batteries, isBatteryError]); return ( - - - - - - - State - - {stateDetails} - - {batteries !== undefined && batteries.length > 0 && ( - + + + + + + - Battery + State - {batteriesDetails} + {stateDetails} - )} + {batteries !== undefined && batteries.length > 0 && ( + + + Battery + + {batteriesDetails} + + )} + - - - + + + ); }; diff --git a/frontend/src/controls/ZonePresets.tsx b/frontend/src/controls/ZonePresets.tsx deleted file mode 100644 index 273ce562..00000000 --- a/frontend/src/controls/ZonePresets.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { - Box, - Button, - CircularProgress, - FormControl, - FormHelperText, - Grid, - MenuItem, - Paper, - Select, - SelectChangeEvent, - styled, - Typography, -} from "@mui/material"; -import React from "react"; -import { - Capability, - useCleanZonePresetMutation, - useRobotStatusQuery, - useZonePresetsQuery, -} from "../api"; - -const StyledFormControl = styled(FormControl)({ - minWidth: 120, -}); - -const ZonePresets = (): JSX.Element => { - const { data: status } = useRobotStatusQuery((status) => { - return status.value; - }); - const { - data: zonePresets, - isLoading: zonePresetsLoading, - isError: errorLoadingZonePresets, - } = useZonePresetsQuery(); - const { - isLoading: cleanZonePresetExecuting, - mutate: cleanZonePreset - } = useCleanZonePresetMutation({ - onSuccess() { - setSelected(""); - }, - }); - const [selected, setSelected] = React.useState(""); - const canClean = status === "idle" || status === "docked"; - - const handleChange = React.useCallback( - (event: SelectChangeEvent) => { - setSelected(event.target.value as string); - }, - [] - ); - - const handleClean = React.useCallback(() => { - if (selected === "" || !canClean) { - return; - } - cleanZonePreset(selected); - }, [canClean, cleanZonePreset, selected]); - - const body = React.useMemo(() => { - if (zonePresetsLoading) { - return ( - - - - ); - } - - if (errorLoadingZonePresets || zonePresets === undefined) { - return ( - - - Error loading {Capability.ZoneCleaning} - - - ); - } - - return ( - <> - - - - {!canClean && selected !== "" && ( - Can only start cleaning when idle - )} - - - - - - - - - ); - }, [ - canClean, - handleChange, - handleClean, - cleanZonePresetExecuting, - errorLoadingZonePresets, - zonePresetsLoading, - selected, - zonePresets, - ]); - - return ( - - - - - Clean zone preset - - {body} - - - - ); -}; -export default ZonePresets; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index f7fabd9f..e5f43f54 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,6 +1,9 @@ -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import App from "./App"; -ReactDOM.render(, document.getElementById("root")); +// @ts-ignore +const root = createRoot(document.getElementById("root")); + +root.render(); diff --git a/frontend/src/map/EditMap.tsx b/frontend/src/map/EditMap.tsx index fa720a04..f83e2597 100644 --- a/frontend/src/map/EditMap.tsx +++ b/frontend/src/map/EditMap.tsx @@ -108,25 +108,20 @@ class EditMap extends Map { } - protected updateState(mode? : mode) : void { - const segmentNames = {} as Record; - const selectedSegmentIds = [] as Array; + protected updateState() : void { + super.updateState(); + const segmentNames = {} as Record; this.structureManager.getMapStructures().forEach(s => { if (s.type === SegmentLabelMapStructure.TYPE) { const label = s as SegmentLabelMapStructure; - if (label.selected) { - selectedSegmentIds.push(label.id); - - segmentNames[label.id] = label.name ?? label.id; - } + segmentNames[label.id] = label.name ?? label.id; } }); this.setState({ - selectedSegmentIds: selectedSegmentIds, segmentNames: segmentNames, cuttingLine: this.structureManager.getClientStructures().find(s => { if (s.type === CuttingLineClientStructure.TYPE) { diff --git a/frontend/src/map/LiveMap.tsx b/frontend/src/map/LiveMap.tsx index f8a71da8..84cb9d97 100644 --- a/frontend/src/map/LiveMap.tsx +++ b/frontend/src/map/LiveMap.tsx @@ -1,4 +1,4 @@ -import Map, {MapProps, MapState} from "./Map"; +import Map, {MapProps, MapState, usePendingMapAction} from "./Map"; import {Capability} from "../api"; import GoToTargetClientStructure from "./structures/client_structures/GoToTargetClientStructure"; import LocateAction from "./actions/live_map_actions/LocateAction"; @@ -8,6 +8,7 @@ import SegmentLabelMapStructure from "./structures/map_structures/SegmentLabelMa import ZoneActions from "./actions/live_map_actions/ZoneActions"; import ZoneClientStructure from "./structures/client_structures/ZoneClientStructure"; import GoToActions from "./actions/live_map_actions/GoToActions"; +import {TapTouchHandlerEvent} from "./utils/touch_handling/events/TapTouchHandlerEvent"; interface LiveMapProps extends MapProps { supportedCapabilities: { @@ -35,20 +36,9 @@ class LiveMap extends Map { } protected updateState() : void { - this.setState({ - selectedSegmentIds: this.structureManager.getMapStructures().filter(s => { - if (s.type === SegmentLabelMapStructure.TYPE) { - const label = s as SegmentLabelMapStructure; - - return label.selected; - } else { - return false; - } - }).map(s => { - const label = s as SegmentLabelMapStructure; + super.updateState(); - return label.id; - }), + this.setState({ zones: this.structureManager.getClientStructures().filter(s => { return s.type === ZoneClientStructure.TYPE; }) as Array, @@ -59,17 +49,13 @@ class LiveMap extends Map { } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected onTap(evt: any): boolean | void { + protected onTap(evt: TapTouchHandlerEvent): boolean | void { if (super.onTap(evt)) { return; } - if (this.canvas === null || this.ctx === null) { - return; - } - const {x, y} = Map.relativeCoordinates(evt.tappedCoordinates, this.canvas); - const tappedPointInMapSpace = this.ctx.transformedPoint(x, y); + const {x, y} = this.relativeCoordinatesToCanvas(evt.x0, evt.y0); + const tappedPointInMapSpace = this.ctxWrapper.mapPointToCurrentTransform(x, y); if (this.props.supportedCapabilities[Capability.GoToLocation]) { @@ -88,6 +74,20 @@ class LiveMap extends Map { } } + componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { + super.componentDidUpdate(prevProps, prevState); + + if ( + this.state.selectedSegmentIds.length > 0 || + this.state.zones.length > 0 || + this.state.goToTarget !== undefined + ) { + usePendingMapAction.setState({hasPendingMapAction: true}); + } else { + usePendingMapAction.setState({hasPendingMapAction: false}); + } + } + protected renderAdditionalElements(): JSX.Element { return <> { diff --git a/frontend/src/map/LiveMapPage.tsx b/frontend/src/map/LiveMapPage.tsx index 4dd73380..42016645 100644 --- a/frontend/src/map/LiveMapPage.tsx +++ b/frontend/src/map/LiveMapPage.tsx @@ -1,5 +1,5 @@ import {Box, Button, CircularProgress, styled, Typography, useTheme} from "@mui/material"; -import {Capability, useRobotMapQuery} from "../api"; +import {Capability, useMapSegmentationPropertiesQuery, useRobotMapQuery} from "../api"; import LiveMap from "./LiveMap"; import {useCapabilitiesSupported} from "../CapabilitiesProvider"; @@ -35,6 +35,11 @@ const LiveMapPage = (props: Record ): JSX.Element => { Capability.Locate ); + const { + data: mapSegmentationProperties, + isLoading: mapSegmentationPropertiesLoading + } = useMapSegmentationPropertiesQuery(mapSegmentationCapabilitySupported); + const theme = useTheme(); if (mapLoadError) { @@ -51,7 +56,10 @@ const LiveMapPage = (props: Record ): JSX.Element => { ); } - if (!mapData && mapIsLoading) { + if ( + (!mapData && mapIsLoading) || + (mapSegmentationCapabilitySupported && !mapSegmentationProperties && mapSegmentationPropertiesLoading) + ) { return ( @@ -70,6 +78,7 @@ const LiveMapPage = (props: Record ): JSX.Element => { return } +export const usePendingMapAction = create<{ + hasPendingMapAction: boolean +}>()(() => { + return { + hasPendingMapAction: false + }; +}); + const Container = styled(Box)({ position: "relative", height: "100%", @@ -34,8 +53,8 @@ class Map extends React.Component

{ protected readonly canvasRef: React.RefObject; protected structureManager: StructureManager; protected mapLayerRenderer: MapLayerRenderer; - protected ctx: any; - protected canvas: HTMLCanvasElement | null; + protected canvas!: HTMLCanvasElement; + protected ctxWrapper!: Canvas2DContextTrackingWrapper; protected readonly resizeListener: () => void; protected readonly visibilityStateChangeListener: () => void; @@ -74,114 +93,105 @@ class Map extends React.Component

{ // Save the current transformation and recreate it // as the transformation state is lost when changing canvas size // https://stackoverflow.com/questions/48044951/canvas-state-lost-after-changing-size - if (this.ctx !== null && this.canvas !== null) { - const {a, b, c, d, e, f} = this.ctx.getTransform(); + const {a, b, c, d, e, f} = this.ctxWrapper.getTransform(); - //Ignore weirdness related to the URL bar on Firefox mobile - if (this.canvas.clientWidth === 0 || this.canvas.clientHeight === 0) { - return; - } + //Ignore weirdness related to the URL bar on Firefox mobile + if (this.canvas.clientWidth === 0 || this.canvas.clientHeight === 0) { + return; + } - this.canvas.height = this.canvas.clientHeight; - this.canvas.width = this.canvas.clientWidth; + this.canvas.height = this.canvas.clientHeight; + this.canvas.width = this.canvas.clientWidth; - this.ctx.setTransform(a, b, c, d, e, f); - this.ctx.imageSmoothingEnabled = false; - } + this.ctxWrapper.setTransform(a, b, c, d, e, f); this.draw(); }; this.visibilityStateChangeListener = () => { - if (document.visibilityState === "visible") { - this.draw(); + if (this.pendingInternalDrawableStateUpdate && document.visibilityState === "visible") { + this.pendingInternalDrawableStateUpdate = false; + + this.updateInternalDrawableState(); } }; - - this.canvas = null; - this.ctx = null; } componentDidMount(): void { - if (this.canvasRef.current !== null) { - this.canvas = this.canvasRef.current; - this.canvas.height = this.canvas.clientHeight; - this.canvas.width = this.canvas.clientWidth; + this.canvas = this.canvasRef.current!; + this.canvas.height = this.canvas.clientHeight; + this.canvas.width = this.canvas.clientWidth; - this.ctx = this.canvasRef.current.getContext("2d"); + this.ctxWrapper = new Canvas2DContextTrackingWrapper(this.canvas.getContext("2d")!); - if (this.ctx === null) { - return; + this.registerCanvasInteractionHandlers(); + window.addEventListener("resize", this.resizeListener); + document.addEventListener("visibilitychange", this.visibilityStateChangeListener); + + const boundingBox = { + minX: this.props.rawMap.size.x / this.props.rawMap.pixelSize, + minY: this.props.rawMap.size.y / this.props.rawMap.pixelSize, + maxX: 0, + maxY: 0 + }; + + this.props.rawMap.layers.forEach(l => { + if (l.dimensions.x.min < boundingBox.minX) { + boundingBox.minX = l.dimensions.x.min; } - trackTransforms(this.ctx); - this.registerCanvasInteractionHandlers(); - window.addEventListener("resize", this.resizeListener); - document.addEventListener("visibilitychange", this.visibilityStateChangeListener); - - this.ctx.imageSmoothingEnabled = false; - - const boundingBox = { - minX: this.props.rawMap.size.x / this.props.rawMap.pixelSize, - minY: this.props.rawMap.size.y / this.props.rawMap.pixelSize, - maxX: 0, - maxY: 0 - }; - - this.props.rawMap.layers.forEach(l => { - if (l.dimensions.x.min < boundingBox.minX) { - boundingBox.minX = l.dimensions.x.min; - } - if (l.dimensions.y.min < boundingBox.minY) { - boundingBox.minY = l.dimensions.y.min; - } - if (l.dimensions.x.max > boundingBox.maxX) { - boundingBox.maxX = l.dimensions.x.max; - } - if (l.dimensions.y.max > boundingBox.maxY) { - boundingBox.maxY = l.dimensions.y.max; - } - }); + if (l.dimensions.y.min < boundingBox.minY) { + boundingBox.minY = l.dimensions.y.min; + } + if (l.dimensions.x.max > boundingBox.maxX) { + boundingBox.maxX = l.dimensions.x.max; + } + if (l.dimensions.y.max > boundingBox.maxY) { + boundingBox.maxY = l.dimensions.y.max; + } + }); - const initialScalingFactor = Math.min( - this.canvas.width / ((boundingBox.maxX - boundingBox.minX)*1.1), - this.canvas.height / ((boundingBox.maxY - boundingBox.minY)*1.1) - ); + const initialScalingFactor = Math.min( + this.canvas.width / ((boundingBox.maxX - boundingBox.minX)*1.1), + this.canvas.height / ((boundingBox.maxY - boundingBox.minY)*1.1) + ); - const initialxOffset = (this.canvas.width - (boundingBox.maxX - boundingBox.minX)*initialScalingFactor) / 2; - const initialyOffset = (this.canvas.height - (boundingBox.maxY - boundingBox.minY)*initialScalingFactor) / 2; - this.ctx.translate(initialxOffset, initialyOffset); + const initialxOffset = (this.canvas.width - (boundingBox.maxX - boundingBox.minX)*initialScalingFactor) / 2; + const initialyOffset = (this.canvas.height - (boundingBox.maxY - boundingBox.minY)*initialScalingFactor) / 2; + this.ctxWrapper.translate(initialxOffset, initialyOffset); - this.currentScaleFactor = initialScalingFactor; + this.currentScaleFactor = initialScalingFactor; - this.ctx.scale(initialScalingFactor, initialScalingFactor); - this.ctx.translate(-boundingBox.minX, -boundingBox.minY); + this.ctxWrapper.scale(initialScalingFactor, initialScalingFactor); + this.ctxWrapper.translate(-boundingBox.minX, -boundingBox.minY); - this.updateDrawableComponents().then(() => { - this.draw(); - }); - } + this.updateInternalDrawableState(); + + usePendingMapAction.setState({hasPendingMapAction: false}); } componentDidUpdate(prevProps: Readonly, prevState: Readonly): void { - //As react-query refreshes the data when switching back to a previously invisible tab anyways, - //we can just ignore all updates while minimized/in the background to 🌈 conserve energy 🌈 - if (document.visibilityState === "visible") { - if (prevProps.rawMap.metaData.nonce !== this.props.rawMap.metaData.nonce) { - this.onMapUpdate(); - - //Postpone data update if the map is currently being interacted with to avoid jank - if (this.activeTouchEvent || this.activeScrollEvent) { - this.pendingInternalDrawableStateUpdate = true; - } else { - this.updateInternalDrawableState(); - } - } else if (this.props.theme.palette.mode !== prevProps.theme.palette.mode) { + if (prevProps.rawMap.metaData.nonce !== this.props.rawMap.metaData.nonce) { + this.onMapUpdate(); + + /** + * If we're not visible, we do not need to render map updates as no one would see those anyway + * We also cannot update the map data while someone interacts with it as that causes jank + */ + if ( + document.visibilityState !== "visible" || + this.activeTouchEvent || + this.activeScrollEvent + ) { + this.pendingInternalDrawableStateUpdate = true; + } else { this.updateInternalDrawableState(); } + } else if (this.props.theme.palette.mode !== prevProps.theme.palette.mode) { + this.updateInternalDrawableState(); } } @@ -192,6 +202,8 @@ class Map extends React.Component

{ componentWillUnmount(): void { window.removeEventListener("resize", this.resizeListener); document.removeEventListener("visibilitychange", this.visibilityStateChangeListener); + + usePendingMapAction.setState({hasPendingMapAction: false}); } protected updateInternalDrawableState() : void { @@ -205,7 +217,14 @@ class Map extends React.Component

{ render(): JSX.Element { return ( - + {this.renderAdditionalElements()} ); @@ -223,15 +242,15 @@ class Map extends React.Component

{ await this.mapLayerRenderer.draw(this.props.rawMap, this.props.theme); this.drawableComponents.push(this.mapLayerRenderer.getCanvas()); - const pathsImage = await PathDrawer.drawPaths( - this.props.rawMap.entities.filter(e => { + const pathsImage = await PathDrawer.drawPaths( { + paths: this.props.rawMap.entities.filter(e => { return e.type === RawMapEntityType.Path || e.type === RawMapEntityType.PredictedPath; }), - this.props.rawMap.size.x, - this.props.rawMap.size.y, - this.props.rawMap.pixelSize, - this.props.theme - ); + mapWidth: this.props.rawMap.size.x, + mapHeight: this.props.rawMap.size.y, + pixelSize: this.props.rawMap.pixelSize, + paletteMode: this.props.theme.palette.mode, + }); this.drawableComponents.push(pathsImage); @@ -244,24 +263,44 @@ class Map extends React.Component

{ resolve(); }); }); - } protected updateState() : void { - this.setState({ - selectedSegmentIds: this.structureManager.getMapStructures().filter(s => { - if (s.type === SegmentLabelMapStructure.TYPE) { - const label = s as SegmentLabelMapStructure; + const currentSegmentLabelStructures = this.structureManager.getMapStructures().filter(s => { + return s.type === SegmentLabelMapStructure.TYPE; + }) as Array; + + const previouslySelectedSegmentIds = this.state.selectedSegmentIds; + const currentlySelectedSegmentIds = currentSegmentLabelStructures.filter(s => { + return s.selected; + }).map(s => { + return s.id; + }); + + // This ensures that we keep the order in which segments were selected by the user + const updatedSelectedSegmentIds = [ + ...previouslySelectedSegmentIds.filter(id => { //Take existing ones excluding those, which aren't selected anymore + return currentlySelectedSegmentIds.includes(id); + }), + ...currentlySelectedSegmentIds.filter(id => { //Append all IDs that weren't part of the previous array + return !previouslySelectedSegmentIds.includes(id); + }) + ]; - return label.selected; + if (this.props.trackSegmentSelectionOrder === true) { + currentSegmentLabelStructures.forEach(s => { + const idx = updatedSelectedSegmentIds.indexOf(s.id); + + if (idx >= 0) { + s.topLabel = convertNumberToRoman(idx + 1); } else { - return false; + s.topLabel = undefined; } - }).map(s => { - const label = s as SegmentLabelMapStructure; + }); + } - return label.id; - }) + this.setState({ + selectedSegmentIds: updatedSelectedSegmentIds, } as S & MapState); } @@ -269,20 +308,22 @@ class Map extends React.Component

{ protected draw() : void { window.requestAnimationFrame(() => { this.drawableComponentsMutex.take(() => { - if (!this.ctx || !this.canvas) { - this.drawableComponentsMutex.leave(); - return; - } + const ctx = this.ctxWrapper.getContext(); + + this.ctxWrapper.save(); + this.ctxWrapper.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + this.ctxWrapper.restore(); + - this.ctx.save(); - this.ctx.setTransform(1, 0, 0, 1, 0, 0); - this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - this.ctx.restore(); + ctx.imageSmoothingEnabled = false; this.drawableComponents.forEach(c => { - this.ctx.drawImage(c, 0, 0); + ctx.drawImage(c, 0, 0); }); + ctx.imageSmoothingEnabled = true; + /** * Carries out a drawing routine on the canvas with resetting the scaling / translation of the canvas @@ -290,13 +331,13 @@ class Map extends React.Component

{ * This allows for drawing equally thick lines no matter what the zoomlevel of the canvas currently is. * */ - const transformationMatrixToScreenSpace = this.ctx.getTransform(); - this.ctx.save(); - this.ctx.setTransform(1, 0, 0, 1, 0, 0); + const transformationMatrixToScreenSpace = this.ctxWrapper.getTransform(); + this.ctxWrapper.save(); + this.ctxWrapper.setTransform(1, 0, 0, 1, 0, 0); this.structureManager.getMapStructures().forEach(s => { s.draw( - this.ctx, + this.ctxWrapper, transformationMatrixToScreenSpace, this.currentScaleFactor, this.structureManager.getPixelSize() @@ -305,41 +346,28 @@ class Map extends React.Component

{ this.structureManager.getClientStructures().forEach(s => { s.draw( - this.ctx, + this.ctxWrapper, transformationMatrixToScreenSpace, this.currentScaleFactor, this.structureManager.getPixelSize() ); }); - this.ctx.restore(); + this.ctxWrapper.restore(); this.drawableComponentsMutex.leave(); }); }); } - protected getCurrentViewportCenterCoordinatesInPixelSpace() : {x: number, y: number} { - if (this.canvas === null) { - // This will actually never happen, but typescript thinks that this.canvas can be null, so.. - return { - x: (this.props.rawMap.size.x / this.props.rawMap.pixelSize) /2, - y: (this.props.rawMap.size.y / this.props.rawMap.pixelSize) /2 - }; - } else { - return this.ctx.transformedPoint(this.canvas.width/2, this.canvas.height/2); - } + protected getCurrentViewportCenterCoordinatesInPixelSpace() : PointCoordinates { + return this.ctxWrapper.mapPointToCurrentTransform(this.canvas.width/2, this.canvas.height/2); } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected onTap(evt: any) : boolean | void { - if (this.canvas === null || this.ctx === null) { - return; - } - - const currentTransform = this.ctx.getTransform(); + protected onTap(evt: TapTouchHandlerEvent) : boolean | void { + const currentTransform = this.ctxWrapper.getTransform(); - const {x, y} = Map.relativeCoordinates(evt.tappedCoordinates, this.canvas); - const tappedPointInMapSpace = this.ctx.transformedPoint(x, y); + const {x, y} = this.relativeCoordinatesToCanvas(evt.x0, evt.y0); + const tappedPointInMapSpace = this.ctxWrapper.mapPointToCurrentTransform(x, y); const tappedPointInScreenSpace = new DOMPoint(tappedPointInMapSpace.x, tappedPointInMapSpace.y).matrixTransform(currentTransform); let drawRequested = false; @@ -412,10 +440,6 @@ class Map extends React.Component

{ } protected onScroll(evt: WheelEvent) : void { - if (this.canvas === null || this.ctx === null) { - return; - } - this.activeScrollEvent = true; if (this.scrollTimeout) { clearTimeout(this.scrollTimeout); @@ -433,7 +457,7 @@ class Map extends React.Component

{ const fullStep = evt.deltaY < 0 ? SCROLL_PARAMETERS.ZOOM_IN_MULTIPLIER : SCROLL_PARAMETERS.ZOOM_OUT_MULTIPLIER; const factor = 1 - (fullStep * (evt.deltaY / SCROLL_PARAMETERS.PIXELS_PER_FULL_STEP)); - const currentScaleFactor = this.ctx.getScaleFactor2d()[0]; + const { scaleX: currentScaleFactor } = this.ctxWrapper.getScaleFactor(); if ( (factor * currentScaleFactor < 0.4 && factor < 1) || @@ -442,12 +466,12 @@ class Map extends React.Component

{ return; } - const pt = this.ctx.transformedPoint(evt.offsetX, evt.offsetY); - this.ctx.translate(pt.x, pt.y); - this.ctx.scale(factor, factor); - this.ctx.translate(-pt.x, -pt.y); + const pt = this.ctxWrapper.mapPointToCurrentTransform(evt.offsetX, evt.offsetY); + this.ctxWrapper.translate(pt.x, pt.y); + this.ctxWrapper.scale(factor, factor); + this.ctxWrapper.translate(-pt.x, -pt.y); - const [scaleX] = this.ctx.getScaleFactor2d(); + const { scaleX } = this.ctxWrapper.getScaleFactor(); this.currentScaleFactor = scaleX; this.draw(); @@ -455,26 +479,17 @@ class Map extends React.Component

{ return evt.preventDefault(); } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected startTranslate(evt: any) : void { - if (this.canvas === null || this.ctx === null) { - return; - } - const {x, y} = Map.relativeCoordinates(evt.coordinates, this.canvas); + protected startTranslate(evt: PanStartTouchHandlerEvent) : void { + const {x, y} = this.relativeCoordinatesToCanvas(evt.x0, evt.y0); this.touchHandlingState.lastX = x; this.touchHandlingState.lastY = y; - this.touchHandlingState.dragStart = this.ctx.transformedPoint(this.touchHandlingState.lastX, this.touchHandlingState.lastY); + this.touchHandlingState.dragStart = this.ctxWrapper.mapPointToCurrentTransform(this.touchHandlingState.lastX, this.touchHandlingState.lastY); this.activeTouchEvent = true; } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected moveTranslate(evt: any) : void { - if (this.canvas === null || this.ctx === null) { - return; - } - - const {x, y} = Map.relativeCoordinates(evt.currentCoordinates, this.canvas); + protected moveTranslate(evt: PanMoveTouchHandlerEvent) : void { + const {x, y} = this.relativeCoordinatesToCanvas(evt.x1,evt.y1); const oldX = this.touchHandlingState.lastX; const oldY = this.touchHandlingState.lastY; this.touchHandlingState.lastX = x; @@ -482,9 +497,9 @@ class Map extends React.Component

{ if (this.touchHandlingState.dragStart) { - const currentTransform = this.ctx.getTransform(); + const currentTransform = this.ctxWrapper.getTransform(); const currentPixelSize = this.structureManager.getPixelSize(); - const invertedCurrentTransform = DOMMatrix.fromMatrix(this.ctx.getTransform()).invertSelf(); + const invertedCurrentTransform = DOMMatrix.fromMatrix(this.ctxWrapper.getTransform()).invertSelf(); const wasHandled = this.structureManager.getClientStructures().some(structure => { const result = structure.translate( @@ -516,14 +531,13 @@ class Map extends React.Component

{ } // If no location stopped event handling -> pan the whole map - const pt = this.ctx.transformedPoint(this.touchHandlingState.lastX, this.touchHandlingState.lastY); - this.ctx.translate(pt.x - this.touchHandlingState.dragStart.x, pt.y - this.touchHandlingState.dragStart.y); + const pt = this.ctxWrapper.mapPointToCurrentTransform(this.touchHandlingState.lastX, this.touchHandlingState.lastY); + this.ctxWrapper.translate(pt.x - this.touchHandlingState.dragStart.x, pt.y - this.touchHandlingState.dragStart.y); this.draw(); } } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected endTranslate(evt: any) : void { + protected endTranslate(evt: PanEndTouchHandlerEvent | PinchEndTouchHandlerEvent) : void { this.activeTouchEvent = false; this.touchHandlingState.dragStart = null; @@ -545,39 +559,19 @@ class Map extends React.Component

{ } } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected startPinch(evt: any) : void { - if (this.canvas === null || this.ctx === null) { - return; - } + protected startPinch(evt: PinchStartTouchHandlerEvent) : void { this.touchHandlingState.lastScaleFactor = 1; // translate - const {x, y} = Map.relativeCoordinates(evt.center, this.canvas); + const {x, y} = this.relativeCoordinatesToCanvas(evt.x0, evt.y0); this.touchHandlingState.lastX = x; this.touchHandlingState.lastY = y; - this.touchHandlingState.dragStart = this.ctx.transformedPoint(this.touchHandlingState.lastX, this.touchHandlingState.lastY); + this.touchHandlingState.dragStart = this.ctxWrapper.mapPointToCurrentTransform(this.touchHandlingState.lastX, this.touchHandlingState.lastY); this.activeTouchEvent = true; } - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected endPinch(evt: any) : void { - if (this.canvas === null || this.ctx === null) { - return; - } - - const [scaleX] = this.ctx.getScaleFactor2d(); - this.currentScaleFactor = scaleX; - this.endTranslate(evt); - } - - //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected scalePinch(evt: any) : any { - if (this.canvas === null || this.ctx === null) { - return; - } - - const currentScaleFactor = this.ctx.getScaleFactor2d()[0]; + protected scalePinch(evt: PinchMoveTouchHandlerEvent) : any { + const { scaleX: currentScaleFactor } = this.ctxWrapper.getScaleFactor(); const factor = evt.scale / this.touchHandlingState.lastScaleFactor; if (factor * currentScaleFactor < 0.4 && factor < 1) { @@ -588,40 +582,57 @@ class Map extends React.Component

{ this.touchHandlingState.lastScaleFactor = evt.scale; - const pt = this.ctx.transformedPoint(evt.center.x, evt.center.y); - this.ctx.translate(pt.x, pt.y); - this.ctx.scale(factor, factor); - this.ctx.translate(-pt.x, -pt.y); + const pt = this.ctxWrapper.mapPointToCurrentTransform(evt.x0, evt.y0); + this.ctxWrapper.translate(pt.x, pt.y); + this.ctxWrapper.scale(factor, factor); + this.ctxWrapper.translate(-pt.x, -pt.y); // translate - const {x, y} = Map.relativeCoordinates(evt.center, this.canvas); + const {x, y} = this.relativeCoordinatesToCanvas(evt.x0, evt.y0); this.touchHandlingState.lastX = x; this.touchHandlingState.lastY = y; - const p = this.ctx.transformedPoint(this.touchHandlingState.lastX, this.touchHandlingState.lastY); - this.ctx.translate(p.x - this.touchHandlingState.dragStart.x, p.y - this.touchHandlingState.dragStart.y); + const p = this.ctxWrapper.mapPointToCurrentTransform(this.touchHandlingState.lastX, this.touchHandlingState.lastY); + this.ctxWrapper.translate(p.x - this.touchHandlingState.dragStart.x, p.y - this.touchHandlingState.dragStart.y); this.draw(); } - protected registerCanvasInteractionHandlers(): void { - if (this.canvas === null || this.ctx === null) { - return; - } + protected endPinch(evt: PinchEndTouchHandlerEvent) : void { + const { scaleX } = this.ctxWrapper.getScaleFactor(); + this.currentScaleFactor = scaleX; + this.endTranslate(evt); + } - const touchHandler = new TouchHandler(); - touchHandler.registerListeners(this.canvas); + protected registerCanvasInteractionHandlers(): void { + const touchHandler = new TouchHandler(this.canvas); this.touchHandlingState.lastX = this.canvas.width / 2; this.touchHandlingState.lastY = this.canvas.height / 2; - this.canvas.addEventListener("tap", this.onTap.bind(this)); - this.canvas.addEventListener("panstart", this.startTranslate.bind(this)); - this.canvas.addEventListener("panmove", this.moveTranslate.bind(this)); - this.canvas.addEventListener("panend", this.endTranslate.bind(this)); - this.canvas.addEventListener("pinchstart", this.startPinch.bind(this)); - this.canvas.addEventListener("pinchmove", this.scalePinch.bind(this)); - this.canvas.addEventListener("pinchend", this.endPinch.bind(this)); + touchHandler.addEventListener(TapTouchHandlerEvent.TYPE, evt => { + this.onTap(evt as TapTouchHandlerEvent); + }); + + touchHandler.addEventListener(PanStartTouchHandlerEvent.TYPE, evt => { + this.startTranslate(evt as PanStartTouchHandlerEvent); + }); + touchHandler.addEventListener(PanMoveTouchHandlerEvent.TYPE, evt => { + this.moveTranslate(evt as PanMoveTouchHandlerEvent); + }); + touchHandler.addEventListener(PanEndTouchHandlerEvent.TYPE, evt => { + this.endTranslate(evt as PanEndTouchHandlerEvent); + }); + + touchHandler.addEventListener(PinchStartTouchHandlerEvent.TYPE, evt => { + this.startPinch(evt as PinchStartTouchHandlerEvent); + }); + touchHandler.addEventListener(PinchMoveTouchHandlerEvent.TYPE, evt => { + this.scalePinch(evt as PinchMoveTouchHandlerEvent); + }); + touchHandler.addEventListener(PinchEndTouchHandlerEvent.TYPE, evt => { + this.endPinch(evt as PinchEndTouchHandlerEvent); + }); //Order might be important here but I've never tested that this.canvas.addEventListener("wheel", this.onScroll.bind(this), false); @@ -630,13 +641,13 @@ class Map extends React.Component

{ /** * Helper function for calculating coordinates relative to an HTML Element * - * @param {{x: number, y: number}} "{x, y}" - the absolute screen coordinates (clicked) - * @param {*} referenceElement - the element (e.g. a canvas) to which - * relative coordinates should be calculated - * @returns {{x: number, y: number}} coordinates relative to the referenceElement + * @param {number} x absolute screen coordinates x + * @param {number} y absolute screen coordinates y + * + * @returns {{x: number, y: number}} coordinates relative to the canvas element */ - protected static relativeCoordinates({x, y}: {x: number, y:number}, referenceElement: HTMLElement) : {x: number, y: number} { - const rect = referenceElement.getBoundingClientRect(); + protected relativeCoordinatesToCanvas(x: number, y:number) : PointCoordinates { + const rect = this.canvas.getBoundingClientRect(); return { x: x - rect.left, y: y - rect.top diff --git a/frontend/src/map/MapLayerRenderUtils.ts b/frontend/src/map/MapLayerRenderUtils.ts new file mode 100644 index 00000000..1b323607 --- /dev/null +++ b/frontend/src/map/MapLayerRenderUtils.ts @@ -0,0 +1,67 @@ +import {RawMapLayer} from "../api"; +import {FourColorTheoremSolver} from "./utils/colors/FourColorTheoremSolver"; + +export type RGBColor = { + r: number; + g: number; + b: number; +} + +export type LayerColors = { + floor: RGBColor; + wall: RGBColor; + segments: RGBColor[]; +}; + +export function RENDER_LAYERS_TO_IMAGEDATA(layers: Array, pixelSize: number, width: number, height: number, colorsToUse: LayerColors) { + const imageData = new ImageData( + new Uint8ClampedArray( width * height * 4 ), + width, + height + ); + + const colorFinder = new FourColorTheoremSolver(layers, pixelSize); + + [...layers].sort((a,b) => { + return TYPE_SORT_MAPPING[a.type] - TYPE_SORT_MAPPING[b.type]; + }).forEach(layer => { + let color; + + switch (layer.type) { + case "floor": + color = colorsToUse.floor; + break; + case "wall": + color = colorsToUse.wall; + break; + case "segment": + color = colorsToUse.segments[colorFinder.getColor((layer.metaData.segmentId ?? ""))]; + break; + } + + if (!color) { + // eslint-disable-next-line no-console + console.error(`Missing color for ${layer.type} with segment id '${layer.metaData.segmentId}'.`); + color = {r: 128, g: 128, b: 128}; + } + + for (let i = 0; i < layer.pixels.length; i = i + 2) { + const imgDataOffset = (layer.pixels[i] + layer.pixels[i+1] * width) * 4; + + imageData.data[imgDataOffset] = color.r; + imageData.data[imgDataOffset + 1] = color.g; + imageData.data[imgDataOffset + 2] = color.b; + imageData.data[imgDataOffset + 3] = 255; + } + }); + + return imageData; +} + +// This is important because it determines the draw order +const TYPE_SORT_MAPPING = { + "floor": 14, + "segment": 15, + "wall": 16 +}; + diff --git a/frontend/src/map/MapLayerRenderer.ts b/frontend/src/map/MapLayerRenderer.ts index c830f80c..98e98ddb 100644 --- a/frontend/src/map/MapLayerRenderer.ts +++ b/frontend/src/map/MapLayerRenderer.ts @@ -1,13 +1,9 @@ import {RawMapData} from "../api"; -import {FourColorTheoremSolver} from "./utils/map-color-finder"; import {Theme} from "@mui/material"; import {adjustColorBrightness} from "../utils"; +import {RGBColor, LayerColors, RENDER_LAYERS_TO_IMAGEDATA} from "./MapLayerRenderUtils"; + -type RGBColor = { - r: number; - g: number; - b: number; -} function hexToRgb(hex: string) : RGBColor { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim()); @@ -24,17 +20,17 @@ function hexToRgb(hex: string) : RGBColor { } export class MapLayerRenderer { - private canvas: HTMLCanvasElement; - private readonly ctx: CanvasRenderingContext2D | null; + private readonly canvas: HTMLCanvasElement; + private readonly ctx: CanvasRenderingContext2D; private width: number; private height: number; private mapLayerRenderWebWorker: Worker; private mapLayerRenderWebWorkerAvailable = false; - private pendingCallback: any; + private pendingCallback: (() => void) | undefined; private colors: { floor: string; wall: string; segments: string[] }; - private darkColors: { floor: RGBColor; wall: RGBColor; segments: RGBColor[] }; - private lightColors: { floor: RGBColor; wall: RGBColor; segments: RGBColor[] }; + private readonly darkColors: { floor: RGBColor; wall: RGBColor; segments: RGBColor[] }; + private readonly lightColors: { floor: RGBColor; wall: RGBColor; segments: RGBColor[] }; constructor() { this.width = 1; @@ -44,11 +40,7 @@ export class MapLayerRenderer { this.canvas.width = this.width; this.canvas.height = this.height; - this.ctx = this.canvas.getContext("2d"); - - if (this.ctx === null) { - throw new Error("Context is null"); - } + this.ctx = this.canvas.getContext("2d")!; this.colors = { floor:"#0076ff", @@ -78,7 +70,7 @@ export class MapLayerRenderer { }) }; - this.mapLayerRenderWebWorker = new Worker("mapLayerRenderWebWorker.js"); + this.mapLayerRenderWebWorker = new Worker(new URL("./MapLayerRenderer.worker", import.meta.url)); this.mapLayerRenderWebWorker.onerror = (ev => { // eslint-disable-next-line no-console @@ -89,22 +81,23 @@ export class MapLayerRenderer { this.mapLayerRenderWebWorker.onmessage = (evt) => { if (evt.data.pixels !== undefined) { - if (this.ctx !== null) { - const imageData = new ImageData( - new Uint8ClampedArray( evt.data.pixels ), - evt.data.width, - evt.data.height - ); + const imageData = new ImageData( + new Uint8ClampedArray(evt.data.pixels), + evt.data.width, + evt.data.height + ); - this.ctx.putImageData(imageData, 0, 0); + this.ctx.putImageData(imageData, 0, 0); - if (typeof this.pendingCallback === "function") { - this.pendingCallback(); - this.pendingCallback = undefined; - } + if (typeof this.pendingCallback === "function") { + this.pendingCallback(); + this.pendingCallback = undefined; } } else { if (evt.data.ready === true) { + // eslint-disable-next-line no-console + console.info("MapLayerRenderer.worker available"); + this.mapLayerRenderWebWorkerAvailable = true; return; @@ -116,7 +109,7 @@ export class MapLayerRenderer { } draw(data : RawMapData, theme: Theme): Promise { - let colorsToUse: { floor: RGBColor; wall: RGBColor; segments: RGBColor[]; }; + let colorsToUse: LayerColors; switch (theme.palette.mode) { case "light": @@ -128,10 +121,6 @@ export class MapLayerRenderer { } return new Promise((resolve, reject) => { - if (this.ctx === null) { - throw new Error("Context is null"); - } - //As the map data might change dimensions, we need to keep track of that. if ( this.canvas.width !== Math.round(data.size.x / data.pixelSize) || @@ -148,14 +137,14 @@ export class MapLayerRenderer { if (data.layers.length > 0) { if (this.mapLayerRenderWebWorkerAvailable) { this.mapLayerRenderWebWorker.postMessage( { - width: this.width, - height: this.height, mapLayers: data.layers, pixelSize: data.pixelSize, - colors: colorsToUse + width: this.width, + height: this.height, + colorsToUse: colorsToUse }); - //I'm not 100% sure if this cleanup is necessary but it should prevent eternally stuck promises + //I'm not 100% sure if this cleanup is necessary, but it should prevent eternally stuck promises if (typeof this.pendingCallback === "function") { this.pendingCallback(); this.pendingCallback = undefined; @@ -165,42 +154,13 @@ export class MapLayerRenderer { resolve(); }; } else { //Fallback if there's no worker for some reason - const imageData = this.ctx.createImageData(this.width,this.height); - - const colorFinder = new FourColorTheoremSolver(data.layers, data.pixelSize); - - [...data.layers].sort((a,b) => { - return TYPE_SORT_MAPPING[a.type] - TYPE_SORT_MAPPING[b.type]; - }).forEach(layer => { - let color; - - switch (layer.type) { - case "floor": - color = colorsToUse.floor; - break; - case "wall": - color = colorsToUse.wall; - break; - case "segment": - color = colorsToUse.segments[colorFinder.getColor((layer.metaData.segmentId ?? ""))]; - break; - } - - if (!color) { - //eslint-disable-next-line no-console - console.error(`Missing color for ${layer.type} with segment id '${layer.metaData.segmentId}'.`); - color = {r: 0, g: 0, b: 0}; - } - - for (let i = 0; i < layer.pixels.length; i = i + 2) { - const imgDataOffset = (layer.pixels[i] + layer.pixels[i+1] * this.width) * 4; - - imageData.data[imgDataOffset] = color.r; - imageData.data[imgDataOffset + 1] = color.g; - imageData.data[imgDataOffset + 2] = color.b; - imageData.data[imgDataOffset + 3] = 255; - } - }); + const imageData = RENDER_LAYERS_TO_IMAGEDATA( + data.layers, + data.pixelSize, + this.width, + this.height, + colorsToUse + ); this.ctx.putImageData(imageData, 0, 0); resolve(); @@ -216,10 +176,3 @@ export class MapLayerRenderer { } } -// This is important because it determines the draw order -const TYPE_SORT_MAPPING = { - "floor": 14, - "segment": 15, - "wall": 16 -}; - diff --git a/frontend/src/map/MapLayerRenderer.worker.ts b/frontend/src/map/MapLayerRenderer.worker.ts new file mode 100644 index 00000000..d50dfa5f --- /dev/null +++ b/frontend/src/map/MapLayerRenderer.worker.ts @@ -0,0 +1,32 @@ +import { RENDER_LAYERS_TO_IMAGEDATA } from "./MapLayerRenderUtils"; + +self.postMessage({ + ready: true +}); + +self.addEventListener( "message", ( evt ) => { + //According to SonarJS S2819, this might be problematic + //I honestly have no idea if this check is actually needed in a webworker context, but I'll do as the tool says. + if (evt.origin !== "") { + // eslint-disable-next-line no-console + console.warn(`Received event with unexpected origin "${evt.origin}"`); + + return; + } + + const imageData = RENDER_LAYERS_TO_IMAGEDATA( + evt.data.mapLayers, + evt.data.pixelSize, + evt.data.width, + evt.data.height, + evt.data.colorsToUse + ); + + self.postMessage( { + pixels: imageData.data.buffer, + width: evt.data.width, + height: evt.data.height, + }, { + transfer: [imageData.data.buffer] + }); +} ); diff --git a/frontend/src/map/PathDrawer.ts b/frontend/src/map/PathDrawer.ts index c374fcd0..2947a160 100644 --- a/frontend/src/map/PathDrawer.ts +++ b/frontend/src/map/PathDrawer.ts @@ -1,13 +1,22 @@ import {RawMapEntity, RawMapEntityType} from "../api"; -import {Theme} from "@mui/material"; +import {PaletteMode} from "@mui/material"; + +type PathDrawerOptions = { + paths: Array, + mapWidth: number, + mapHeight: number, + pixelSize: number, + paletteMode: PaletteMode, + width?: number +}; export class PathDrawer { - static drawPaths(paths: Array, mapWidth: number, mapHeight: number, pixelSize: number, theme: Theme) : Promise { + static drawPaths(options: PathDrawerOptions) : Promise { return new Promise((resolve, reject) => { const img = new Image(); - if (paths.length > 0) { - img.src = PathDrawer.createSVGDataUrlFromPaths(paths, mapWidth, mapHeight, pixelSize, theme); + if (options.paths.length > 0) { + img.src = PathDrawer.createSVGDataUrlFromPaths(options); img.decode().then(() => { resolve(img); @@ -20,11 +29,20 @@ export class PathDrawer { }); } - private static createSVGDataUrlFromPaths(paths: Array, mapWidth: number, mapHeight: number, pixelSize: number, theme : Theme) { + private static createSVGDataUrlFromPaths(options: PathDrawerOptions) { + const { + mapWidth, + mapHeight, + paletteMode, + paths, + pixelSize, + width + } = options; + let svg = ``; let pathColor : string; - switch (theme.palette.mode) { + switch (paletteMode) { case "light": pathColor = "#ffffff"; break; @@ -38,7 +56,8 @@ export class PathDrawer { path.points, path.type, pixelSize, - pathColor + pathColor, + width ); }); @@ -47,7 +66,14 @@ export class PathDrawer { return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`; } - private static createSVGPathFromPoints(points: Array, type: RawMapEntityType, pixelSize: number, color: string) { + private static createSVGPathFromPoints( + points: Array, + type: RawMapEntityType, + pixelSize: number, + color: string, + width?: number, + ) { + const pathWidth = width ?? 0.5; let svgPath = " { + constructor(props: MapProps) { + super(props); + + this.state = { + selectedSegmentIds: [], + helpDialogOpen: false + }; + } + + protected renderAdditionalElements(): JSX.Element { + return <> + { + this.setState({helpDialogOpen: open}); + }} + /> + + { + this.setState({helpDialogOpen: open}); + }} + helpText={this.props.helpText} + /> + ; + } + + protected updateDrawableComponents(): Promise { + return new Promise((resolve, reject) => { + this.drawableComponentsMutex.take(async () => { + this.drawableComponents = []; + + await this.mapLayerRenderer.draw(this.props.rawMap, this.props.theme); + this.drawableComponents.push(this.mapLayerRenderer.getCanvas()); + + const coveragePathImage = await PathDrawer.drawPaths( { + paths: this.props.rawMap.entities.filter(e => { + return e.type === RawMapEntityType.Path; + }), + mapWidth: this.props.rawMap.size.x, + mapHeight: this.props.rawMap.size.y, + pixelSize: this.props.rawMap.pixelSize, + paletteMode: this.props.theme.palette.mode === "dark" ? "light" : "dark", + width: 5 + }); + + this.drawableComponents.push(coveragePathImage); + + const pathsImage = await PathDrawer.drawPaths( { + paths: this.props.rawMap.entities.filter(e => { + return e.type === RawMapEntityType.Path || e.type === RawMapEntityType.PredictedPath; + }), + mapWidth: this.props.rawMap.size.x, + mapHeight: this.props.rawMap.size.y, + pixelSize: this.props.rawMap.pixelSize, + paletteMode: this.props.theme.palette.mode, + }); + + this.drawableComponents.push(pathsImage); + + this.structureManager.updateMapStructuresFromMapData(this.props.rawMap); + + // remove all segment labels + this.structureManager.getMapStructures().forEach(s => { + if (s.type === SegmentLabelMapStructure.TYPE) { + this.structureManager.removeMapStructure(s); + } + }); + + + this.updateState(); + + this.drawableComponentsMutex.leave(); + + resolve(); + }); + }); + } + + //eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + protected onTap(evt: any): boolean | void { + // Disable all interactions + return; + } +} + +export default RobotCoverageMap; diff --git a/frontend/src/map/RobotCoverageMapPage.tsx b/frontend/src/map/RobotCoverageMapPage.tsx new file mode 100644 index 00000000..d6ad3df6 --- /dev/null +++ b/frontend/src/map/RobotCoverageMapPage.tsx @@ -0,0 +1,78 @@ +import {Box, Button, CircularProgress, styled, Typography, useTheme} from "@mui/material"; +import { + useRobotMapQuery, + useRobotStatusQuery +} from "../api"; +import RobotCoverageMap from "./RobotCoverageMap"; +import {RobotCoverageMapHelp} from "./res/RobotCoverageMapHelp"; + + +const Container = styled(Box)({ + flex: "1", + height: "100%", + display: "flex", + flexFlow: "column", + justifyContent: "center", + alignItems: "center", +}); + +const RobotCoverageMapPage = (): JSX.Element => { + const { + data: mapData, + isLoading: mapIsLoading, + isError: mapLoadError, + refetch: refetchMap + } = useRobotMapQuery(); + const { + data: robotStatus, + isLoading: robotStatusLoading + } = useRobotStatusQuery(); + + const theme = useTheme(); + + if (mapLoadError) { + return ( + + Error loading map data + + + + ); + } + + if ((!mapData && mapIsLoading) || (!robotStatus && robotStatusLoading)) { + return ( + + + + ); + } + + if (!mapData) { + return ( + + No map data; + + ); + } + + if (!robotStatus) { + return ( + + No robot status; + + ); + } + + return ; +}; + +export default RobotCoverageMapPage; diff --git a/frontend/src/map/StructureManager.ts b/frontend/src/map/StructureManager.ts index e53d5428..d26a21aa 100644 --- a/frontend/src/map/StructureManager.ts +++ b/frontend/src/map/StructureManager.ts @@ -10,6 +10,7 @@ import NoMopAreaMapStructure from "./structures/map_structures/NoMopAreaMapStruc import VirtualWallMapStructure from "./structures/map_structures/VirtualWallMapStructure"; import GoToTargetMapStructure from "./structures/map_structures/GoToTargetMapStructure"; import {median} from "../utils"; +import {PointCoordinates} from "./utils/types"; class StructureManager { @@ -17,8 +18,6 @@ class StructureManager { private clientStructures: Array; private pixelSize = 5; - private oldSegmentLabelActiveMap: any = {}; - constructor() { this.mapStructures = []; this.clientStructures = []; @@ -33,47 +32,37 @@ class StructureManager { } updateMapStructuresFromMapData(rawMap: RawMapData): void { - this.oldSegmentLabelActiveMap = {}; - - this.mapStructures.forEach(s => { - if (s.type === SegmentLabelMapStructure.TYPE) { - const label = s as SegmentLabelMapStructure; - - this.oldSegmentLabelActiveMap[label.id] = label.selected; - } - }); - - this.mapStructures = []; - - - - this.updateMapStructuresFromEntityMapData(rawMap.entities); - this.updateMapStructuresFromLayerMapData(rawMap.layers); + this.mapStructures = [ + ...this.buildMapStructuresFromEntityMapData(rawMap.entities), + ...this.buildMapStructuresFromLayerMapData(rawMap.layers) + ]; this.mapStructures.sort((a,b) => { return TYPE_SORT_MAPPING[a.type] - TYPE_SORT_MAPPING[b.type]; }); } - private updateMapStructuresFromEntityMapData(entities: Array) { + private buildMapStructuresFromEntityMapData(entities: Array): Array { + const mapStructures: Array = []; + entities.forEach(e => { switch (e.type) { case RawMapEntityType.RobotPosition: { const p0 = this.convertCMCoordinatesToPixelSpace({x: e.points[0], y: e.points[1]}); - this.mapStructures.push(new RobotPositionMapStructure(p0.x, p0.y, e.metaData.angle ?? 0)); + mapStructures.push(new RobotPositionMapStructure(p0.x, p0.y, e.metaData.angle ?? 0)); break; } case RawMapEntityType.ChargerLocation: { const p0 = this.convertCMCoordinatesToPixelSpace({x: e.points[0], y: e.points[1]}); - this.mapStructures.push(new ChargerLocationMapStructure(p0.x, p0.y)); + mapStructures.push(new ChargerLocationMapStructure(p0.x, p0.y)); break; } case RawMapEntityType.GoToTarget: { const p0 = this.convertCMCoordinatesToPixelSpace({x: e.points[0], y: e.points[1]}); - this.mapStructures.push(new GoToTargetMapStructure(p0.x, p0.y)); + mapStructures.push(new GoToTargetMapStructure(p0.x, p0.y)); break; } case RawMapEntityType.ActiveZone: { @@ -82,7 +71,7 @@ class StructureManager { const p2 = this.convertCMCoordinatesToPixelSpace({x: e.points[4], y: e.points[5]}); const p3 = this.convertCMCoordinatesToPixelSpace({x: e.points[6], y: e.points[7]}); - this.mapStructures.push(new ActiveZoneMapStructure( + mapStructures.push(new ActiveZoneMapStructure( p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, @@ -96,7 +85,7 @@ class StructureManager { const p2 = this.convertCMCoordinatesToPixelSpace({x: e.points[4], y: e.points[5]}); const p3 = this.convertCMCoordinatesToPixelSpace({x: e.points[6], y: e.points[7]}); - this.mapStructures.push(new NoGoAreaMapStructure( + mapStructures.push(new NoGoAreaMapStructure( p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, @@ -110,7 +99,7 @@ class StructureManager { const p2 = this.convertCMCoordinatesToPixelSpace({x: e.points[4], y: e.points[5]}); const p3 = this.convertCMCoordinatesToPixelSpace({x: e.points[6], y: e.points[7]}); - this.mapStructures.push(new NoMopAreaMapStructure( + mapStructures.push(new NoMopAreaMapStructure( p0.x, p0.y, p1.x, p1.y, p2.x, p2.y, @@ -122,7 +111,7 @@ class StructureManager { const p0 = this.convertCMCoordinatesToPixelSpace({x: e.points[0], y: e.points[1]}); const p1 = this.convertCMCoordinatesToPixelSpace({x: e.points[2], y: e.points[3]}); - this.mapStructures.push(new VirtualWallMapStructure( + mapStructures.push(new VirtualWallMapStructure( p0.x, p0.y, p1.x, p1.y )); @@ -130,9 +119,23 @@ class StructureManager { } } }); + + return mapStructures; } - private updateMapStructuresFromLayerMapData(layers: Array) { + private buildMapStructuresFromLayerMapData(layers: Array): Array { + const mapStructures: Array = []; + const previouslySelectedSegmentLabelsMap: Record = {}; + + this.mapStructures.forEach(s => { + if (s.type === SegmentLabelMapStructure.TYPE) { + const label = s as SegmentLabelMapStructure; + + previouslySelectedSegmentLabelsMap[label.id] = label.selected; + } + }); + + layers.forEach(l => { switch (l.type) { case RawMapLayerType.Segment: { @@ -148,12 +151,12 @@ class StructureManager { Using the avg instead of the segment mid solves this partly, however it's still not perfect. - Calculating the median works even better but also requires more resources + Calculating the median works even better but also requires more resources, which is why it's not done by the backend. As end devices usually have much more ram to spare, we can easily do it here. - However to not waste CPU cycles for no benefit, we try to only do that - when the shape of the room is odd which can be detected by avg and mid + However, to not waste CPU cycles for no benefit, we try to only do that + when the shape of the room is odd, which can be detected by avg and mid diverging significantly >= 8 pixels is just guesswork here and might require additional tuning @@ -176,11 +179,11 @@ class StructureManager { coords.y = median(pixels.y); } - this.mapStructures.push(new SegmentLabelMapStructure( + mapStructures.push(new SegmentLabelMapStructure( coords.x, coords.y, l.metaData.segmentId ?? "", - !!this.oldSegmentLabelActiveMap[l.metaData.segmentId ?? ""], + !!previouslySelectedSegmentLabelsMap[l.metaData.segmentId ?? ""], !!l.metaData.active, l.metaData.area, l.metaData.name @@ -190,6 +193,8 @@ class StructureManager { } } }); + + return mapStructures; } removeMapStructure(structure: MapStructure): void { @@ -216,12 +221,12 @@ class StructureManager { }); } - convertCMCoordinatesToPixelSpace(coordinates: {x: number, y: number}) : {x: number, y: number} { + convertCMCoordinatesToPixelSpace(coordinates: PointCoordinates) : PointCoordinates { return {x: Math.floor(coordinates.x / this.pixelSize), y: Math.floor(coordinates.y / this.pixelSize)}; } - convertPixelCoordinatesToCMSpace(coordinates: {x: number, y: number}) : {x: number, y: number} { + convertPixelCoordinatesToCMSpace(coordinates: PointCoordinates) : PointCoordinates { return {x: Math.floor(coordinates.x * this.pixelSize), y: Math.floor(coordinates.y * this.pixelSize)}; } } diff --git a/frontend/src/map/actions/edit_map_actions/SegmentActions.tsx b/frontend/src/map/actions/edit_map_actions/SegmentActions.tsx index fb61d86b..84f312f3 100644 --- a/frontend/src/map/actions/edit_map_actions/SegmentActions.tsx +++ b/frontend/src/map/actions/edit_map_actions/SegmentActions.tsx @@ -19,6 +19,7 @@ import { } from "@mui/material"; import {ActionButton} from "../../Styled"; import CuttingLineClientStructure from "../../structures/client_structures/CuttingLineClientStructure"; +import {PointCoordinates} from "../../utils/types"; interface SegmentActionsProperties { robotStatus: StatusState, @@ -26,7 +27,7 @@ interface SegmentActionsProperties { segmentNames: Record; cuttingLine: CuttingLineClientStructure | undefined, - convertPixelCoordinatesToCMSpace(coordinates: {x: number, y: number}) : {x: number, y: number} + convertPixelCoordinatesToCMSpace(coordinates: PointCoordinates) : PointCoordinates supportedCapabilities: { [Capability.MapSegmentEdit]: boolean, @@ -111,7 +112,7 @@ const SegmentActions = ( renameSegment({ segment_id: selectedSegmentIds[0], - name: newSegmentName + name: newSegmentName.trim() }); }, [canEdit, selectedSegmentIds, newSegmentName, renameSegment]); diff --git a/frontend/src/map/actions/edit_map_actions/VirtualRestrictionActions.tsx b/frontend/src/map/actions/edit_map_actions/VirtualRestrictionActions.tsx index 3a18fac6..91c3d783 100644 --- a/frontend/src/map/actions/edit_map_actions/VirtualRestrictionActions.tsx +++ b/frontend/src/map/actions/edit_map_actions/VirtualRestrictionActions.tsx @@ -13,6 +13,7 @@ import VirtualWallClientStructure from "../../structures/client_structures/Virtu import NoGoAreaClientStructure from "../../structures/client_structures/NoGoAreaClientStructure"; import NoMopAreaClientStructure from "../../structures/client_structures/NoMopAreaClientStructure"; import RestrictedZoneClientStructure from "../../structures/client_structures/RestrictedZoneClientStructure"; +import {PointCoordinates} from "../../utils/types"; interface VirtualRestrictionActionsProperties { robotStatus: StatusState, @@ -20,7 +21,7 @@ interface VirtualRestrictionActionsProperties { noGoAreas: Array, noMopAreas: Array, - convertPixelCoordinatesToCMSpace(coordinates: {x: number, y: number}) : {x: number, y: number} + convertPixelCoordinatesToCMSpace(coordinates: PointCoordinates) : PointCoordinates onAddVirtualWall(): void, onAddNoGoArea(): void, diff --git a/frontend/src/map/actions/live_map_actions/GoToActions.tsx b/frontend/src/map/actions/live_map_actions/GoToActions.tsx index dee710d6..ad6e8985 100644 --- a/frontend/src/map/actions/live_map_actions/GoToActions.tsx +++ b/frontend/src/map/actions/live_map_actions/GoToActions.tsx @@ -6,11 +6,15 @@ import React from "react"; import {CircularProgress, Grid, Typography} from "@mui/material"; import {ActionButton} from "../../Styled"; import GoToTargetClientStructure from "../../structures/client_structures/GoToTargetClientStructure"; +import IntegrationHelpDialog from "../../../components/IntegrationHelpDialog"; +import {useLongPress} from "use-long-press"; +import {floorObject} from "../../../api/utils"; +import {PointCoordinates} from "../../utils/types"; interface GoToActionsProperties { goToTarget: GoToTargetClientStructure; - convertPixelCoordinatesToCMSpace(coordinates: {x: number, y: number}) : {x: number, y: number} + convertPixelCoordinatesToCMSpace(coordinates: PointCoordinates) : PointCoordinates onClear(): void; } @@ -19,6 +23,8 @@ const GoToActions = ( props: GoToActionsProperties ): JSX.Element => { const {goToTarget, convertPixelCoordinatesToCMSpace, onClear} = props; + const [integrationHelpDialogOpen, setIntegrationHelpDialogOpen] = React.useState(false); + const [integrationHelpDialogPayload, setIntegrationHelpDialogPayload] = React.useState(""); const {data: status} = useRobotStatusQuery((state) => { return state.value; @@ -40,47 +46,78 @@ const GoToActions = ( goTo(convertPixelCoordinatesToCMSpace({x: goToTarget.x0, y: goToTarget.y0})); }, [canGo, goToTarget, goTo, convertPixelCoordinatesToCMSpace]); + const handleLongClick = React.useCallback(() => { + setIntegrationHelpDialogPayload(JSON.stringify({ + action: "goto", + coordinates: floorObject(convertPixelCoordinatesToCMSpace({x: goToTarget.x0, y: goToTarget.y0})), + }, null, 2)); + + setIntegrationHelpDialogOpen(true); + }, [goToTarget, convertPixelCoordinatesToCMSpace]); + + const setupClickHandlers = useLongPress( + handleLongClick, + { + onCancel: (event) => { + handleClick(); + }, + threshold: 500, + captureEvent: true, + cancelOnMovement: true, + } + ); return ( - - - - Go To Location - {goToIsExecuting && ( - - )} - - - - - Clear - - - { - !canGo && + <> + + + + Go To Location + {goToIsExecuting && ( + + )} + + - - Cannot go to point while the robot is busy - + + Clear + - } - + { + !canGo && + + + Cannot go to point while the robot is busy + + + } + + { + setIntegrationHelpDialogOpen(open); + }} + helperText={"To trigger a \"Go To\" to the currently selected location via MQTT or REST, simply use this payload."} + coordinatesWarning={true} + payload={integrationHelpDialogPayload} + /> + ); }; diff --git a/frontend/src/map/actions/live_map_actions/SegmentActions.tsx b/frontend/src/map/actions/live_map_actions/SegmentActions.tsx index 9b369f0a..e71b7b0c 100644 --- a/frontend/src/map/actions/live_map_actions/SegmentActions.tsx +++ b/frontend/src/map/actions/live_map_actions/SegmentActions.tsx @@ -2,6 +2,8 @@ import {Capability, useCleanSegmentsMutation, useMapSegmentationPropertiesQuery, import React from "react"; import {Box, Button, CircularProgress, Container, Grid, Typography} from "@mui/material"; import {ActionButton} from "../../Styled"; +import IntegrationHelpDialog from "../../../components/IntegrationHelpDialog"; +import {useLongPress} from "use-long-press"; interface SegmentActionsProperties { segments: string[]; @@ -14,6 +16,9 @@ const SegmentActions = ( ): JSX.Element => { const {segments, onClear} = props; const [iterationCount, setIterationCount] = React.useState(1); + const [integrationHelpDialogOpen, setIntegrationHelpDialogOpen] = React.useState(false); + const [integrationHelpDialogPayload, setIntegrationHelpDialogPayload] = React.useState(""); + const { data: mapSegmentationProperties, @@ -40,9 +45,33 @@ const SegmentActions = ( executeSegmentAction({ segment_ids: segments, - iterations: iterationCount + iterations: iterationCount, + customOrder: mapSegmentationProperties?.customOrderSupport }); - }, [canClean, executeSegmentAction, segments, iterationCount]); + }, [canClean, executeSegmentAction, segments, iterationCount, mapSegmentationProperties]); + + const handleLongClick = React.useCallback(() => { + setIntegrationHelpDialogPayload(JSON.stringify({ + action: "start_segment_action", + segment_ids: segments, + iterations: iterationCount ?? 1, + customOrder: mapSegmentationProperties?.customOrderSupport ?? false + }, null, 2)); + + setIntegrationHelpDialogOpen(true); + }, [segments, iterationCount, mapSegmentationProperties]); + + const setupClickHandlers = useLongPress( + handleLongClick, + { + onCancel: (event) => { + handleClick(); + }, + threshold: 500, + captureEvent: true, + cancelOnMovement: true, + } + ); const handleIterationToggle = React.useCallback(() => { if (mapSegmentationProperties) { @@ -88,61 +117,72 @@ const SegmentActions = ( return ( - - - - Clean {segments.length} segments - {segmentActionExecuting && ( - - )} - - - { - mapSegmentationProperties.iterationCount.max > 1 && + <> + - {iterationCount}x + Clean {segments.length} segments + {segmentActionExecuting && ( + + )} - } - - - Clear - - - { - !canClean && + { + mapSegmentationProperties.iterationCount.max > 1 && + + + {iterationCount}x + + + } - - Cannot start segment cleaning while the robot is busy - + + Clear + - } - + { + !canClean && + + + Cannot start segment cleaning while the robot is busy + + + } + + { + setIntegrationHelpDialogOpen(open); + }} + coordinatesWarning={false} + helperText={"To start a cleanup of the currently selected segments with the currently configured parameters via MQTT or REST, simply use this payload."} + payload={integrationHelpDialogPayload} + /> + ); }; diff --git a/frontend/src/map/actions/live_map_actions/ZoneActions.tsx b/frontend/src/map/actions/live_map_actions/ZoneActions.tsx index 5852891f..c42e3532 100644 --- a/frontend/src/map/actions/live_map_actions/ZoneActions.tsx +++ b/frontend/src/map/actions/live_map_actions/ZoneActions.tsx @@ -5,13 +5,16 @@ import { } from "../../../api"; import React from "react"; import {Box, Button, CircularProgress, Container, Grid, Typography} from "@mui/material"; +import { useLongPress } from "use-long-press"; import {ActionButton} from "../../Styled"; import ZoneClientStructure from "../../structures/client_structures/ZoneClientStructure"; +import IntegrationHelpDialog from "../../../components/IntegrationHelpDialog"; +import {PointCoordinates} from "../../utils/types"; interface ZoneActionsProperties { zones: ZoneClientStructure[]; - convertPixelCoordinatesToCMSpace(coordinates: {x: number, y: number}) : {x: number, y: number} + convertPixelCoordinatesToCMSpace(coordinates: PointCoordinates) : PointCoordinates onClear(): void; @@ -23,6 +26,8 @@ const ZoneActions = ( ): JSX.Element => { const { zones, convertPixelCoordinatesToCMSpace, onClear, onAdd } = props; const [iterationCount, setIterationCount] = React.useState(1); + const [integrationHelpDialogOpen, setIntegrationHelpDialogOpen] = React.useState(false); + const [integrationHelpDialogPayload, setIntegrationHelpDialogPayload] = React.useState(""); const { data: status } = useRobotStatusQuery((state) => { return state.value; @@ -43,37 +48,60 @@ const ZoneActions = ( const canClean = status === "idle" || status === "docked" || status === "paused" || status === "returning" || status === "error"; const didSelectZones = zones.length > 0; + const zonesForAPI = React.useMemo(() => { + return zones.map((zone) => { + return { + iterations: iterationCount, + points: { + pA: convertPixelCoordinatesToCMSpace({ + x: zone.x0, + y: zone.y0 + }), + pB: convertPixelCoordinatesToCMSpace({ + x: zone.x1, + y: zone.y0 + }), + pC: convertPixelCoordinatesToCMSpace({ + x: zone.x1, + y: zone.y1 + }), + pD: convertPixelCoordinatesToCMSpace({ + x: zone.x0, + y: zone.y1 + }) + } + }; + }); + }, [zones, iterationCount, convertPixelCoordinatesToCMSpace]); + const handleClick = React.useCallback(() => { if (!didSelectZones || !canClean) { return; } - cleanTemporaryZones( - zones.map((zone) => { - return { - iterations: iterationCount, - points: { - pA: convertPixelCoordinatesToCMSpace({ - x: zone.x0, - y: zone.y0 - }), - pB: convertPixelCoordinatesToCMSpace({ - x: zone.x1, - y: zone.y0 - }), - pC: convertPixelCoordinatesToCMSpace({ - x: zone.x1, - y: zone.y1 - }), - pD: convertPixelCoordinatesToCMSpace({ - x: zone.x0, - y: zone.y1 - }) - } - }; - }) - ); - }, [canClean, didSelectZones, zones, iterationCount, cleanTemporaryZones, convertPixelCoordinatesToCMSpace]); + cleanTemporaryZones(zonesForAPI); + }, [canClean, didSelectZones, zonesForAPI, cleanTemporaryZones]); + + const handleLongClick = React.useCallback(() => { + setIntegrationHelpDialogPayload(JSON.stringify({ + action: "clean", + zones: zonesForAPI + }, null, 2)); + + setIntegrationHelpDialogOpen(true); + }, [zonesForAPI]); + + const setupClickHandlers = useLongPress( + handleLongClick, + { + onCancel: (event) => { + handleClick(); + }, + threshold: 500, + captureEvent: true, + cancelOnMovement: true, + } + ); const handleIterationToggle = React.useCallback(() => { if (zoneProperties) { @@ -117,76 +145,87 @@ const ZoneActions = ( } return ( - - - - Clean {zones.length} zones - {cleanTemporaryZonesIsExecuting && ( - - )} - - - { - zoneProperties.iterationCount.max > 1 && + <> + - {iterationCount}x + Clean {zones.length} zones + {cleanTemporaryZonesIsExecuting && ( + + )} - } - - - Add ({zones.length}/{zoneProperties.zoneCount.max}) - - - { - didSelectZones && + zoneProperties.iterationCount.max > 1 && + + + {iterationCount}x + + + } + - Clear + Add ({zones.length}/{zoneProperties.zoneCount.max}) - } - - - { - (didSelectZones && !canClean) && - - Cannot start zone cleaning while the robot is busy - - } + + + { + didSelectZones && + + Clear + + } + + + { + (didSelectZones && !canClean) && + + Cannot start zone cleaning while the robot is busy + + } + - + { + setIntegrationHelpDialogOpen(open); + }} + coordinatesWarning={true} + helperText={"To start a cleanup of the currently drawn zones with the currently configured parameters via MQTT or REST, simply use this payload."} + payload={integrationHelpDialogPayload} + /> + ); }; diff --git a/frontend/src/map/res/RobotCoverageMapHelp.ts b/frontend/src/map/res/RobotCoverageMapHelp.ts new file mode 100644 index 00000000..911e862d --- /dev/null +++ b/frontend/src/map/res/RobotCoverageMapHelp.ts @@ -0,0 +1,7 @@ +export const RobotCoverageMapHelp = ` +## Robot Coverage Map + +By rendering the path with a much thicker stroke, this live map view allows you to easily spot areas that weren't reached +by the robot. + +`; diff --git a/frontend/src/map/structures/Structure.ts b/frontend/src/map/structures/Structure.ts index 0fcf2961..a4c465bb 100644 --- a/frontend/src/map/structures/Structure.ts +++ b/frontend/src/map/structures/Structure.ts @@ -1,8 +1,6 @@ +import {Canvas2DContextTrackingWrapper} from "../utils/Canvas2DContextTrackingWrapper"; +import {PointCoordinates} from "../utils/types"; -export type PointCoordinates = { - x: number; - y: number; -} export type StructureInterceptionHandlerResult = { stopPropagation: boolean; //Will always redraw deleteMe?: boolean; @@ -24,7 +22,7 @@ abstract class Structure { this.type = this.getType(); } - abstract draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number, pixelSize: number) : void + abstract draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number, pixelSize: number) : void /** * Handler for intercepting tap events on the canvas @@ -49,7 +47,6 @@ abstract class Structure { postProcess() : void { //intentional } - } export default Structure; diff --git a/frontend/src/map/structures/client_structures/ClientStructure.ts b/frontend/src/map/structures/client_structures/ClientStructure.ts index fa7ea437..caf14c16 100644 --- a/frontend/src/map/structures/client_structures/ClientStructure.ts +++ b/frontend/src/map/structures/client_structures/ClientStructure.ts @@ -1,4 +1,5 @@ -import Structure, {PointCoordinates, StructureInterceptionHandlerResult} from "../Structure"; +import Structure, {StructureInterceptionHandlerResult} from "../Structure"; +import {PointCoordinates} from "../../utils/types"; /* ClientStructures are structures that only exists on the client-side @@ -33,6 +34,20 @@ abstract class ClientStructure extends Structure { //intentional } + + protected static calculateTranslateDelta(lastCoordinates: PointCoordinates, currentCoordinates: PointCoordinates, transformationMatrixToScreenSpace : DOMMatrixInit) { + const transformationMatrixToMapSpace = DOMMatrix.fromMatrix(transformationMatrixToScreenSpace).invertSelf(); + + const lastInMapSpace = new DOMPoint(lastCoordinates.x, lastCoordinates.y).matrixTransform(transformationMatrixToMapSpace); + const currentInMapSpace = new DOMPoint(currentCoordinates.x, currentCoordinates.y).matrixTransform(transformationMatrixToMapSpace); + + return { + dx: currentInMapSpace.x - lastInMapSpace.x, + dy: currentInMapSpace.y - lastInMapSpace.y, + lastInMapSpace: lastInMapSpace, + currentInMapSpace: currentInMapSpace + }; + } } export default ClientStructure; diff --git a/frontend/src/map/structures/client_structures/CuttingLineClientStructure.ts b/frontend/src/map/structures/client_structures/CuttingLineClientStructure.ts index 04b85894..d0d8f9a3 100644 --- a/frontend/src/map/structures/client_structures/CuttingLineClientStructure.ts +++ b/frontend/src/map/structures/client_structures/CuttingLineClientStructure.ts @@ -1,49 +1,21 @@ -import ClientStructure from "./ClientStructure"; -import deleteButtonIconSVG from "../icons/delete_zone.svg"; -import moveButtonIconSVG from "../icons/move_zone.svg"; -import {PointCoordinates, StructureInterceptionHandlerResult} from "../Structure"; +import LineClientStructure from "./LineClientStructure"; -const img_delete_button = new Image(); -img_delete_button.src = deleteButtonIconSVG; - -const img_move_button = new Image(); -img_move_button.src = moveButtonIconSVG; - -const buttonSize = 30; - -class CuttingLineClientStructure extends ClientStructure { +class CuttingLineClientStructure extends LineClientStructure { public static TYPE = "CuttingLineClientStructure"; - public x1: number; - public y1: number; - - //TODO: someone capable of math and therefore understanding these should give them better names - private matrix: DOMMatrix = new DOMMatrix(); - private sp0: DOMPoint = new DOMPoint(); - private sp1: DOMPoint = new DOMPoint(); - - constructor( x0: number, y0: number, x1: number, y1: number, active?: boolean ) { - super(x0, y0); - - this.x1 = x1; - this.y1 = y1; - - this.active = active ?? true; + super( + x0, y0, + x1, y1, + active ?? true + ); } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { - const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - - - ctx.save(); - - + protected setLineStyle(ctx: CanvasRenderingContext2D) { ctx.strokeStyle = "rgb(255, 255, 255)"; ctx.lineWidth = 5; ctx.lineCap = "round"; @@ -51,147 +23,6 @@ class CuttingLineClientStructure extends ClientStructure { if (this.active) { ctx.setLineDash([15, 5]); } - - ctx.beginPath(); - ctx.moveTo(p0.x, p0.y); - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - - - ctx.restore(); - - if (this.active) { - ctx.drawImage( - img_delete_button, - p0.x - img_delete_button.width / 2, - p0.y - img_delete_button.height / 2 - ); - - ctx.drawImage( - img_move_button, - p1.x - img_move_button.width / 2, - p1.y - img_move_button.height / 2 - ); - } - - this.matrix = new DOMMatrix().rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x); - this.sp0 = p0.matrixTransform(new DOMMatrix().translate(-10).rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x)); - this.sp1 = p1.matrixTransform(new DOMMatrix().translate(+10).rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x)); - } - - tap(tappedPoint : PointCoordinates, transformationMatrixToScreenSpace: DOMMatrixInit) : StructureInterceptionHandlerResult { - const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); - - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p0.x, 2) + Math.pow(tappedPoint.y - p0.y, 2) - ); - - const sTappedPoint = new DOMPoint(tappedPoint.x,tappedPoint.y).matrixTransform(this.matrix); - - if (this.active && distanceFromDelete <= buttonSize / 2) { - return { - deleteMe: true, - stopPropagation: true - }; - } else if ( - sTappedPoint.x >= this.sp0.x && - sTappedPoint.x <= this.sp1.x && - sTappedPoint.y >= this.sp0.y && - sTappedPoint.y <= this.sp1.y - ) { - this.active = true; - - return { - stopPropagation: true - }; - } else if (this.active) { - this.active = false; - - return { - stopPropagation: false, - requestDraw: true - }; - } else { - return { - stopPropagation: false - }; - } - } - - translate(startCoordinates: PointCoordinates, lastCoordinates: PointCoordinates, currentCoordinates: PointCoordinates, transformationMatrixToScreenSpace : DOMMatrixInit) : StructureInterceptionHandlerResult { - if (this.active) { - const transformationMatrixToMapSpace = DOMMatrix.fromMatrix(transformationMatrixToScreenSpace).invertSelf(); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - - const distanceFromResize = Math.sqrt( - Math.pow(lastCoordinates.x - p1.x, 2) + Math.pow(lastCoordinates.y - p1.y, 2) - ); - if (!this.isResizing && distanceFromResize <= buttonSize / 2) { - this.isResizing = true; - } - - const lastInMapSpace = new DOMPoint(lastCoordinates.x, lastCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - const currentInMapSpace = new DOMPoint(currentCoordinates.x, currentCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; - - const sLast = new DOMPoint(lastCoordinates.x,lastCoordinates.y).matrixTransform(this.matrix); - - if (distanceFromResize <= buttonSize / 2) { - this.x1 += dx; - this.y1 += dy; - - return { - stopPropagation: true - }; - } else if ( - sLast.x >= this.sp0.x && - sLast.x <= this.sp1.x && - sLast.y >= this.sp0.y && - sLast.y <= this.sp1.y - ) { - this.x0 += dx; - this.y0 += dy; - this.x1 += dx; - this.y1 += dy; - - return { - stopPropagation: true - }; - } - } - - return { - stopPropagation: false - }; - } - - postProcess(): void { - this.x0 = Math.round(this.x0); - this.y0 = Math.round(this.y0); - - const deltaY = Math.abs(this.y0 - this.y1); - const deltaX = Math.abs(this.x0 - this.x1); - const distance = Math.round(Math.hypot(deltaX, deltaY)); - - const angle = Math.atan2(deltaY, deltaX) * 180/Math.PI; - const newAngle = (Math.round(angle/5)*5); - - let xOffset = distance * Math.cos(newAngle * Math.PI/180); - let yOffset = distance * Math.sin(newAngle * Math.PI/180); - - - if (this.x0 > this.x1) { - xOffset = xOffset * -1; - } - - if (this.y0 > this.y1) { - yOffset = yOffset * -1; - } - - this.x1 = this.x0 + xOffset; - this.y1 = this.y0 + yOffset; } getType(): string { diff --git a/frontend/src/map/structures/client_structures/GoToTargetClientStructure.ts b/frontend/src/map/structures/client_structures/GoToTargetClientStructure.ts index f72944fb..a05017ab 100644 --- a/frontend/src/map/structures/client_structures/GoToTargetClientStructure.ts +++ b/frontend/src/map/structures/client_structures/GoToTargetClientStructure.ts @@ -1,5 +1,6 @@ import ClientStructure from "./ClientStructure"; import goToTargetIconSVG from "../icons/marker.svg"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; const img = new Image(); img.src = goToTargetIconSVG; @@ -11,7 +12,8 @@ class GoToTargetClientStructure extends ClientStructure { super(x0, y0); } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); diff --git a/frontend/src/map/structures/client_structures/LineClientStructure.ts b/frontend/src/map/structures/client_structures/LineClientStructure.ts new file mode 100644 index 00000000..d554aada --- /dev/null +++ b/frontend/src/map/structures/client_structures/LineClientStructure.ts @@ -0,0 +1,206 @@ +import ClientStructure from "./ClientStructure"; +import deleteButtonIconSVG from "../icons/delete_zone.svg"; +import moveButtonIconSVG from "../icons/move_zone.svg"; +import {StructureInterceptionHandlerResult} from "../Structure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; +import {PointCoordinates} from "../../utils/types"; +import {calculateBoxAroundPoint, isInsideBox} from "../../utils/helpers"; + +const img_delete_button = new Image(); +img_delete_button.src = deleteButtonIconSVG; + +const img_move_button = new Image(); +img_move_button.src = moveButtonIconSVG; + +const buttonHitboxPadding = 22.5; +const lineHitboxPadding = 22.5; + +abstract class LineClientStructure extends ClientStructure { + public static TYPE = "LineClientStructure"; + + public x1: number; + public y1: number; + + /* + We use this matrix approach to remove the rotation of our line before calculating if an input relates + to it. This makes it a lot easier than having to deal with rotated rectangles + + By applying this matrix transformation, we "normalize" our lines' coordinates so that both ends end up + with the same x coordinate. If we now apply the same transformation to the input event coordinates + we can easily check if that event was inside a box drawn around our line + + You can imagine it like this: + ╔ │ ╗ + ║ │ ║ + ║ │ ║ + ╚ │ ╝ + + no matter at what angle the actual displayed line might be / \ - + */ + private rotationRemovalTransformationMatrix: DOMMatrix = new DOMMatrix(); + + private lineHitbox = { + topLeftBound: new DOMPoint(), + bottomRightBound: new DOMPoint() + }; + + + constructor( + x0: number, y0: number, + x1: number, y1: number, + active: boolean + ) { + super(x0, y0); + + this.x1 = x1; + this.y1 = y1; + + this.active = active; + } + + protected abstract setLineStyle(ctx: CanvasRenderingContext2D) : void; + + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); + const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); + const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); + + + ctxWrapper.save(); + + + this.setLineStyle(ctx); + + ctx.beginPath(); + ctx.moveTo(p0.x, p0.y); + ctx.lineTo(p1.x, p1.y); + ctx.stroke(); + + + ctxWrapper.restore(); + + if (this.active) { + ctx.drawImage( + img_delete_button, + p0.x - img_delete_button.width / 2, + p0.y - img_delete_button.height / 2 + ); + + ctx.drawImage( + img_move_button, + p1.x - img_move_button.width / 2, + p1.y - img_move_button.height / 2 + ); + } + + this.rotationRemovalTransformationMatrix = new DOMMatrix().rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x); + + this.lineHitbox.topLeftBound = p0.matrixTransform( + new DOMMatrix().translate(-lineHitboxPadding).multiply(this.rotationRemovalTransformationMatrix) + ); + this.lineHitbox.bottomRightBound = p1.matrixTransform( + new DOMMatrix().translate(lineHitboxPadding).multiply(this.rotationRemovalTransformationMatrix) + ); + } + + tap(tappedPoint : PointCoordinates, transformationMatrixToScreenSpace: DOMMatrixInit) : StructureInterceptionHandlerResult { + const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); + + const deleteButtonHitbox = calculateBoxAroundPoint(p0, buttonHitboxPadding); + const sTappedPoint = new DOMPoint(tappedPoint.x,tappedPoint.y).matrixTransform(this.rotationRemovalTransformationMatrix); + + if (this.active && isInsideBox(tappedPoint, deleteButtonHitbox)) { + return { + deleteMe: true, + stopPropagation: true + }; + } else if (isInsideBox(sTappedPoint, this.lineHitbox)) { + this.active = true; + + return { + stopPropagation: true + }; + } else if (this.active) { + this.active = false; + + return { + stopPropagation: false, + requestDraw: true + }; + } else { + return { + stopPropagation: false + }; + } + } + + translate(startCoordinates: PointCoordinates, lastCoordinates: PointCoordinates, currentCoordinates: PointCoordinates, transformationMatrixToScreenSpace : DOMMatrixInit) : StructureInterceptionHandlerResult { + if (this.active) { + const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); + + const resizeButtonHitbox = calculateBoxAroundPoint(p1, buttonHitboxPadding); + + if (!this.isResizing && isInsideBox(lastCoordinates, resizeButtonHitbox)) { + this.isResizing = true; + } + + const { dx, dy } = ClientStructure.calculateTranslateDelta(lastCoordinates, currentCoordinates, transformationMatrixToScreenSpace); + const sLast = new DOMPoint(lastCoordinates.x,lastCoordinates.y).matrixTransform(this.rotationRemovalTransformationMatrix); + + if (isInsideBox(lastCoordinates, resizeButtonHitbox)) { + this.x1 += dx; + this.y1 += dy; + + return { + stopPropagation: true + }; + } else if (isInsideBox(sLast, this.lineHitbox)) { + this.x0 += dx; + this.y0 += dy; + this.x1 += dx; + this.y1 += dy; + + return { + stopPropagation: true + }; + } + } + + return { + stopPropagation: false + }; + } + + postProcess(): void { + this.x0 = Math.round(this.x0); + this.y0 = Math.round(this.y0); + + const deltaY = Math.abs(this.y0 - this.y1); + const deltaX = Math.abs(this.x0 - this.x1); + const distance = Math.round(Math.hypot(deltaX, deltaY)); + + const angle = Math.atan2(deltaY, deltaX) * 180/Math.PI; + const newAngle = (Math.round(angle/5)*5); + + let xOffset = distance * Math.cos(newAngle * Math.PI/180); + let yOffset = distance * Math.sin(newAngle * Math.PI/180); + + + if (this.x0 > this.x1) { + xOffset = xOffset * -1; + } + + if (this.y0 > this.y1) { + yOffset = yOffset * -1; + } + + this.x1 = this.x0 + xOffset; + this.y1 = this.y0 + yOffset; + } + + getType(): string { + return LineClientStructure.TYPE; + } +} + +export default LineClientStructure; diff --git a/frontend/src/map/structures/client_structures/NoGoAreaClientStructure.ts b/frontend/src/map/structures/client_structures/NoGoAreaClientStructure.ts index 260aedb8..f43c9ece 100644 --- a/frontend/src/map/structures/client_structures/NoGoAreaClientStructure.ts +++ b/frontend/src/map/structures/client_structures/NoGoAreaClientStructure.ts @@ -3,18 +3,12 @@ import RestrictedZoneClientStructure from "./RestrictedZoneClientStructure"; class NoGoAreaClientStructure extends RestrictedZoneClientStructure { public static TYPE = "NoGoAreaClientStructure"; - protected activeStyle : { - stroke: string, - fill: string, - } = { + protected activeStyle : { stroke: string, fill: string } = { stroke: "rgb(255, 0, 0)", fill: "rgba(255, 0, 0, 0)" }; - protected style : { - stroke: string, - fill: string, - } = { + protected style : { stroke: string, fill: string } = { stroke: "rgb(255, 0, 0)", fill: "rgba(255, 0, 0, 0.4)" }; diff --git a/frontend/src/map/structures/client_structures/NoMopAreaClientStructure.ts b/frontend/src/map/structures/client_structures/NoMopAreaClientStructure.ts index a3ce10e1..fb5baae7 100644 --- a/frontend/src/map/structures/client_structures/NoMopAreaClientStructure.ts +++ b/frontend/src/map/structures/client_structures/NoMopAreaClientStructure.ts @@ -3,18 +3,12 @@ import RestrictedZoneClientStructure from "./RestrictedZoneClientStructure"; class NoMopAreaClientStructure extends RestrictedZoneClientStructure { public static TYPE = "NoMopAreaClientStructure"; - protected activeStyle : { - stroke: string, - fill: string, - } = { + protected activeStyle : { stroke: string, fill: string } = { stroke: "rgb(200, 0, 255)", fill: "rgba(255, 0, 255, 0)" }; - protected style : { - stroke: string, - fill: string, - } = { + protected style : { stroke: string, fill: string } = { stroke: "rgb(200, 0, 255)", fill: "rgba(200, 0, 255, 0.4)" }; diff --git a/frontend/src/map/structures/client_structures/RestrictedZoneClientStructure.ts b/frontend/src/map/structures/client_structures/RestrictedZoneClientStructure.ts index 0683f163..7c7cea75 100644 --- a/frontend/src/map/structures/client_structures/RestrictedZoneClientStructure.ts +++ b/frontend/src/map/structures/client_structures/RestrictedZoneClientStructure.ts @@ -1,7 +1,10 @@ import ClientStructure from "./ClientStructure"; import deleteButtonIconSVG from "../icons/delete_zone.svg"; import scaleButtonIconSVG from "../icons/scale_zone.svg"; -import {PointCoordinates, StructureInterceptionHandlerResult} from "../Structure"; +import {StructureInterceptionHandlerResult} from "../Structure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; +import {PointCoordinates} from "../../utils/types"; +import {calculateBoxAroundPoint, isInsideBox} from "../../utils/helpers"; const img_delete_button = new Image(); img_delete_button.src = deleteButtonIconSVG; @@ -9,23 +12,17 @@ img_delete_button.src = deleteButtonIconSVG; const img_scale_button = new Image(); img_scale_button.src = scaleButtonIconSVG; -const buttonSize = 30; +const buttonHitboxPadding = 22.5; abstract class RestrictedZoneClientStructure extends ClientStructure { public static TYPE = "RestrictedZoneClientStructure"; - protected activeStyle : { - stroke: string, - fill: string, - } = { + protected activeStyle : { stroke: string, fill: string } = { stroke: "rgb(0, 255, 0)", fill: "rgba(0, 255, 0, 0)" }; - protected style : { - stroke: string, - fill: string, - } = { + protected style : { stroke: string, fill: string } = { stroke: "rgb(0, 255, 0)", fill: "rgba(0, 255, 0, 0.4)" }; @@ -56,14 +53,15 @@ abstract class RestrictedZoneClientStructure extends ClientStructure { this.active = active ?? true; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformationMatrixToScreenSpace); const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformationMatrixToScreenSpace); - ctx.save(); + ctxWrapper.save(); ctx.lineWidth = 5; ctx.lineCap = "round"; @@ -83,11 +81,16 @@ abstract class RestrictedZoneClientStructure extends ClientStructure { ctx.lineTo(p2.x, p2.y); ctx.lineTo(p3.x, p3.y); ctx.closePath(); - ctx.stroke(); + ctx.fill(); + ctx.shadowColor = "rgba(0,0,0, 1)"; + ctx.shadowBlur = 2; + + ctx.stroke(); - ctx.restore(); + + ctxWrapper.restore(); if (this.active) { @@ -124,21 +127,14 @@ abstract class RestrictedZoneClientStructure extends ClientStructure { const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformationMatrixToScreenSpace); - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p1.x, 2) + Math.pow(tappedPoint.y - p1.y, 2) - ); + const deleteButtonHitbox = calculateBoxAroundPoint(p1, buttonHitboxPadding); - if (this.active && distanceFromDelete <= buttonSize / 2) { + if (this.active && isInsideBox(tappedPoint, deleteButtonHitbox)) { return { deleteMe: true, stopPropagation: true }; - } else if ( - tappedPoint.x >= p0.x && - tappedPoint.x <= p2.x && - tappedPoint.y >= p0.y && - tappedPoint.y <= p2.y - ) { + } else if (isInsideBox(tappedPoint, {topLeftBound: p0, bottomRightBound: p2})) { this.active = true; return { @@ -160,22 +156,21 @@ abstract class RestrictedZoneClientStructure extends ClientStructure { translate(startCoordinates: PointCoordinates, lastCoordinates: PointCoordinates, currentCoordinates: PointCoordinates, transformationMatrixToScreenSpace : DOMMatrixInit, pixelSize: number) : StructureInterceptionHandlerResult { if (this.active) { - const transformationMatrixToMapSpace = DOMMatrix.fromMatrix(transformationMatrixToScreenSpace).invertSelf(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformationMatrixToScreenSpace); - const distanceFromResize = Math.sqrt( - Math.pow(lastCoordinates.x - p2.x, 2) + Math.pow(lastCoordinates.y - p2.y, 2) - ); - if (!this.isResizing && distanceFromResize <= buttonSize / 2) { + const resizeButtonHitbox = calculateBoxAroundPoint(p2, buttonHitboxPadding); + + if (!this.isResizing && isInsideBox(lastCoordinates, resizeButtonHitbox)) { this.isResizing = true; } - const lastInMapSpace = new DOMPoint(lastCoordinates.x, lastCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - const currentInMapSpace = new DOMPoint(currentCoordinates.x, currentCoordinates.y).matrixTransform(transformationMatrixToMapSpace); + const { + dx, + dy, + currentInMapSpace + } = ClientStructure.calculateTranslateDelta(lastCoordinates, currentCoordinates, transformationMatrixToScreenSpace); - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; if (this.isResizing) { if (currentInMapSpace.x > this.x0 + pixelSize && this.x1 + dx > this.x0 + pixelSize) { @@ -190,12 +185,7 @@ abstract class RestrictedZoneClientStructure extends ClientStructure { return { stopPropagation: true }; - } else if ( - lastCoordinates.x >= p0.x && - lastCoordinates.x <= p2.x && - lastCoordinates.y >= p0.y && - lastCoordinates.y <= p2.y - ) { + } else if (isInsideBox(lastCoordinates, {topLeftBound: p0, bottomRightBound: p2})) { this.x0 += dx; this.y0 += dy; this.x1 += dx; diff --git a/frontend/src/map/structures/client_structures/VirtualWallClientStructure.ts b/frontend/src/map/structures/client_structures/VirtualWallClientStructure.ts index aeebeead..10d4281d 100644 --- a/frontend/src/map/structures/client_structures/VirtualWallClientStructure.ts +++ b/frontend/src/map/structures/client_structures/VirtualWallClientStructure.ts @@ -1,48 +1,23 @@ -import ClientStructure from "./ClientStructure"; -import deleteButtonIconSVG from "../icons/delete_zone.svg"; -import moveButtonIconSVG from "../icons/move_zone.svg"; -import {PointCoordinates, StructureInterceptionHandlerResult} from "../Structure"; +import LineClientStructure from "./LineClientStructure"; -const img_delete_button = new Image(); -img_delete_button.src = deleteButtonIconSVG; - -const img_move_button = new Image(); -img_move_button.src = moveButtonIconSVG; - -const buttonSize = 30; - -class VirtualWallClientStructure extends ClientStructure { +class VirtualWallClientStructure extends LineClientStructure { public static TYPE = "VirtualWallClientStructure"; - public x1: number; - public y1: number; - - //TODO: someone capable of math and therefore understanding these should give them better names - private matrix: DOMMatrix = new DOMMatrix(); - private sp0: DOMPoint = new DOMPoint(); - private sp1: DOMPoint = new DOMPoint(); - - constructor( x0: number, y0: number, x1: number, y1: number, active?: boolean ) { - super(x0, y0); - - this.x1 = x1; - this.y1 = y1; - - this.active = active ?? false; + super( + x0, y0, + x1, y1, + active ?? false + ); } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { - const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - - - ctx.save(); - + protected setLineStyle(ctx: CanvasRenderingContext2D) { + ctx.shadowColor = "rgba(0,0,0, 1)"; + ctx.shadowBlur = 2; ctx.strokeStyle = "rgb(255, 0, 0)"; ctx.lineWidth = 5; @@ -51,147 +26,6 @@ class VirtualWallClientStructure extends ClientStructure { if (this.active) { ctx.setLineDash([15, 5]); } - - ctx.beginPath(); - ctx.moveTo(p0.x, p0.y); - ctx.lineTo(p1.x, p1.y); - ctx.stroke(); - - - ctx.restore(); - - if (this.active) { - ctx.drawImage( - img_delete_button, - p0.x - img_delete_button.width / 2, - p0.y - img_delete_button.height / 2 - ); - - ctx.drawImage( - img_move_button, - p1.x - img_move_button.width / 2, - p1.y - img_move_button.height / 2 - ); - } - - this.matrix = new DOMMatrix().rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x); - this.sp0 = p0.matrixTransform(new DOMMatrix().translate(-10).rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x)); - this.sp1 = p1.matrixTransform(new DOMMatrix().translate(+10).rotateFromVectorSelf(p1.y - p0.y,p1.x - p0.x)); - } - - tap(tappedPoint : PointCoordinates, transformationMatrixToScreenSpace: DOMMatrixInit) : StructureInterceptionHandlerResult { - const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); - - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p0.x, 2) + Math.pow(tappedPoint.y - p0.y, 2) - ); - - const sTappedPoint = new DOMPoint(tappedPoint.x,tappedPoint.y).matrixTransform(this.matrix); - - if (this.active && distanceFromDelete <= buttonSize / 2) { - return { - deleteMe: true, - stopPropagation: true - }; - } else if ( - sTappedPoint.x >= this.sp0.x && - sTappedPoint.x <= this.sp1.x && - sTappedPoint.y >= this.sp0.y && - sTappedPoint.y <= this.sp1.y - ) { - this.active = true; - - return { - stopPropagation: true - }; - } else if (this.active) { - this.active = false; - - return { - stopPropagation: false, - requestDraw: true - }; - } else { - return { - stopPropagation: false - }; - } - } - - translate(startCoordinates: PointCoordinates, lastCoordinates: PointCoordinates, currentCoordinates: PointCoordinates, transformationMatrixToScreenSpace : DOMMatrixInit) : StructureInterceptionHandlerResult { - if (this.active) { - const transformationMatrixToMapSpace = DOMMatrix.fromMatrix(transformationMatrixToScreenSpace).invertSelf(); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - - const distanceFromResize = Math.sqrt( - Math.pow(lastCoordinates.x - p1.x, 2) + Math.pow(lastCoordinates.y - p1.y, 2) - ); - if (!this.isResizing && distanceFromResize <= buttonSize / 2) { - this.isResizing = true; - } - - const lastInMapSpace = new DOMPoint(lastCoordinates.x, lastCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - const currentInMapSpace = new DOMPoint(currentCoordinates.x, currentCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; - - const sLast = new DOMPoint(lastCoordinates.x,lastCoordinates.y).matrixTransform(this.matrix); - - if (distanceFromResize <= buttonSize / 2) { - this.x1 += dx; - this.y1 += dy; - - return { - stopPropagation: true - }; - } else if ( - sLast.x >= this.sp0.x && - sLast.x <= this.sp1.x && - sLast.y >= this.sp0.y && - sLast.y <= this.sp1.y - ) { - this.x0 += dx; - this.y0 += dy; - this.x1 += dx; - this.y1 += dy; - - return { - stopPropagation: true - }; - } - } - - return { - stopPropagation: false - }; - } - - postProcess(): void { - this.x0 = Math.round(this.x0); - this.y0 = Math.round(this.y0); - - const deltaY = Math.abs(this.y0 - this.y1); - const deltaX = Math.abs(this.x0 - this.x1); - const distance = Math.round(Math.hypot(deltaX, deltaY)); - - const angle = Math.atan2(deltaY, deltaX) * 180/Math.PI; - const newAngle = (Math.round(angle/5)*5); - - let xOffset = distance * Math.cos(newAngle * Math.PI/180); - let yOffset = distance * Math.sin(newAngle * Math.PI/180); - - - if (this.x0 > this.x1) { - xOffset = xOffset * -1; - } - - if (this.y0 > this.y1) { - yOffset = yOffset * -1; - } - - this.x1 = this.x0 + xOffset; - this.y1 = this.y0 + yOffset; } getType(): string { diff --git a/frontend/src/map/structures/client_structures/ZoneClientStructure.ts b/frontend/src/map/structures/client_structures/ZoneClientStructure.ts index 4a5c8f2c..70aaf7a8 100644 --- a/frontend/src/map/structures/client_structures/ZoneClientStructure.ts +++ b/frontend/src/map/structures/client_structures/ZoneClientStructure.ts @@ -1,7 +1,10 @@ import ClientStructure from "./ClientStructure"; import deleteButtonIconSVG from "../icons/delete_zone.svg"; import scaleButtonIconSVG from "../icons/scale_zone.svg"; -import {PointCoordinates, StructureInterceptionHandlerResult} from "../Structure"; +import {StructureInterceptionHandlerResult} from "../Structure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; +import {PointCoordinates} from "../../utils/types"; +import {calculateBoxAroundPoint, isInsideBox} from "../../utils/helpers"; const img_delete_button = new Image(); img_delete_button.src = deleteButtonIconSVG; @@ -9,7 +12,7 @@ img_delete_button.src = deleteButtonIconSVG; const img_scale_button = new Image(); img_scale_button.src = scaleButtonIconSVG; -const buttonSize = 30; +const buttonHitboxPadding = 22.5; class ZoneClientStructure extends ClientStructure { public static TYPE = "ZoneClientStructure"; @@ -37,7 +40,8 @@ class ZoneClientStructure extends ClientStructure { this.y1 = Math.max(y0, y1); } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number, pixelSize: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number, pixelSize: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); @@ -47,7 +51,8 @@ class ZoneClientStructure extends ClientStructure { }; const label = dimensions.x.toFixed(2) + " x " + dimensions.y.toFixed(2) + "m"; - ctx.save(); + ctxWrapper.save(); + if (!this.active) { ctx.strokeStyle = "rgb(255, 255, 255)"; ctx.fillStyle = "rgba(255, 255, 255, 0.4)"; @@ -56,20 +61,25 @@ class ZoneClientStructure extends ClientStructure { ctx.strokeStyle = "rgb(255, 255, 255)"; ctx.fillStyle = "rgba(255, 255, 255, 0)"; } - ctx.lineWidth = 2; + ctx.fillRect(p0.x, p0.y, p1.x - p0.x, p1.y - p0.y); + + ctx.shadowColor = "rgba(0,0,0, 1)"; + ctx.shadowBlur = 2; + ctx.strokeRect(p0.x, p0.y, p1.x - p0.x, p1.y - p0.y); - ctx.restore(); - ctx.save(); + ctxWrapper.restore(); + + ctxWrapper.save(); ctx.textAlign = "start"; ctx.fillStyle = "rgba(255, 255, 255, 1)"; ctx.font = Math.round(6 * scaleFactor).toString(10) + "px sans-serif"; - ctx.fillText(label, p0.x, p0.y - 4); - ctx.strokeText(label, p0.x, p0.y - 4); + ctx.fillText(label, p0.x, p0.y - 8); + ctx.strokeText(label, p0.x, p0.y - 8); - ctx.restore(); + ctxWrapper.restore(); if (this.active) { ctx.drawImage( @@ -98,21 +108,14 @@ class ZoneClientStructure extends ClientStructure { const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p1.x, 2) + Math.pow(tappedPoint.y - p0.y, 2) - ); + const deleteButtonHitbox = calculateBoxAroundPoint({x: p1.x, y: p0.y}, buttonHitboxPadding); - if (this.active && distanceFromDelete <= buttonSize / 2) { + if (this.active && isInsideBox(tappedPoint, deleteButtonHitbox )) { return { deleteMe: true, stopPropagation: true }; - } else if ( - tappedPoint.x >= p0.x && - tappedPoint.x <= p1.x && - tappedPoint.y >= p0.y && - tappedPoint.y <= p1.y - ) { + } else if (isInsideBox(tappedPoint, {topLeftBound: p0, bottomRightBound: p1})) { this.active = true; return { @@ -134,22 +137,20 @@ class ZoneClientStructure extends ClientStructure { translate(startCoordinates: PointCoordinates, lastCoordinates: PointCoordinates, currentCoordinates: PointCoordinates, transformationMatrixToScreenSpace : DOMMatrixInit, pixelSize: number) : StructureInterceptionHandlerResult { if (this.active) { - const transformationMatrixToMapSpace = DOMMatrix.fromMatrix(transformationMatrixToScreenSpace).invertSelf(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - const distanceFromResize = Math.sqrt( - Math.pow(lastCoordinates.x - p1.x, 2) + Math.pow(lastCoordinates.y - p1.y, 2) - ); - if (!this.isResizing && distanceFromResize <= buttonSize / 2) { + const resizeButtonHitbox = calculateBoxAroundPoint(p1, buttonHitboxPadding); + + if (!this.isResizing && isInsideBox(lastCoordinates, resizeButtonHitbox)) { this.isResizing = true; } - const lastInMapSpace = new DOMPoint(lastCoordinates.x, lastCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - const currentInMapSpace = new DOMPoint(currentCoordinates.x, currentCoordinates.y).matrixTransform(transformationMatrixToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; + const { + dx, + dy, + currentInMapSpace + } = ClientStructure.calculateTranslateDelta(lastCoordinates, currentCoordinates, transformationMatrixToScreenSpace); if (this.isResizing) { if (currentInMapSpace.x > this.x0 + pixelSize && this.x1 + dx > this.x0 + pixelSize) { @@ -162,12 +163,7 @@ class ZoneClientStructure extends ClientStructure { return { stopPropagation: true }; - } else if ( - lastCoordinates.x >= p0.x && - lastCoordinates.x <= p1.x && - lastCoordinates.y >= p0.y && - lastCoordinates.y <= p1.y - ) { + } else if (isInsideBox(lastCoordinates, {topLeftBound: p0, bottomRightBound: p1})) { this.x0 += dx; this.y0 += dy; this.x1 += dx; diff --git a/frontend/src/map/structures/icons/segment.svg b/frontend/src/map/structures/icons/segment.svg index d7827d70..08f1c2ce 100644 --- a/frontend/src/map/structures/icons/segment.svg +++ b/frontend/src/map/structures/icons/segment.svg @@ -1,11 +1,9 @@ - - + + - - - - - + + + diff --git a/frontend/src/map/structures/icons/segment_selected.svg b/frontend/src/map/structures/icons/segment_selected.svg index 1e99587c..e96662f4 100644 --- a/frontend/src/map/structures/icons/segment_selected.svg +++ b/frontend/src/map/structures/icons/segment_selected.svg @@ -1,11 +1,7 @@ - - + + - - - - diff --git a/frontend/src/map/structures/map_structures/ActiveZoneMapStructure.ts b/frontend/src/map/structures/map_structures/ActiveZoneMapStructure.ts index 05886ffb..a06218db 100644 --- a/frontend/src/map/structures/map_structures/ActiveZoneMapStructure.ts +++ b/frontend/src/map/structures/map_structures/ActiveZoneMapStructure.ts @@ -1,3 +1,4 @@ +import { Canvas2DContextTrackingWrapper } from "../../utils/Canvas2DContextTrackingWrapper"; import MapStructure from "./MapStructure"; @@ -27,14 +28,15 @@ class ActiveZoneMapStructure extends MapStructure { this.y3 = y3; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformationMatrixToScreenSpace); const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformationMatrixToScreenSpace); - ctx.save(); + ctxWrapper.save(); ctx.strokeStyle = "rgb(53, 145, 26)"; @@ -51,7 +53,7 @@ class ActiveZoneMapStructure extends MapStructure { ctx.fill(); - ctx.restore(); + ctxWrapper.restore(); } getType(): string { diff --git a/frontend/src/map/structures/map_structures/ChargerLocationMapStructure.ts b/frontend/src/map/structures/map_structures/ChargerLocationMapStructure.ts index 8c8b43c0..08cb669a 100644 --- a/frontend/src/map/structures/map_structures/ChargerLocationMapStructure.ts +++ b/frontend/src/map/structures/map_structures/ChargerLocationMapStructure.ts @@ -1,5 +1,6 @@ import MapStructure from "./MapStructure"; import chargerIconSVG from "../icons/charger.svg"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; const img = new Image(); img.src = chargerIconSVG; @@ -11,7 +12,8 @@ class ChargerLocationMapStructure extends MapStructure { super(x0, y0); } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); diff --git a/frontend/src/map/structures/map_structures/GoToTargetMapStructure.ts b/frontend/src/map/structures/map_structures/GoToTargetMapStructure.ts index 23898b54..9b041276 100644 --- a/frontend/src/map/structures/map_structures/GoToTargetMapStructure.ts +++ b/frontend/src/map/structures/map_structures/GoToTargetMapStructure.ts @@ -1,5 +1,6 @@ import MapStructure from "./MapStructure"; import goToTargetIconSVG from "../icons/marker_active.svg"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; const img = new Image(); img.src = goToTargetIconSVG; @@ -11,7 +12,8 @@ class GoToTargetMapStructure extends MapStructure { super(x0, y0); } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); diff --git a/frontend/src/map/structures/map_structures/NoGoAreaMapStructure.ts b/frontend/src/map/structures/map_structures/NoGoAreaMapStructure.ts index 5627cffc..92b5b010 100644 --- a/frontend/src/map/structures/map_structures/NoGoAreaMapStructure.ts +++ b/frontend/src/map/structures/map_structures/NoGoAreaMapStructure.ts @@ -1,4 +1,5 @@ import MapStructure from "./MapStructure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; class NoGoAreaMapStructure extends MapStructure { @@ -27,18 +28,19 @@ class NoGoAreaMapStructure extends MapStructure { this.y3 = y3; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformationMatrixToScreenSpace); const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformationMatrixToScreenSpace); - ctx.save(); + ctxWrapper.save(); - ctx.strokeStyle = "rgb(255, 0, 0)"; - ctx.fillStyle = "rgba(255, 0, 0, 0.4)"; + ctx.strokeStyle = "rgb(255, 0, 0, 0.75)"; + ctx.fillStyle = "rgba(255, 0, 0, 0.15)"; ctx.lineWidth = 2; ctx.beginPath(); @@ -51,7 +53,7 @@ class NoGoAreaMapStructure extends MapStructure { ctx.fill(); - ctx.restore(); + ctxWrapper.restore(); } getType(): string { diff --git a/frontend/src/map/structures/map_structures/NoMopAreaMapStructure.ts b/frontend/src/map/structures/map_structures/NoMopAreaMapStructure.ts index 906f24e6..be7b6469 100644 --- a/frontend/src/map/structures/map_structures/NoMopAreaMapStructure.ts +++ b/frontend/src/map/structures/map_structures/NoMopAreaMapStructure.ts @@ -1,4 +1,5 @@ import MapStructure from "./MapStructure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; class NoMopAreaMapStructure extends MapStructure { @@ -27,18 +28,19 @@ class NoMopAreaMapStructure extends MapStructure { this.y3 = y3; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformationMatrixToScreenSpace); const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformationMatrixToScreenSpace); - ctx.save(); + ctxWrapper.save(); - ctx.strokeStyle = "rgb(200, 0, 255)"; - ctx.fillStyle = "rgba(200, 0, 255, 0.4)"; + ctx.strokeStyle = "rgb(200, 0, 255, 0.6)"; + ctx.fillStyle = "rgba(200, 0, 255, 0.15)"; ctx.lineWidth = 2; ctx.beginPath(); @@ -51,7 +53,7 @@ class NoMopAreaMapStructure extends MapStructure { ctx.fill(); - ctx.restore(); + ctxWrapper.restore(); } getType(): string { diff --git a/frontend/src/map/structures/map_structures/RobotPositionMapStructure.ts b/frontend/src/map/structures/map_structures/RobotPositionMapStructure.ts index 036b55f4..74105f90 100644 --- a/frontend/src/map/structures/map_structures/RobotPositionMapStructure.ts +++ b/frontend/src/map/structures/map_structures/RobotPositionMapStructure.ts @@ -1,5 +1,6 @@ import MapStructure from "./MapStructure"; import robotIconSVG from "../icons/robot.svg"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; const img = new Image(); img.src = robotIconSVG; @@ -15,7 +16,8 @@ class RobotPositionMapStructure extends MapStructure { this.angle = angle; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const rotateRobot = (img: HTMLImageElement, scaledSize: {width: number, height: number}, angle: number) => { diff --git a/frontend/src/map/structures/map_structures/SegmentLabelMapStructure.ts b/frontend/src/map/structures/map_structures/SegmentLabelMapStructure.ts index 1006f3d1..eaa85791 100644 --- a/frontend/src/map/structures/map_structures/SegmentLabelMapStructure.ts +++ b/frontend/src/map/structures/map_structures/SegmentLabelMapStructure.ts @@ -1,7 +1,10 @@ import MapStructure from "./MapStructure"; import segmentIconSVG from "../icons/segment.svg"; import segmentSelectedIconSVG from "../icons/segment_selected.svg"; -import {PointCoordinates, StructureInterceptionHandlerResult} from "../Structure"; +import {StructureInterceptionHandlerResult} from "../Structure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; +import {PointCoordinates} from "../../utils/types"; +import {calculateBoxAroundPoint, isInsideBox} from "../../utils/helpers"; const img = new Image(); img.src = segmentIconSVG; @@ -9,18 +12,21 @@ img.src = segmentIconSVG; const img_selected = new Image(); img_selected.src = segmentSelectedIconSVG; +const hitboxPadding = 5; + class SegmentLabelMapStructure extends MapStructure { public static TYPE = "SegmentLabelMapStructure"; id: string; selected: boolean; + topLabel: string | undefined; private active: boolean; - private area: number | undefined; + private area: number; public name: string | undefined; private scaledIconSize: { width: number; height: number } = {width: 1, height: 1}; - constructor(x0 : number ,y0 : number, id: string, selected: boolean, active: boolean, area?: number, name?: string) { + constructor(x0 : number ,y0 : number, id: string, selected: boolean, active: boolean, area: number, name?: string) { super(x0, y0); this.id = id; @@ -30,7 +36,8 @@ class SegmentLabelMapStructure extends MapStructure { this.name = name; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const imageToUse = this.selected ? img_selected : img; @@ -46,12 +53,12 @@ class SegmentLabelMapStructure extends MapStructure { ) }; - ctx.save(); + ctxWrapper.save(); if (this.active) { - ctx.translate(p0.x, p0.y); - ctx.rotate(Math.PI); - ctx.translate(-p0.x, -p0.y); + ctxWrapper.translate(p0.x, p0.y); + ctxWrapper.rotate(Math.PI); + ctxWrapper.translate(-p0.x, -p0.y); } ctx.drawImage( @@ -62,43 +69,69 @@ class SegmentLabelMapStructure extends MapStructure { this.scaledIconSize.height ); - ctx.restore(); + ctxWrapper.restore(); + + if (this.topLabel && scaleFactor >= 1.2) { + let fontSize; + const yOffset = ((this.scaledIconSize.height/3)*2) + (this.active ? 0 : 10); + + if (scaleFactor >= 9) { + fontSize = 45; + } else if (scaleFactor >= 8) { + fontSize = 40; + } else if (scaleFactor >= 7) { + fontSize = 35; + } else if (scaleFactor >= 6) { + fontSize = 30; + } else { + fontSize = 25; + } + + ctxWrapper.save(); - if (scaleFactor >= 9) { - ctx.save(); + ctx.textAlign = "center"; + ctx.font = `${fontSize}px sans-serif`; + ctx.fillStyle = "rgba(255, 255, 255, 1)"; + + ctx.fillText(this.topLabel, p0.x , p0.y - yOffset); + ctx.strokeText(this.topLabel, p0.x , p0.y - yOffset); + + ctxWrapper.restore(); + } + + if (scaleFactor >= 7) { + ctxWrapper.save(); ctx.textAlign = "center"; ctx.font = "45px sans-serif"; ctx.fillStyle = "rgba(255, 255, 255, 1)"; - const text = this.name ? this.name : this.id; - ctx.fillText(text, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0)); - ctx.strokeText(text, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0)); + if (this.name) { + ctx.fillText(this.name, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0)); + ctx.strokeText(this.name, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0)); + } - if (this.area) { - let areaString = (this.area / 10000).toPrecision(2) + " m²"; - if (this.name) { - areaString += `\n(id=${this.id})`; - } + if (scaleFactor >= 11) { + let metaString = (this.area / 10000).toPrecision(2) + " m²"; + metaString += ` (id=${this.id})`; ctx.font = "35px sans-serif"; ctx.fillStyle = "rgba(255, 255, 255, 1)"; - ctx.fillText(areaString, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0) + 45); - ctx.strokeText(areaString, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0) + 45); + ctx.fillText(metaString, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0) + (this.name ? 45 : 0)); + ctx.strokeText(metaString, p0.x , p0.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0) + (this.name ? 45 : 0)); } - ctx.restore(); + + + ctxWrapper.restore(); } } tap(tappedPoint : PointCoordinates, transformationMatrixToScreenSpace: DOMMatrixInit) : StructureInterceptionHandlerResult { const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); - if ( - tappedPoint.x >= p0.x - this.scaledIconSize.width / 2 && - tappedPoint.x <= p0.x + this.scaledIconSize.width / 2 && - tappedPoint.y >= p0.y - this.scaledIconSize.height / 2 && - tappedPoint.y <= p0.y + this.scaledIconSize.height / 2 - ) { + const iconHitbox = calculateBoxAroundPoint(p0, (this.scaledIconSize.width / 2) + hitboxPadding); + + if (isInsideBox(tappedPoint, iconHitbox)) { this.selected = !this.selected; return { diff --git a/frontend/src/map/structures/map_structures/VirtualWallMapStructure.ts b/frontend/src/map/structures/map_structures/VirtualWallMapStructure.ts index d75a9990..8331795d 100644 --- a/frontend/src/map/structures/map_structures/VirtualWallMapStructure.ts +++ b/frontend/src/map/structures/map_structures/VirtualWallMapStructure.ts @@ -1,4 +1,5 @@ import MapStructure from "./MapStructure"; +import {Canvas2DContextTrackingWrapper} from "../../utils/Canvas2DContextTrackingWrapper"; class VirtualWallMapStructure extends MapStructure { @@ -18,15 +19,16 @@ class VirtualWallMapStructure extends MapStructure { this.y1 = y1; } - draw(ctx: CanvasRenderingContext2D, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + draw(ctxWrapper: Canvas2DContextTrackingWrapper, transformationMatrixToScreenSpace: DOMMatrixInit, scaleFactor: number): void { + const ctx = ctxWrapper.getContext(); const p0 = new DOMPoint(this.x0, this.y0).matrixTransform(transformationMatrixToScreenSpace); const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformationMatrixToScreenSpace); - ctx.save(); + ctxWrapper.save(); - ctx.strokeStyle = "rgb(255, 0, 0)"; + ctx.strokeStyle = "rgb(255, 0, 0, 0.75)"; ctx.lineWidth = 5; ctx.lineCap = "round"; @@ -36,7 +38,7 @@ class VirtualWallMapStructure extends MapStructure { ctx.stroke(); - ctx.restore(); + ctxWrapper.restore(); } getType(): string { diff --git a/frontend/src/map/utils/Canvas2DContextTrackingWrapper.ts b/frontend/src/map/utils/Canvas2DContextTrackingWrapper.ts new file mode 100644 index 00000000..68b06bb1 --- /dev/null +++ b/frontend/src/map/utils/Canvas2DContextTrackingWrapper.ts @@ -0,0 +1,92 @@ + +/** + * This wrapper is used by the map to allow for panning and zooming + * It went through multiple iterations. This certainly won't be the last one + * + * At some point it was adapted from https://codepen.io/techslides/pen/zowLd + */ +export class Canvas2DContextTrackingWrapper { + private ctx: CanvasRenderingContext2D; + private currentTransform: DOMMatrix; + private savedTransforms: Array; + + + constructor(ctx : CanvasRenderingContext2D) { + this.ctx = ctx; + + this.currentTransform = new DOMMatrix(); + this.savedTransforms = []; + } + + getTransform() { + return this.currentTransform.translate(0, 0); + } + + save() { + this.savedTransforms.push(this.currentTransform.translate(0, 0)); + + this.ctx.save(); + } + + restore() { + if (this.savedTransforms.length > 0) { + this.currentTransform = this.savedTransforms.pop()!; + } + + this.ctx.restore(); + } + + scale(sx : number, sy : number) { + this.currentTransform = this.currentTransform.scale(sx, sy); + + this.ctx.scale(sx, sy); + } + + rotate(radians: number) { + this.currentTransform = this.currentTransform.rotate(radians * 180 / Math.PI); + + this.ctx.rotate(radians); + } + + translate(dx: number, dy: number) { + this.currentTransform = this.currentTransform.translate(dx, dy); + + this.ctx.translate(dx, dy); + } + + transform(a: number, b: number, c: number, d: number, e: number, f: number) { + const m2 = new DOMMatrix(); + m2.a = a; m2.b = b; m2.c = c; m2.d = d; m2.e = e; m2.f = f; + this.currentTransform = this.currentTransform.multiply(m2); + + this.ctx.transform(a, b, c, d, e, f); + } + + setTransform(a: number, b: number, c: number, d: number, e: number, f: number) { + this.currentTransform.a = a; + this.currentTransform.b = b; + this.currentTransform.c = c; + this.currentTransform.d = d; + this.currentTransform.e = e; + this.currentTransform.f = f; + + this.ctx.setTransform(a, b, c, d, e, f); + } + + mapPointToCurrentTransform(x: number, y: number) { + const pt = new DOMPoint(x, y); + + return pt.matrixTransform(DOMMatrix.fromMatrix(this.currentTransform).invertSelf()); + } + + getScaleFactor() { + return { + scaleX: Math.sqrt(this.currentTransform.a * this.currentTransform.a + this.currentTransform.b + this.currentTransform.b), + scaleY: Math.sqrt(this.currentTransform.c * this.currentTransform.c + this.currentTransform.d * this.currentTransform.d) + }; + } + + getContext() { + return this.ctx; + } +} diff --git a/frontend/src/map/utils/colors/ColorUtils.ts b/frontend/src/map/utils/colors/ColorUtils.ts new file mode 100644 index 00000000..ec378e89 --- /dev/null +++ b/frontend/src/map/utils/colors/ColorUtils.ts @@ -0,0 +1,13 @@ +export type SegmentId = string; + +export type PossibleSegmentId = SegmentId | undefined; + +export type SegmentColorId = number; + +export type PossibleSegmentColorId = SegmentColorId | undefined; + +export function create2DArray(xLength: number, yLength: number) { + return [...new Array(xLength)].map(elem => { + return [...new Array(yLength)]; + }); +} diff --git a/frontend/src/map/utils/map-color-finder.js b/frontend/src/map/utils/colors/FourColorTheoremSolver.ts similarity index 51% rename from frontend/src/map/utils/map-color-finder.js rename to frontend/src/map/utils/colors/FourColorTheoremSolver.ts index bbeef275..f425c31e 100644 --- a/frontend/src/map/utils/map-color-finder.js +++ b/frontend/src/map/utils/colors/FourColorTheoremSolver.ts @@ -1,8 +1,10 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types, max-classes-per-file */ +import {MapAreaVertex} from "./MapAreaVertex"; +import {MapAreaGraph} from "./MapAreaGraph"; +import {RawMapLayer} from "../../../api"; +import {create2DArray, PossibleSegmentId, SegmentColorId, SegmentId} from "./ColorUtils"; -// Snatched from https://github.com/Hypfer/Valetudo/blob/59b9bd5e7a315c21f459613a9f09e8f50787ab7b/client/js/js-modules/map-color-finder.js export class FourColorTheoremSolver { - /** + /* * This class determines how to color the different map segments contained in the given layers object. * The resulting color mapping will ensure that no two adjacent segments share the same color. * The map is evaluated row-by-row and column-by-column in order to find every pair of segments that are in "line of sight" of each other. @@ -12,7 +14,10 @@ export class FourColorTheoremSolver { * @param {Array} layers - the data containing the map image (array of pixel offsets) * @param {number} pixelSize - Used to calculate the resolution of the theorem. Assumes a robot diameter of 30cm and calculates the minimum size of a room. */ - constructor(layers, pixelSize) { + private readonly stepFunction: (c: number) => number; + private readonly areaGraph: MapAreaGraph | undefined; + + constructor(layers: Array, pixelSize: number) { /** * @param {number} resolution - Minimal resolution of the map scanner in pixels. Any number higher than one will lead to this many pixels being skipped when finding segment boundaries. * For example: If the robot measures 30cm in length/width, this should be set to 6, as no room can be smaller than 6 pixels. This of course implies that a pixel represents 5cm in the real world. @@ -21,70 +26,86 @@ export class FourColorTheoremSolver { this.stepFunction = function (c) { return c + resolution; }; - var preparedLayers = this.preprocessLayers(layers); + + const preparedLayers = this.preprocessLayers(layers); if (preparedLayers !== undefined) { - var mapData = this.createPixelToSegmentMapping(preparedLayers); + const mapData = this.createPixelToSegmentMapping(preparedLayers); this.areaGraph = this.buildGraph(mapData); this.areaGraph.colorAllVertices(); } } - /** + /* * @param {string} segmentId - ID of the segment you want to get the color for. * The segment ID is extracted from the layer meta data in the first contructor parameter of this class. * @returns {number} The segment color, represented as an integer. Starts at 0 and goes up the minimal number of colors required to color the map without collisions. */ - getColor(segmentId) { + getColor(segmentId: string) : SegmentColorId { if (this.areaGraph === undefined) { // Layer preprocessing seems to have failed. Just return a default value for any input. return 0; } - var segmentFromGraph = this.areaGraph.getById(segmentId); - if (segmentFromGraph) { + const segmentFromGraph = this.areaGraph.getById(segmentId); + + if (segmentFromGraph && segmentFromGraph.color !== undefined) { return segmentFromGraph.color; } else { return 0; } } - preprocessLayers(layers) { - var internalSegments = []; - var boundaries = { + private preprocessLayers(layers: Array): PreparedLayers | undefined { + const internalSegments : Array<{ + segmentId: SegmentId, + name: string | undefined, + pixels: Array + }>= []; + + const boundaries: Boundaries = { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity, }; + + const filteredLayers = layers.filter((layer) => { return layer.type === "segment"; }); + if (filteredLayers.length <= 0) { return undefined; } + filteredLayers.forEach((layer) => { - var allPixels = []; + const allPixels = []; for (let index = 0; index < layer.pixels.length - 1; index += 2) { - var p = { + const p = { x: layer.pixels[index], y: layer.pixels[index + 1], }; - this.setBoundaries(boundaries, p); + FourColorTheoremSolver.setBoundaries(boundaries, p); allPixels.push(p); } - internalSegments.push({ - segmentId: layer.metaData.segmentId, - name: layer.metaData.name, - pixels: allPixels, - }); + + if (layer.metaData.segmentId !== undefined) { + internalSegments.push({ + segmentId: layer.metaData.segmentId, + name: layer.metaData.name, + pixels: allPixels, + }); + } + }); + return { boundaries: boundaries, segments: internalSegments, }; } - setBoundaries(res, pixel) { + private static setBoundaries(res: Boundaries, pixel: Pixel) { if (pixel.x < res.minX) { res.minX = pixel.x; } @@ -99,50 +120,57 @@ export class FourColorTheoremSolver { } } - createPixelToSegmentMapping(preparedLayers) { - var pixelData = this.create2DArray( + private createPixelToSegmentMapping(preparedLayers: PreparedLayers) { + const pixelData = create2DArray( preparedLayers.boundaries.maxX + 1, preparedLayers.boundaries.maxY + 1 ); - var segmentIds = []; + const segmentIds: Array = []; + preparedLayers.segments.forEach((seg) => { segmentIds.push(seg.segmentId); + seg.pixels.forEach((p) => { pixelData[p.x][p.y] = seg.segmentId; }); }); + return { - map: pixelData, + map: pixelData as Array>, segmentIds: segmentIds, boundaries: preparedLayers.boundaries, }; } - buildGraph(mapData) { - var vertices = mapData.segmentIds.map((i) => { + private buildGraph(mapData: {map: Array>, segmentIds: Array, boundaries: Boundaries}) { + const vertices = mapData.segmentIds.map((i) => { return new MapAreaVertex(i); }); - var graph = new MapAreaGraph(vertices); + + const graph = new MapAreaGraph(vertices); + this.traverseMap( mapData.boundaries, mapData.map, - (x, y, currentSegmentId, pixelData) => { - var newSegmentId = pixelData[x][y]; + (x: number, y: number, currentSegmentId: PossibleSegmentId, pixelData: Array>) => { + const newSegmentId = pixelData[x][y]; + graph.connectVertices(currentSegmentId, newSegmentId); return newSegmentId !== undefined ? newSegmentId : currentSegmentId; } ); + return graph; } - traverseMap(boundaries, pixelData, func) { + private traverseMap(boundaries: Boundaries, pixelData: Array>, func : TraverseFunction) { // row-first traversal for ( let y = boundaries.minY; y <= boundaries.maxY; y = this.stepFunction(y) ) { - var rowFirstSegmentId = undefined; + let rowFirstSegmentId = undefined; for ( let x = boundaries.minX; x <= boundaries.maxX; @@ -157,7 +185,7 @@ export class FourColorTheoremSolver { x <= boundaries.maxX; x = this.stepFunction(x) ) { - var colFirstSegmentId = undefined; + let colFirstSegmentId = undefined; for ( let y = boundaries.minY; y <= boundaries.maxY; @@ -167,108 +195,32 @@ export class FourColorTheoremSolver { } } } - - /** - * Credit for this function goes to the authors of this StackOverflow answer: https://stackoverflow.com/a/966938 - * - * @param {number} length - */ - create2DArray(length) { - var arr = new Array(length || 0), - i = length; - if (arguments.length > 1) { - var args = Array.prototype.slice.call(arguments, 1); - while (i--) { - arr[length - 1 - i] = this.create2DArray.apply(this, args); - } - } - return arr; - } } -class MapAreaVertex { - constructor(id) { - this.id = id; - this.adjacentVertexIds = new Set(); - this.color = undefined; - } - - appendVertex(vertexId) { - if (vertexId !== undefined) { - this.adjacentVertexIds.add(vertexId); - } - } +type Pixel = { + x: number, + y: number } -class MapAreaGraph { - constructor(vertices) { - this.vertices = vertices; - this.vertexLookup = new Map(); - this.vertices.forEach((v) => { - this.vertexLookup.set(v.id, v); - }); - } - - connectVertices(id1, id2) { - if (id1 !== undefined && id2 !== undefined && id1 !== id2) { - if (this.vertexLookup.has(id1)) { - this.vertexLookup.get(id1).appendVertex(id2); - } - if (this.vertexLookup.has(id2)) { - this.vertexLookup.get(id2).appendVertex(id1); - } - } - } - - /** - * Color the graphs vertices using a greedy algorithm. Any vertices that have already been assigned a color will not be changed. - * Color assignment will start with the vertex that is connected with the highest number of edges. In most cases, this will - * naturally lead to a distribution where only four colors are required for the whole graph. This is relevant for maps with a high - * number of segments, as the naive, greedy algorithm tends to require a fifth color when starting coloring in a segment far from the map's center. - * - */ - colorAllVertices() { - this.vertices - .sort((l, r) => { - return r.adjacentVertexIds.size - l.adjacentVertexIds.size; - }) - .forEach((v) => { - if (v.adjacentVertexIds.size <= 0) { - v.color = 0; - } else { - var adjs = this.getAdjacentVertices(v); - var existingColors = adjs - .filter((vert) => { - return vert.color !== undefined; - }) - .map((vert) => { - return vert.color; - }); - v.color = this.lowestColor(existingColors); - } - }); - } - - getAdjacentVertices(vertex) { - return Array.from(vertex.adjacentVertexIds).map((id) => { - return this.getById(id); - }); - } - - getById(id) { - return this.vertices.find((v) => { - return v.id === id; - }); - } +type Boundaries = { + minX: number, + maxX: number, + minY: number, + maxY: number +} - lowestColor(colors) { - if (colors.length <= 0) { - return 0; - } - for (let index = 0; index < colors.length + 1; index++) { - if (!colors.includes(index)) { - return index; - } - } - } +type PreparedLayers = { + boundaries: Boundaries + segments: Array<{ + segmentId: SegmentId, + name: string | undefined, + pixels: Array + }> } + +type TraverseFunction = ( + x: number, + y: number, + currentSegmentId: PossibleSegmentId, + pixelData: Array> +) => PossibleSegmentId diff --git a/frontend/src/map/utils/colors/MapAreaGraph.ts b/frontend/src/map/utils/colors/MapAreaGraph.ts new file mode 100644 index 00000000..48177a54 --- /dev/null +++ b/frontend/src/map/utils/colors/MapAreaGraph.ts @@ -0,0 +1,85 @@ +import {MapAreaVertex} from "./MapAreaVertex"; +import {PossibleSegmentId, SegmentColorId, SegmentId} from "./ColorUtils"; + +export class MapAreaGraph { + vertices: Array; + vertexLookup: Map; + + + constructor(vertices: Array) { + this.vertices = vertices; + this.vertexLookup = new Map(); + + this.vertices.forEach((v) => { + this.vertexLookup.set(v.id, v); + }); + } + + connectVertices(id1 : PossibleSegmentId, id2: PossibleSegmentId) { + if (id1 !== undefined && id2 !== undefined && id1 !== id2) { + if (this.vertexLookup.has(id1)) { + this.vertexLookup.get(id1)!.appendVertex(id2); + } + if (this.vertexLookup.has(id2)) { + this.vertexLookup.get(id2)!.appendVertex(id1); + } + } + } + + /** + * Color the graphs vertices using a greedy algorithm. Any vertices that have already been assigned a color will not be changed. + * Color assignment will start with the vertex that is connected with the highest number of edges. In most cases, this will + * naturally lead to a distribution where only four colors are required for the whole graph. This is relevant for maps with a high + * number of segments, as the naive, greedy algorithm tends to require a fifth color when starting coloring in a segment far from the map's center. + * + */ + colorAllVertices() { + this.vertices.sort((l, r) => { + return r.adjacentVertexIds.size - l.adjacentVertexIds.size; + }); + + this.vertices.forEach((v) => { + if (v.adjacentVertexIds.size <= 0) { + v.color = 0; + } else { + const adjacentVertices = this.getAdjacentVertices(v); + + const existingColors = adjacentVertices + .filter((vert) => { + return vert.color !== undefined; + }) + .map((vert) => { + return vert.color; + }) as Array; + + v.color = this.lowestColor(existingColors); + } + }); + } + + getAdjacentVertices(vertex: MapAreaVertex): Array { + return Array.from(vertex.adjacentVertexIds).map((id) => { + return this.getById(id); + }).filter(adjacentVertex => { + return adjacentVertex !== undefined; + }) as Array; + } + + getById(id: string): MapAreaVertex | undefined { + return this.vertices.find((v) => { + return v.id === id; + }); + } + + lowestColor(colors: Array) { + if (colors.length <= 0) { + return 0; + } + + for (let index = 0; index < colors.length + 1; index++) { + if (!colors.includes(index)) { + return index; + } + } + } +} diff --git a/frontend/src/map/utils/colors/MapAreaVertex.ts b/frontend/src/map/utils/colors/MapAreaVertex.ts new file mode 100644 index 00000000..10b19e99 --- /dev/null +++ b/frontend/src/map/utils/colors/MapAreaVertex.ts @@ -0,0 +1,20 @@ +import {PossibleSegmentColorId, SegmentId} from "./ColorUtils"; + +export class MapAreaVertex { + id: SegmentId; + adjacentVertexIds: Set; + color: PossibleSegmentColorId; + + constructor(id: SegmentId) { + this.id = id; + this.adjacentVertexIds = new Set(); + + this.color = undefined; + } + + appendVertex(vertexId: string) { + if (vertexId !== undefined) { + this.adjacentVertexIds.add(vertexId); + } + } +} diff --git a/frontend/src/map/utils/helpers.ts b/frontend/src/map/utils/helpers.ts new file mode 100644 index 00000000..f85341a8 --- /dev/null +++ b/frontend/src/map/utils/helpers.ts @@ -0,0 +1,34 @@ +import {PointCoordinates} from "./types"; + +type Box = { + topLeftBound: { + x: number, + y: number + }, + bottomRightBound: { + x: number, + y: number + } +} + +export function isInsideBox(point: PointCoordinates, box: Box) { + return ( + point.x >= box.topLeftBound.x && + point.x <= box.bottomRightBound.x && + point.y >= box.topLeftBound.y && + point.y <= box.bottomRightBound.y + ); +} + +export function calculateBoxAroundPoint(point: PointCoordinates, boxPadding: number) : Box { + return { + topLeftBound: { + x: point.x - boxPadding, + y: point.y - boxPadding + }, + bottomRightBound: { + x: point.x + boxPadding, + y: point.y + boxPadding + } + }; +} diff --git a/frontend/src/map/utils/touch-handling.js b/frontend/src/map/utils/touch-handling.js deleted file mode 100644 index 024e7d0a..00000000 --- a/frontend/src/map/utils/touch-handling.js +++ /dev/null @@ -1,263 +0,0 @@ -/* eslint-disable */ - -//TODO: convert to typescript and add types for all these events - -function distance([x1, y1], [x2, y2]) { - return Math.sqrt( - Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) - ); -} - -class NoGesture { - updatePointerPosition(evts) {/* intentional */} - removePointer(evt) { - return this; - } -} - -class PossibleTap { - constructor(pointerDownEvent, dispatchEvent) { - this.tapTolerance = 5; - this.pointerId = pointerDownEvent.pointerId; - this.pointerDownPosition = [pointerDownEvent.clientX, pointerDownEvent.clientY]; - this.lastPosition = [pointerDownEvent.clientX, pointerDownEvent.clientY]; - - this.dispatchEvent = dispatchEvent; - } - - toleranceExeeded() { - return distance(this.lastPosition, this.pointerDownPosition) > this.tapTolerance; - } - - updatePointerPosition(evts) { - this.lastPosition = [evts[0].clientX, evts[0].clientY]; - } - - removePointer(evt) { - if (evt.pointerId === this.pointerId) { - const tapEvent = new Event("tap"); - tapEvent.tappedCoordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - this.dispatchEvent(tapEvent); - - return new NoGesture(); - } else { - return this; - } - } -} - -class OngoingPan { - constructor(pointerId, [pointerDownX, pointerDownY], [currentX, currentY], dispatchEvent) { - this.pointerId = pointerId; - this.pointerDownPosition = [pointerDownX, pointerDownY]; - this.lastPosition = [currentX, currentY]; - - this.dispatchEvent = dispatchEvent; - - const panStartEvent = new Event("panstart"); - panStartEvent.coordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - this.dispatchEvent(panStartEvent); - } - - updatePointerPosition(evts) { - this.lastPosition = [evts[0].clientX, evts[0].clientY]; - - const panMoveEvent = new Event("panmove"); - panMoveEvent.startCoordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - panMoveEvent.currentCoordinates = {x: evts[0].clientX, y: evts[0].clientY}; - this.dispatchEvent(panMoveEvent); - } - - removePointer(evt) { - if (evt.pointerId === this.pointerId) { - const panEndEvent = new Event("panend"); - panEndEvent.startCoordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - panEndEvent.currentCoordinates = {x: evt.clientX, y: evt.clientY}; - this.dispatchEvent(panEndEvent); - - return new NoGesture(); - } else { - return this; - } - } -} - -class OngoingPinch { - constructor(pointerId, [pointerDownX, pointerDownY], secondPointerDownEvent, dispatchEvent) { - this.tapTolerance = 5; - this.pointerId = pointerId; - this.pointerDownPosition = [pointerDownX, pointerDownY]; - this.lastPosition = [pointerDownX, pointerDownY]; - this.pointer2Id = secondPointerDownEvent.pointerId; - this.pointer2DownPosition = [secondPointerDownEvent.clientX, secondPointerDownEvent.clientY]; - this.lastPosition2 = [secondPointerDownEvent.clientX, secondPointerDownEvent.clientY]; - - this.dispatchEvent = dispatchEvent; - - const pinchStartEvent = new Event("pinchstart"); - pinchStartEvent.distance = distance(this.pointerDownPosition, this.pointer2DownPosition); - pinchStartEvent.scale = 1; - pinchStartEvent.center = { - x: (this.pointerDownPosition[0] + this.pointer2DownPosition[0]) / 2, - y: (this.pointerDownPosition[1] + this.pointer2DownPosition[1]) / 2 - }; - this.dispatchEvent(pinchStartEvent); - } - - updatePointerPosition(evts) { - for (let evt of evts) { - if (evt.pointerId === this.pointerId) { - this.lastPosition = [evt.clientX, evt.clientY]; - } else if (evt.pointerId === this.pointer2Id) { - this.lastPosition2 = [evt.clientX, evt.clientY]; - } - } - - const pinchMoveEvent = new Event("pinchmove"); - pinchMoveEvent.distance = distance(this.lastPosition, this.lastPosition2); - pinchMoveEvent.scale = pinchMoveEvent.distance / distance(this.pointerDownPosition, this.pointer2DownPosition); - pinchMoveEvent.center = { - x: (this.lastPosition[0] + this.lastPosition2[0]) / 2, - y: (this.lastPosition[1] + this.lastPosition2[1]) / 2 - }; - - this.dispatchEvent(pinchMoveEvent); - } - - removePointer(evt) { - if (evt.pointerId === this.pointerId) { - this.dispatchEvent(new Event("pinchend")); - return new OngoingPan( - this.pointer2Id, - this.lastPosition2, - this.lastPosition2, - this.dispatchEvent - ); - } else if (evt.pointerId === this.pointer2Id) { - this.dispatchEvent(new Event("pinchend")); - return new OngoingPan( - this.pointerId, - this.lastPosition, - this.lastPosition, - this.dispatchEvent - ); - } else { - return this; - } - } -} - -export class TouchHandler { - constructor(trackedElement) { - this.ongoingGesture = new NoGesture(); - } - - /** - * @param {HTMLElement} trackedElement - */ - registerListeners(trackedElement) { - this.trackedElement = trackedElement; - - this.trackedElement.addEventListener("mousedown", e => { - return this.pointerDown(e, this.touchChangesFromMouseEvent(e)); - }); - this.trackedElement.addEventListener("mousemove", e => { - return this.pointerMove(e, this.touchChangesFromMouseEvent(e)); - }); - this.trackedElement.addEventListener("mouseup", e => { - return this.pointerUp(e, this.touchChangesFromMouseEvent(e)); - }); - this.trackedElement.addEventListener("mouseleave", e => { - return this.pointerUp(e, this.touchChangesFromMouseEvent(e)); - }); - this.trackedElement.addEventListener("mouseout", e => { - return this.pointerUp(e, this.touchChangesFromMouseEvent(e)); - }); - - this.trackedElement.addEventListener("touchstart", e => { - return this.pointerDown(e, this.touchChangesFromTouchEvent(e)); - }); - this.trackedElement.addEventListener("touchmove", e => { - return this.pointerMove(e, this.touchChangesFromTouchEvent(e)); - }); - this.trackedElement.addEventListener("touchcancel", e => { - return this.pointerUp(e, this.touchChangesFromTouchEvent(e)); - }); - this.trackedElement.addEventListener("touchend", e => { - return this.pointerUp(e, this.touchChangesFromTouchEvent(e)); - }); - } - - - touchChangesFromMouseEvent(evt) { - return [{ - clientX: evt.clientX, - clientY: evt.clientY, - pointerId: 0 - }]; - } - - touchChangesFromTouchEvent(evt) { - const changedTouches = []; - - for (let touch of evt.changedTouches) { - changedTouches.push({ - clientX: touch.clientX, - clientY: touch.clientY, - pointerId: touch.identifier - }); - } - - return changedTouches; - } - - pointerDown(evt, changedTouches) { - evt.stopPropagation(); - evt.preventDefault(); - - //Ignore every mouse button that isn't just a regular click - if (evt.type === "mousedown" && evt.button !== 0) { - return; - } - - if (this.ongoingGesture instanceof NoGesture) { - this.ongoingGesture = new PossibleTap(changedTouches[0], this.trackedElement.dispatchEvent.bind(this.trackedElement)); - - } else if (this.ongoingGesture instanceof PossibleTap || this.ongoingGesture instanceof OngoingPan) { - this.ongoingGesture = new OngoingPinch( - this.ongoingGesture.pointerId, - // start the pinch with the first pointer at the current position - // (when the second pointer was added) - this.ongoingGesture.lastPosition, - changedTouches[0], - this.trackedElement.dispatchEvent.bind(this.trackedElement) - ); - } - } - - pointerMove(evt, changedTouches) { - evt.stopPropagation(); - evt.preventDefault(); - - this.ongoingGesture.updatePointerPosition(changedTouches); - - // Upgrade Tap to a Pan if the movement tolerance is exeeded - if (this.ongoingGesture instanceof PossibleTap && this.ongoingGesture.toleranceExeeded()) { - this.ongoingGesture = new OngoingPan( - this.ongoingGesture.pointerId, - this.ongoingGesture.pointerDownPosition, - this.ongoingGesture.lastPosition, - this.trackedElement.dispatchEvent.bind(this.trackedElement) - ); - } - } - - pointerUp(evt, changedTouches) { - evt.stopPropagation(); - evt.preventDefault(); - - changedTouches.forEach(e => { - this.ongoingGesture = this.ongoingGesture.removePointer(e); - }); - } -} diff --git a/frontend/src/map/utils/touch_handling/MapCanvasEvent.ts b/frontend/src/map/utils/touch_handling/MapCanvasEvent.ts new file mode 100644 index 00000000..5ad4943d --- /dev/null +++ b/frontend/src/map/utils/touch_handling/MapCanvasEvent.ts @@ -0,0 +1,39 @@ +import {UserEvent} from "./TouchHandlingUtils"; + +export class MapCanvasEvent { + x: number; + y: number; + pointerId: number; + + constructor(x: number, y : number, pointerId : number) { + this.x = x; + this.y = y; + this.pointerId = pointerId; + } + + static CREATE_EVENTS_FROM_MOUSE_EVENT(evt : MouseEvent) : Array { + return [ + new MapCanvasEvent(evt.clientX, evt.clientY, 0) + ]; + } + + static CREATE_EVENTS_FROM_TOUCH_EVENT(evt: TouchEvent) : Array { + const events = []; + + for (const touch of evt.changedTouches) { + events.push(new MapCanvasEvent(touch.clientX, touch.clientY, touch.identifier)); + } + + return events; + } + + static CREATE_EVENTS(evt: UserEvent) : Array { + if (evt instanceof MouseEvent) { + return MapCanvasEvent.CREATE_EVENTS_FROM_MOUSE_EVENT(evt); + } else if (evt instanceof TouchEvent) { + return MapCanvasEvent.CREATE_EVENTS_FROM_TOUCH_EVENT(evt); + } else { + throw new Error("Unknown event type"); + } + } +} diff --git a/frontend/src/map/utils/touch_handling/TouchHandler.ts b/frontend/src/map/utils/touch_handling/TouchHandler.ts new file mode 100644 index 00000000..b0719526 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/TouchHandler.ts @@ -0,0 +1,128 @@ +import {MapCanvasEvent} from "./MapCanvasEvent"; +import {NoGesture} from "./gestures/NoGesture"; +import {Gesture} from "./gestures/Gesture"; +import {PossibleTapGesture} from "./gestures/PossibleTapGesture"; +import {TouchHandlerEvent} from "./events/TouchHandlerEvent"; +import {OngoingPanGesture} from "./gestures/OngoingPanGesture"; +import {PinchEndTouchHandlerEvent} from "./events/PinchEndTouchHandlerEvent"; +import {OngoingPinchGesture} from "./gestures/OngoingPinchGesture"; +import {UserEvent} from "./TouchHandlingUtils"; + + +export class TouchHandler extends EventTarget { + private trackedElement: HTMLCanvasElement; + private currentGesture: Gesture; + + constructor(trackedElement :HTMLCanvasElement) { + super(); + this.currentGesture = new NoGesture(); + + this.trackedElement = trackedElement; + + this.registerListeners(); + } + + private registerListeners() { + [ + "mousedown", + "touchstart" + ].forEach(evtType => { + // @ts-ignore + this.trackedElement.addEventListener(evtType, (evt: UserEvent) => { + this.handleStartEvent(evt, MapCanvasEvent.CREATE_EVENTS(evt)); + }); + }); + + [ + "mousemove", + "touchmove" + ].forEach(evtType => { + // @ts-ignore + this.trackedElement.addEventListener(evtType, (evt: UserEvent) => { + this.handleOngoingEvent(evt, MapCanvasEvent.CREATE_EVENTS(evt)); + }); + }); + + [ + "mouseup", + "mouseleave", + "mouseout", + "touchcancel", + "touchend" + ].forEach(evtType => { + // @ts-ignore + this.trackedElement.addEventListener(evtType, (evt: UserEvent) => { + this.handleEndEvent(evt, MapCanvasEvent.CREATE_EVENTS(evt)); + }); + }); + } + + + private handleStartEvent(rawEvt : UserEvent, mapCanvasEvents: Array) { + rawEvt.stopPropagation(); + rawEvt.preventDefault(); + + + if (this.currentGesture instanceof NoGesture) { + this.currentGesture = new PossibleTapGesture(mapCanvasEvents[0]); + } else if (this.currentGesture instanceof PossibleTapGesture || this.currentGesture instanceof OngoingPanGesture) { //upgrade to pinch + this.currentGesture = new OngoingPinchGesture(this.currentGesture.getLastEvent(), mapCanvasEvents[0]); + } + + + + const result = this.currentGesture.handleStartEvent(rawEvt, mapCanvasEvents); + + if (result === false) { + this.currentGesture = new NoGesture(); + } else if (result instanceof TouchHandlerEvent) { + this.dispatchEvent(result); + } + } + + private handleOngoingEvent(rawEvt : UserEvent, mapCanvasEvents: Array) { + rawEvt.stopPropagation(); + rawEvt.preventDefault(); + + const result = this.currentGesture.handleOngoingEvent(rawEvt, mapCanvasEvents); + + if (result === false) { + if (this.currentGesture instanceof PossibleTapGesture) { //upgrade tap to pan + this.currentGesture = new OngoingPanGesture(this.currentGesture.getLastEvent()); + + const result2 = this.currentGesture.handleStartEvent(rawEvt, mapCanvasEvents); + if (result2 instanceof TouchHandlerEvent) { + this.dispatchEvent(result2); + } + } + } else if (result instanceof TouchHandlerEvent) { + this.dispatchEvent(result); + } + + } + + private handleEndEvent(rawEvt : UserEvent, mapCanvasEvents: Array) { + rawEvt.stopPropagation(); + rawEvt.preventDefault(); + + const result = this.currentGesture.handleEndEvent(rawEvt, mapCanvasEvents); + + if (result === false) { + this.currentGesture = new NoGesture(); + } else if (result instanceof TouchHandlerEvent) { + this.dispatchEvent(result); + + if (result instanceof PinchEndTouchHandlerEvent) { + this.currentGesture = new OngoingPanGesture(new MapCanvasEvent(result.x0, result.y0, result.pointerId)); + + const result2 = this.currentGesture.handleStartEvent(rawEvt, mapCanvasEvents); + if (result2 instanceof TouchHandlerEvent) { + this.dispatchEvent(result2); + } + } else { + this.currentGesture = new NoGesture(); + } + } + } +} + diff --git a/frontend/src/map/utils/touch_handling/TouchHandlingUtils.ts b/frontend/src/map/utils/touch_handling/TouchHandlingUtils.ts new file mode 100644 index 00000000..783e7e0a --- /dev/null +++ b/frontend/src/map/utils/touch_handling/TouchHandlingUtils.ts @@ -0,0 +1,7 @@ +export type UserEvent = MouseEvent | TouchEvent; + +export function distance2d(x0 : number, y0: number, x1: number, y1: number) : number { + return Math.sqrt( + Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2) + ); +} diff --git a/frontend/src/map/utils/touch_handling/events/PanEndTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/PanEndTouchHandlerEvent.ts new file mode 100644 index 00000000..bd25dd3b --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/PanEndTouchHandlerEvent.ts @@ -0,0 +1,22 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class PanEndTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "pan_end"; + + x0: number; + y0: number; + + x1: number; + y1: number; + + constructor(x0: number, y0: number, x1: number, y1: number) { + super(PanEndTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + + this.x1 = x1; + this.y1 = y1; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/PanMoveTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/PanMoveTouchHandlerEvent.ts new file mode 100644 index 00000000..52e5a991 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/PanMoveTouchHandlerEvent.ts @@ -0,0 +1,22 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class PanMoveTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "pan_move"; + + x0: number; + y0: number; + + x1: number; + y1: number; + + constructor(x0: number, y0: number, x1: number, y1: number) { + super(PanMoveTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + + this.x1 = x1; + this.y1 = y1; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/PanStartTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/PanStartTouchHandlerEvent.ts new file mode 100644 index 00000000..29388743 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/PanStartTouchHandlerEvent.ts @@ -0,0 +1,16 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class PanStartTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "pan_start"; + + x0: number; + y0: number; + + constructor(x0: number, y0: number) { + super(PanStartTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/PinchEndTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/PinchEndTouchHandlerEvent.ts new file mode 100644 index 00000000..3f560845 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/PinchEndTouchHandlerEvent.ts @@ -0,0 +1,19 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class PinchEndTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "pinch_end"; + + x0: number; + y0: number; + pointerId: number; + + + constructor(x0: number, y0: number, pointerId: number) { + super(PinchEndTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + this.pointerId = pointerId; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/PinchMoveTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/PinchMoveTouchHandlerEvent.ts new file mode 100644 index 00000000..493bdbb9 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/PinchMoveTouchHandlerEvent.ts @@ -0,0 +1,21 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class PinchMoveTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "pinch_move"; + + x0: number; + y0: number; + distance: number; + scale: number; + + constructor(x0: number, y0: number, distance: number, scale: number) { + super(PinchMoveTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + + this.distance = distance; + this.scale = scale; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/PinchStartTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/PinchStartTouchHandlerEvent.ts new file mode 100644 index 00000000..4976fd39 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/PinchStartTouchHandlerEvent.ts @@ -0,0 +1,21 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class PinchStartTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "pinch_start"; + + x0: number; + y0: number; + distance: number; + scale: number; + + constructor(x0: number, y0: number, distance: number, scale: number) { + super(PinchStartTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + + this.distance = distance; + this.scale = scale; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/TapTouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/TapTouchHandlerEvent.ts new file mode 100644 index 00000000..f372fd95 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/TapTouchHandlerEvent.ts @@ -0,0 +1,16 @@ +import {TouchHandlerEvent} from "./TouchHandlerEvent"; + +export class TapTouchHandlerEvent extends TouchHandlerEvent { + static TYPE = "tap"; + + x0: number; + y0: number; + + constructor(x0: number, y0: number) { + super(TapTouchHandlerEvent.TYPE); + + this.x0 = x0; + this.y0 = y0; + } + +} diff --git a/frontend/src/map/utils/touch_handling/events/TouchHandlerEvent.ts b/frontend/src/map/utils/touch_handling/events/TouchHandlerEvent.ts new file mode 100644 index 00000000..698dde83 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/events/TouchHandlerEvent.ts @@ -0,0 +1,4 @@ + +export abstract class TouchHandlerEvent extends Event { + +} diff --git a/frontend/src/map/utils/touch_handling/gestures/Gesture.ts b/frontend/src/map/utils/touch_handling/gestures/Gesture.ts new file mode 100644 index 00000000..79498a09 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/gestures/Gesture.ts @@ -0,0 +1,33 @@ +import {MapCanvasEvent} from "../MapCanvasEvent"; +import {TouchHandlerEvent} from "../events/TouchHandlerEvent"; +import {UserEvent} from "../TouchHandlingUtils"; + +export type GestureEventHandlingResult = TouchHandlerEvent | false | void; + +export abstract class Gesture { + + /* + * Returns an event if the gesture is ongoing + * May also return false if the gesture doesn't apply anymore + * Also, may return void if the gesture still applies but there's no event yet + */ + handleStartEvent(rawEvt : UserEvent, evts : Array) : GestureEventHandlingResult { + return; + } + + /* + * Returns an event if the gesture is ongoing + * May also return false if the gesture doesn't apply anymore + * Also, may return void if the gesture still applies but there's no event yet + */ + abstract handleOngoingEvent(rawEvt : UserEvent, evts : Array) : GestureEventHandlingResult + + /* + * Returns an event if the gesture is done + * May also return false if the gesture doesn't apply anymore + * Also, may return void if the gesture still applies but there's no event just yet + */ + handleEndEvent(rawEvt : UserEvent, evts : Array): GestureEventHandlingResult { + return; + } +} diff --git a/frontend/src/map/utils/touch_handling/gestures/NoGesture.ts b/frontend/src/map/utils/touch_handling/gestures/NoGesture.ts new file mode 100644 index 00000000..1c51d6e1 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/gestures/NoGesture.ts @@ -0,0 +1,9 @@ +import {Gesture} from "./Gesture"; +import {MapCanvasEvent} from "../MapCanvasEvent"; +import {UserEvent} from "../TouchHandlingUtils"; + +export class NoGesture extends Gesture { + handleOngoingEvent(rawEvt : UserEvent, evts: Array): void { + /* intentional */ + } +} diff --git a/frontend/src/map/utils/touch_handling/gestures/OngoingPanGesture.ts b/frontend/src/map/utils/touch_handling/gestures/OngoingPanGesture.ts new file mode 100644 index 00000000..a23cad52 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/gestures/OngoingPanGesture.ts @@ -0,0 +1,77 @@ +import {Gesture, GestureEventHandlingResult} from "./Gesture"; +import {MapCanvasEvent} from "../MapCanvasEvent"; +import {PanStartTouchHandlerEvent} from "../events/PanStartTouchHandlerEvent"; +import {PanMoveTouchHandlerEvent} from "../events/PanMoveTouchHandlerEvent"; +import {PanEndTouchHandlerEvent} from "../events/PanEndTouchHandlerEvent"; +import {UserEvent} from "../TouchHandlingUtils"; + +export class OngoingPanGesture extends Gesture { + private pointerId: number; + private initialPosition: { x: number; y: number }; + private lastPosition: { x: number; y: number }; + + private initialEvent: MapCanvasEvent; + private lastEvent: MapCanvasEvent; + + constructor(event: MapCanvasEvent) { + super(); + + this.initialEvent = event; + this.lastEvent = event; + + this.pointerId = event.pointerId; + this.initialPosition = { + x: event.x, + y: event.y + }; + this.lastPosition = { + x: event.x, + y: event.y + }; + } + + handleStartEvent(rawEvt: UserEvent, evts: Array): GestureEventHandlingResult { + return new PanStartTouchHandlerEvent(this.initialPosition.x, this.initialPosition.y); + } + + + handleOngoingEvent(rawEvt : UserEvent, evts: Array): GestureEventHandlingResult { + const event = evts[0]; + + this.lastEvent = event; + this.lastPosition.x = event.x; + this.lastPosition.y = event.y; + + return new PanMoveTouchHandlerEvent( + this.initialPosition.x, + this.initialPosition.y, + this.lastPosition.x, + this.lastPosition.y + ); + } + + handleEndEvent(rawEvt : UserEvent, evts : Array) : GestureEventHandlingResult { + const event = evts[0]; + + if (event.pointerId === this.pointerId) { + this.lastPosition.x = event.x; + this.lastPosition.y = event.y; + + return new PanEndTouchHandlerEvent( + this.initialPosition.x, + this.initialPosition.y, + this.lastPosition.x, + this.lastPosition.y + ); + } + } + + getInitialEvent() { + return this.initialEvent; + } + + getLastEvent() { + return this.lastEvent; + } + +} diff --git a/frontend/src/map/utils/touch_handling/gestures/OngoingPinchGesture.ts b/frontend/src/map/utils/touch_handling/gestures/OngoingPinchGesture.ts new file mode 100644 index 00000000..decac993 --- /dev/null +++ b/frontend/src/map/utils/touch_handling/gestures/OngoingPinchGesture.ts @@ -0,0 +1,106 @@ +import {Gesture, GestureEventHandlingResult} from "./Gesture"; +import {MapCanvasEvent} from "../MapCanvasEvent"; +import {PinchStartTouchHandlerEvent} from "../events/PinchStartTouchHandlerEvent"; +import {distance2d, UserEvent} from "../TouchHandlingUtils"; +import {PinchMoveTouchHandlerEvent} from "../events/PinchMoveTouchHandlerEvent"; +import {PinchEndTouchHandlerEvent} from "../events/PinchEndTouchHandlerEvent"; + +export class OngoingPinchGesture extends Gesture { + private pointerId: number; + private initialPosition: { x: number; y: number }; + private lastPosition: { x: number; y: number }; + + private pointer2Id: number; + private initial2Position: { x: number; y: number }; + private last2Position: { x: number; y: number }; + + constructor(event: MapCanvasEvent, event2: MapCanvasEvent) { + super(); + + this.pointerId = event.pointerId; + this.initialPosition = { + x: event.x, + y: event.y + }; + this.lastPosition = { + x: event.x, + y: event.y + }; + + this.pointer2Id = event2.pointerId; + this.initial2Position = { + x: event2.x, + y: event2.y + }; + this.last2Position = { + x: event2.x, + y: event2.y + }; + } + + handleStartEvent(rawEvt: UserEvent, evts: Array): GestureEventHandlingResult { + return new PinchStartTouchHandlerEvent( + (this.initialPosition.x + this.initial2Position.x) / 2, + (this.initialPosition.y + this.initial2Position.y) / 2, + + distance2d( + this.initialPosition.x, this.initialPosition.y, + this.initial2Position.x, this.initial2Position.y, + ), + + 1 + ); + } + + + handleOngoingEvent(rawEvt : UserEvent, evts: Array): GestureEventHandlingResult { + for (const evt of evts) { + if (evt.pointerId === this.pointerId) { + this.lastPosition.x = evt.x; + this.lastPosition.y = evt.y; + } else if (evt.pointerId === this.pointer2Id) { + this.last2Position.x = evt.x; + this.last2Position.y = evt.y; + } + } + + const distance = distance2d( + this.lastPosition.x, this.lastPosition.y, + this.last2Position.x, this.last2Position.y, + ); + + const scale = distance / distance2d( + this.initialPosition.x, this.initialPosition.y, + this.initial2Position.x, this.initial2Position.y, + ); + + return new PinchMoveTouchHandlerEvent( + (this.lastPosition.x + this.last2Position.x) / 2, + (this.lastPosition.y + this.last2Position.y) / 2, + + distance, + scale + ); + } + + handleEndEvent(rawEvt : UserEvent, evts : Array) : GestureEventHandlingResult { + for (const evt of evts) { + if (evt.pointerId === this.pointerId) { + return new PinchEndTouchHandlerEvent( + this.last2Position.x, + this.last2Position.y, + this.pointer2Id + ); + } else if (evt.pointerId === this.pointer2Id) { + return new PinchEndTouchHandlerEvent( + this.lastPosition.x, + this.lastPosition.y, + this.pointerId + ); + + } + } + + return false; + } +} diff --git a/frontend/src/map/utils/touch_handling/gestures/PossibleTapGesture.ts b/frontend/src/map/utils/touch_handling/gestures/PossibleTapGesture.ts new file mode 100644 index 00000000..633d75ce --- /dev/null +++ b/frontend/src/map/utils/touch_handling/gestures/PossibleTapGesture.ts @@ -0,0 +1,75 @@ +import {Gesture, GestureEventHandlingResult} from "./Gesture"; +import {MapCanvasEvent} from "../MapCanvasEvent"; +import {TapTouchHandlerEvent} from "../events/TapTouchHandlerEvent"; +import {distance2d, UserEvent} from "../TouchHandlingUtils"; + +export class PossibleTapGesture extends Gesture { + private pointerId: number; + private initialPosition: { x: number; y: number }; + private lastPosition: { x: number; y: number }; + private initialEvent: MapCanvasEvent; + private lastEvent: MapCanvasEvent; + + constructor(event: MapCanvasEvent) { + super(); + + this.initialEvent = event; + this.lastEvent = event; + + this.pointerId = event.pointerId; + this.initialPosition = { + x: event.x, + y: event.y + }; + this.lastPosition = { + x: event.x, + y: event.y + }; + } + + handleStartEvent(rawEvt : UserEvent, evts: Array): GestureEventHandlingResult { + //Ignore every mouse button that isn't just a regular click + if (rawEvt instanceof MouseEvent && rawEvt.type === "mousedown" && rawEvt.button !== 0) { + return false; + } + } + + + handleOngoingEvent(rawEvt : UserEvent, evts: Array): GestureEventHandlingResult { + const event = evts[0]; + + this.lastEvent = event; + this.lastPosition.x = event.x; + this.lastPosition.y = event.y; + + const distance = distance2d( + this.initialPosition.x, + this.initialPosition.y, + this.lastPosition.x, + this.lastPosition.y + ); + + //If the pointer moved too much, it's not a tap anymore + if (distance > 5) { + return false; + } + } + + handleEndEvent(rawEvt : UserEvent, evts : Array) : GestureEventHandlingResult { + const event = evts[0]; + + if (event.pointerId === this.pointerId) { + return new TapTouchHandlerEvent(this.initialPosition.x, this.initialPosition.y); + } else { + return; + } + } + + getInitialEvent() { + return this.initialEvent; + } + + getLastEvent() { + return this.lastEvent; + } +} diff --git a/frontend/src/map/utils/tracked-canvas.js b/frontend/src/map/utils/tracked-canvas.js deleted file mode 100644 index c16d73b5..00000000 --- a/frontend/src/map/utils/tracked-canvas.js +++ /dev/null @@ -1,80 +0,0 @@ -/* eslint-disable */ -/** - * This allows to save and retrieve the currently applied transfroms from the RenderingContext. - * There is a native browser feature not really supported today: - * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/currentTransform - * - * - * Large amounts of this code are from here: https://codepen.io/techslides/pen/zowLd - * - * @param {CanvasRenderingContext2D} ctx - */ -export function trackTransforms(ctx) { - let xform = new DOMMatrix(); - ctx.getTransform = function () { - return xform.translate(0, 0); - }; - - const savedTransforms = []; - const save = ctx.save; - ctx.save = function () { - savedTransforms.push(xform.translate(0, 0)); - return save.call(ctx); - }; - - const restore = ctx.restore; - ctx.restore = function () { - xform = savedTransforms.pop(); - return restore.call(ctx); - }; - - const scale = ctx.scale; - ctx.scale = function (sx, sy) { - xform = xform.scale(sx, sy); - return scale.call(ctx, sx, sy); - }; - - const rotate = ctx.rotate; - ctx.rotate = function (radians) { - xform = xform.rotate(radians * 180 / Math.PI); - return rotate.call(ctx, radians); - }; - - const translate = ctx.translate; - ctx.translate = function (dx, dy) { - xform = xform.translate(dx, dy); - return translate.call(ctx, dx, dy); - }; - - const transform = ctx.transform; - ctx.transform = function (a, b, c, d, e, f) { - const m2 = new DOMMatrix(); - m2.a = a; m2.b = b; m2.c = c; m2.d = d; m2.e = e; m2.f = f; - xform = xform.multiply(m2); - return transform.call(ctx, a, b, c, d, e, f); - }; - - const setTransform = ctx.setTransform; - ctx.setTransform = function (a, b, c, d, e, f) { - xform.a = a; - xform.b = b; - xform.c = c; - xform.d = d; - xform.e = e; - xform.f = f; - return setTransform.call(ctx, a, b, c, d, e, f); - }; - - const pt = new DOMPoint(); - ctx.transformedPoint = function (x, y) { - pt.x = x; pt.y = y; - return pt.matrixTransform(DOMMatrix.fromMatrix(xform).invertSelf()); - }; - - ctx.getScaleFactor2d = function () { - const sx = Math.sqrt(xform.a * xform.a + xform.b + xform.b); - const sy = Math.sqrt(xform.c * xform.c + xform.d * xform.d); - - return [sx, sy]; - }; -} diff --git a/frontend/src/map/utils/types.ts b/frontend/src/map/utils/types.ts new file mode 100644 index 00000000..c72c2d8b --- /dev/null +++ b/frontend/src/map/utils/types.ts @@ -0,0 +1,4 @@ +export type PointCoordinates = { + x: number; + y: number; +} diff --git a/frontend/src/robot/RobotSettings.tsx b/frontend/src/robot/RobotSettings.tsx index 976c2585..acacced9 100644 --- a/frontend/src/robot/RobotSettings.tsx +++ b/frontend/src/robot/RobotSettings.tsx @@ -20,6 +20,7 @@ import { } from "@mui/icons-material"; import {SpacerListMenuItem} from "../components/list_menu/SpacerListMenuItem"; import {LinkListMenuItem} from "../components/list_menu/LinkListMenuItem"; +import PaperContainer from "../components/PaperContainer"; const KeyLockCapabilitySwitchListMenuItem = () => { const { @@ -216,11 +217,13 @@ const RobotSettings = (): JSX.Element => { ]); return ( - + + + ); }; diff --git a/frontend/src/robot/capabilities/CapabilityLayout.tsx b/frontend/src/robot/capabilities/CapabilityLayout.tsx index 9ed4c574..90c5318f 100644 --- a/frontend/src/robot/capabilities/CapabilityLayout.tsx +++ b/frontend/src/robot/capabilities/CapabilityLayout.tsx @@ -1,6 +1,5 @@ import React from "react"; import {Grid, useMediaQuery, useTheme} from "@mui/material"; -import MasonryItem from "@mui/lab/MasonryItem"; import Masonry from "@mui/lab/Masonry"; import ReloadableCard from "../../components/ReloadableCard"; @@ -13,7 +12,7 @@ export const CapabilityContainer: React.FunctionComponent<{ children: React.Reac const wideLayout = useWideLayout(); if (wideLayout && children) { return ( - + {children} ); @@ -54,11 +53,7 @@ export const CapabilityItem: React.FunctionComponent< ); if (wideLayout) { - return ( - - {content} - - ); + return content; } else { return ( diff --git a/frontend/src/robot/capabilities/res/DoNotDisturbHelp.ts b/frontend/src/robot/capabilities/res/DoNotDisturbHelp.ts index 4416035e..2bd8f74d 100644 --- a/frontend/src/robot/capabilities/res/DoNotDisturbHelp.ts +++ b/frontend/src/robot/capabilities/res/DoNotDisturbHelp.ts @@ -14,8 +14,4 @@ Another thing that can be affected by the DND setting is the auto empty dock as **Please note that DND times are evaluated and stored as UTC. They are only displayed in your current browser timezone for your convenience.** - -**If your country/state is taking part in that nonsensical Daylight Saving Time cult, you will have to -manually shift the DND time back and forth each time you switch from and to DST.** - `; diff --git a/frontend/src/robot/capabilities/res/VoicepackHelp.ts b/frontend/src/robot/capabilities/res/VoicepackHelp.ts index 15c4146a..1dfa5147 100644 --- a/frontend/src/robot/capabilities/res/VoicepackHelp.ts +++ b/frontend/src/robot/capabilities/res/VoicepackHelp.ts @@ -7,7 +7,7 @@ As I personally don't really care about them, this feature is a bit rough around For me, these things are first and foremost tools that should simply work and do so reliably. Thus, I'm fine with it just talking english as that's perfectly serviceable for a tool. -If you want to install install a custom one anyways, you will need a voicepack in the correct format as required by your +If you want to install a custom one anyways, you will need a voicepack in the correct format as required by your robot hosted on some http server. Note that the official CDN is often blocked in the robots firmware meaning that just using the official URL likely won't work. @@ -17,6 +17,6 @@ The type of hash differs depending on the firmware. Furthermore, you'll also need to specify a language code. That value largely doesn't matter much unless you use a reserved code. "EN", "CN" etc are often codes reserved for the inbuilt voice packs of the firmware. -Usually it's possible to revert to the currently installed voice pack by specifying one of those inbuilt voicepack codes during the install. +Usually it's possible to revert to the inititally installed voice pack by specifying one of those inbuilt voicepack codes during the install. `; diff --git a/frontend/src/robot/res/ConsumablesHelp.ts b/frontend/src/robot/res/ConsumablesHelp.ts index 5891510c..3f7e253b 100644 --- a/frontend/src/robot/res/ConsumablesHelp.ts +++ b/frontend/src/robot/res/ConsumablesHelp.ts @@ -14,7 +14,7 @@ Not maintaining your consumables may lead to performance degradation.
Still, Valetudo recommends manual inspection of the part in question. You _may_ be able to use it longer than the manufacturer recommends. -To figure out, which part of your robot is the consumable in question, you can hover your mouse over the remaining time/percent. +To figure out which part of your robot is the consumable in question, you can hover your mouse over the remaining time/percent. The robot part will now light up to show you where it is. diff --git a/frontend/src/robot/res/StatisticsAchievements.ts b/frontend/src/robot/res/StatisticsAchievements.ts index e9b66b6d..f2880d65 100644 --- a/frontend/src/robot/res/StatisticsAchievements.ts +++ b/frontend/src/robot/res/StatisticsAchievements.ts @@ -16,17 +16,17 @@ export const statisticsAchievements: Record { @@ -32,10 +38,12 @@ const MappingPassButtonItem = (): JSX.Element => { secondaryLabel="Create a new map" icon={} buttonLabel="Go" - confirmationDialogTitle="Start mapping pass?" - confirmationDialogBody="Do you really want to start a mapping pass?" - dialogAction={startMappingPass} - dialogActionLoading={mappingPassStarting} + confirmationDialog={{ + title: "Start mapping pass?", + body: "Do you really want to start a mapping pass?" + }} + action={startMappingPass} + actionLoading={mappingPassStarting} /> ); }; @@ -50,10 +58,12 @@ const MapResetButtonItem = (): JSX.Element => { icon={} buttonLabel="Go" buttonIsDangerous={true} - confirmationDialogTitle="Reset map?" - confirmationDialogBody="Do you really want to reset the map?" - dialogAction={resetMap} - dialogActionLoading={mapResetting} + confirmationDialog={{ + title: "Reset map?", + body: "Do you really want to reset the map?" + }} + action={resetMap} + actionLoading={mapResetting} /> ); }; @@ -108,6 +118,45 @@ const PersistentMapSwitchListItem = () => { ); }; +const ValetudoMapDataExportButtonItem = (): JSX.Element => { + const { + data: valetudoInformation, + isLoading: valetudoInformationLoading + } = useValetudoInformationQuery(); + + const { + data: mapData, + isLoading: mapIsLoading, + } = useRobotMapQuery(); + + + return ( + } + buttonLabel="Go" + action={() => { + if (valetudoInformation && mapData) { + const timestamp = new Date().toISOString().replaceAll(":","-").split(".")[0]; + const mapExportBlob = new Blob( + [JSON.stringify(mapData, null, 2)], + { type: "application/json" } + ); + + const linkElement = document.createElement("a"); + + linkElement.href = URL.createObjectURL(mapExportBlob); + linkElement.download = `ValetudoMapExport-${valetudoInformation.systemId}-${timestamp}.json`; + + linkElement.click(); + } + }} + actionLoading={valetudoInformationLoading || mapIsLoading} + /> + ); +}; + const MapManagement = (): JSX.Element => { const [ persistentMapControlCapabilitySupported, @@ -199,13 +248,35 @@ const MapManagement = (): JSX.Element => { mapSegmentRenameCapabilitySupported ]); + const utilityMapItems = React.useMemo(() => { + return [ + } + />, + + ]; + }, []); + return ( - + + + + ); }; diff --git a/frontend/src/settings/SettingsRouter.tsx b/frontend/src/settings/SettingsRouter.tsx index 3649544b..67848560 100644 --- a/frontend/src/settings/SettingsRouter.tsx +++ b/frontend/src/settings/SettingsRouter.tsx @@ -9,6 +9,8 @@ import Connectivity from "./connectivity/Connectivity"; import NTPConnectivity from "./connectivity/NTPConnectivity"; import AuthSettings from "./connectivity/AuthSettings"; import WifiConnectivity from "./connectivity/WifiConnectivity"; +import NetworkAdvertisementSettings from "./connectivity/NetworkAdvertisementSettings"; +import RobotCoverageMapPage from "../map/RobotCoverageMapPage"; const SettingsRouter = (): JSX.Element => { const {path} = useRouteMatch(); @@ -52,6 +54,13 @@ const SettingsRouter = (): JSX.Element => { /> } + + + + + + + @@ -61,6 +70,9 @@ const SettingsRouter = (): JSX.Element => { + + + diff --git a/frontend/src/settings/connectivity/Connectivity.tsx b/frontend/src/settings/connectivity/Connectivity.tsx index 6c0a2f3a..0c354f8f 100644 --- a/frontend/src/settings/connectivity/Connectivity.tsx +++ b/frontend/src/settings/connectivity/Connectivity.tsx @@ -6,10 +6,12 @@ import {MQTTIcon} from "../../components/CustomIcons"; import { AccessTime as NTPIcon, VpnKey as AuthIcon, - Wifi as WifiIcon + Wifi as WifiIcon, + AutoFixHigh as NetworkAdvertisementIcon } from "@mui/icons-material"; import {ListMenu} from "../../components/list_menu/ListMenu"; import {SpacerListMenuItem} from "../../components/list_menu/SpacerListMenuItem"; +import PaperContainer from "../../components/PaperContainer"; const Connectivity = (): JSX.Element => { const [ @@ -50,11 +52,21 @@ const Connectivity = (): JSX.Element => { key="ntpConnectivity" url="/settings/connectivity/ntp" primaryLabel="NTP Connectivity" - secondaryLabel="Configure Valetudos integrated Network Time Protocol (NTP) client" + secondaryLabel="Configure the integrated Network Time Protocol (NTP) client" icon={} /> ); + items.push( + } + /> + ); + items.push( { ]); return ( - + + + ); }; diff --git a/frontend/src/settings/connectivity/MQTTConnectivity.tsx b/frontend/src/settings/connectivity/MQTTConnectivity.tsx index fbb245d1..94f2ed84 100644 --- a/frontend/src/settings/connectivity/MQTTConnectivity.tsx +++ b/frontend/src/settings/connectivity/MQTTConnectivity.tsx @@ -1,5 +1,7 @@ import { Box, + Card, + CardContent, Checkbox, Collapse, Container, @@ -23,23 +25,193 @@ import { import { ArrowUpward, Visibility as VisibilityIcon, - VisibilityOff as VisibilityOffIcon + VisibilityOff as VisibilityOffIcon, + + LinkOff as MQTTDisconnectedIcon, + Link as MQTTConnectedIcon, + Sync as MQTTConnectingIcon, + Warning as MQTTErrorIcon } from "@mui/icons-material"; import React from "react"; import { MQTTConfiguration, + MQTTStatus, useMQTTConfigurationMutation, useMQTTConfigurationQuery, - useMQTTPropertiesQuery + useMQTTPropertiesQuery, + useMQTTStatusQuery } from "../../api"; import {getIn, setIn} from "../../api/utils"; -import {deepCopy} from "../../utils"; +import {convertBytesToHumans, deepCopy} from "../../utils"; import {InputProps} from "@mui/material/Input/Input"; import LoadingFade from "../../components/LoadingFade"; import InfoBox from "../../components/InfoBox"; import PaperContainer from "../../components/PaperContainer"; import {MQTTIcon} from "../../components/CustomIcons"; import {LoadingButton} from "@mui/lab"; +import TextInformationGrid from "../../components/TextInformationGrid"; + +const MQTTStatusComponent : React.FunctionComponent<{ status: MQTTStatus | undefined, statusLoading: boolean, statusError: boolean }> = ({ + status, + statusLoading, + statusError +}) => { + + if (statusLoading || !status) { + return ( + + ); + } + + if (statusError) { + return Error loading MQTT status; + } + + const getIconForState = () : JSX.Element => { + switch (status.state) { + case "disconnected": + return ; + case "ready": + return ; + case "init": + return ; + case "lost": + case "alert": + return ; + } + }; + + const getContentForState = () : JSX.Element => { + switch (status.state) { + case "disconnected": + return ( + Disconnected + ); + case "ready": + return ( + Connected + ); + case "init": + return ( + Connecting/Reconfiguring + ); + case "lost": + case "alert": + return ( + Connection error + ); + } + }; + + const getMessageStats = () : JSX.Element => { + const items = [ + { + header: "Messages Sent", + body: status.stats.messages.count.sent.toString() + }, + { + header: "Bytes Sent", + body: convertBytesToHumans(status.stats.messages.bytes.sent) + }, + { + header: "Messages Received", + body: status.stats.messages.count.received.toString() + }, + { + header: "Bytes Received", + body: convertBytesToHumans(status.stats.messages.bytes.received) + }, + ]; + + return ; + }; + + const getConnectionStats = () : JSX.Element => { + const items = [ + { + header: "Connects", + body: status.stats.connection.connects.toString() + }, + { + header: "Disconnects", + body: status.stats.connection.disconnects.toString() + }, + { + header: "Reconnects", + body: status.stats.connection.reconnects.toString() + }, + { + header: "Errors", + body: status.stats.connection.errors.toString() + }, + ]; + + return ; + }; + + + return ( + <> + + + {getIconForState()} + + + {getContentForState()} + + + + + + + Message Statistics + + + {getMessageStats()} + + + + + + + + Connection Statistics + + + {getConnectionStats()} + + + + + + + ); +}; const GroupBox = (props: { title: string, children: React.ReactNode, checked?: boolean, disabled?: boolean, onChange?: ((event: React.ChangeEvent) => void) }): JSX.Element => { @@ -92,6 +264,7 @@ const MQTTInput : React.FunctionComponent<{ required: boolean, configPath: Array, additionalProps?: InputProps + inputPostProcessor?: (value: any) => any }> = ({ mqttConfiguration, modifyMQTTConfig, @@ -101,7 +274,8 @@ const MQTTInput : React.FunctionComponent<{ helperText, required, configPath, - additionalProps + additionalProps, + inputPostProcessor }) => { const idBase = "mqtt-config-" + configPath.join("-"); const inputId = idBase + "-input"; @@ -122,7 +296,11 @@ const MQTTInput : React.FunctionComponent<{ id={inputId} value={value} onChange={(e) => { - const newValue = additionalProps?.type === "number" ? parseInt(e.target.value) : e.target.value; + let newValue = additionalProps?.type === "number" ? parseInt(e.target.value) : e.target.value; + if (inputPostProcessor) { + newValue = inputPostProcessor(newValue); + } + modifyMQTTConfig(newValue, configPath); }} aria-describedby={helperId} @@ -165,6 +343,70 @@ const MQTTSwitch : React.FunctionComponent<{ ); }; +const MQTTOptionalExposedCapabilitiesEditor : React.FunctionComponent<{ + mqttConfiguration: MQTTConfiguration, + modifyMQTTConfig: (value: any, configPath: Array) => void, + disabled: boolean, + + configPath: Array, + exposableCapabilities: Array +}> = ({ + mqttConfiguration, + modifyMQTTConfig, + disabled, + + configPath, + exposableCapabilities +}) => { + let selection: Array = getIn(mqttConfiguration, configPath); + + return ( + + + { + exposableCapabilities.map((capabilityName : string) => { + return ( + { + if (e.target.checked) { + selection.push(capabilityName); + } else { + selection = selection.filter(e => { + return e !== capabilityName; + }); + } + + modifyMQTTConfig(selection, configPath); + } + } + /> + } + disabled={disabled} + label={capabilityName} + /> + ); + }) + } + + + + ); +}; + +const sanitizeStringForMQTT = (value: string) => { + /* + This rather limited set of characters is unfortunately required by Home Assistant + Without Home Assistant, it would be enough to replace [\s+#/] + + See also: https://www.home-assistant.io/docs/mqtt/discovery/#discovery-topic + */ + return value.replace(/[^a-zA-Z0-9_-]/g,""); +}; + const MQTTConnectivity = (): JSX.Element => { const theme = useTheme(); @@ -179,6 +421,12 @@ const MQTTConnectivity = (): JSX.Element => { isError: mqttConfigurationError, } = useMQTTConfigurationQuery(); + const { + data: mqttStatus, + isLoading: mqttStatusLoading, + isError: mqttStatusError + } = useMQTTStatusQuery(); + const { data: mqttProperties, isLoading: mqttPropertiesLoading, @@ -237,6 +485,12 @@ const MQTTConnectivity = (): JSX.Element => { + + { modifyMQTTConfig(e.target.checked, ["enabled"]); @@ -405,6 +659,7 @@ const MQTTConnectivity = (): JSX.Element => { setAnchorElement(null); }, }} + inputPostProcessor={sanitizeStringForMQTT} /> @@ -428,11 +683,12 @@ const MQTTConnectivity = (): JSX.Element => { setAnchorElement(null); }, }} + inputPostProcessor={sanitizeStringForMQTT} />
The MQTT Topic structure will look like this:
- + @@ -502,6 +758,19 @@ const MQTTConnectivity = (): JSX.Element => { + { + mqttProperties.optionalExposableCapabilities.length > 0 && + + + + } + {({TransitionProps}) => { return ( @@ -529,6 +798,12 @@ const MQTTConnectivity = (): JSX.Element => {

If you're experiencing problems regarding MQTT, make sure to try Mosquitto since some other MQTT brokers only implement a subset of the MQTT spec, which often leads to issues when used with Valetudo. + +

+ If you're using Mosquitto but still experience issues, make sure that your ACLs (if any) are correct and + you're also using the correct login credentials for those. + Valetudo will not receive any feedback from the broker if publishing fails due to ACL restrictions as such feedback + simply isn't part of the MQTT v3.1.1 spec. MQTT v5 fixes this issue but isn't widely available just yet.
diff --git a/frontend/src/settings/connectivity/NTPConnectivity.tsx b/frontend/src/settings/connectivity/NTPConnectivity.tsx index 0c7b4e8e..6588fef5 100644 --- a/frontend/src/settings/connectivity/NTPConnectivity.tsx +++ b/frontend/src/settings/connectivity/NTPConnectivity.tsx @@ -42,7 +42,7 @@ const NTPClientStateComponent : React.FunctionComponent<{ state: NTPClientState } if (stateError) { - return Error loading Updater state; + return Error loading NTPClient state; } const getIconForState = () : JSX.Element => { diff --git a/frontend/src/settings/connectivity/NetworkAdvertisementSettings.tsx b/frontend/src/settings/connectivity/NetworkAdvertisementSettings.tsx new file mode 100644 index 00000000..147a753f --- /dev/null +++ b/frontend/src/settings/connectivity/NetworkAdvertisementSettings.tsx @@ -0,0 +1,146 @@ +import { + Box, + Checkbox, + Divider, + FormControlLabel, + Grid, + TextField, + Typography +} from "@mui/material"; +import React from "react"; +import { + useNetworkAdvertisementConfigurationMutation, + useNetworkAdvertisementConfigurationQuery, + useNetworkAdvertisementPropertiesQuery +} from "../../api"; +import LoadingFade from "../../components/LoadingFade"; +import {LoadingButton} from "@mui/lab"; +import InfoBox from "../../components/InfoBox"; +import PaperContainer from "../../components/PaperContainer"; +import { + AutoFixHigh as NetworkAdvertisementIcon +} from "@mui/icons-material"; + +const NetworkAdvertisementSettings = (): JSX.Element => { + const { + data: storedConfiguration, + isLoading: configurationLoading, + isError: configurationError, + } = useNetworkAdvertisementConfigurationQuery(); + + const { + data: properties, + isLoading: propertiesLoading, + isError: propertiesLoadError + } = useNetworkAdvertisementPropertiesQuery(); + + const {mutate: updateConfiguration, isLoading: configurationUpdating} = useNetworkAdvertisementConfigurationMutation(); + + const [enabled, setEnabled] = React.useState(false); + + const [configurationModified, setConfigurationModified] = React.useState(false); + + + React.useEffect(() => { + if (storedConfiguration) { + setEnabled(storedConfiguration.enabled); + } + }, [storedConfiguration]); + + if (configurationLoading || propertiesLoading) { + return ( + + ); + } + + if (configurationError || propertiesLoadError || !storedConfiguration) { + return Error loading Network Advertisement configuration; + } + + return ( + + + + + + + + + + Network Advertisement + + + + + + { + setEnabled(e.target.checked); + setConfigurationModified(true); + }} + /> + } + label="Network Advertisement enabled" + sx={{mb: 1}} + /> + + + + + + + + + When running Valetudo in embedded mode, it will advertise its presence on your local network + via both Bonjour/mDNS and SSDP/UPnP to enable other software such as the android companion app + or the windows explorer to discover it. +

+ Please note that disabling this feature will break the companion app as well as other + things that may be able to auto-discover Valetudo instances on your network. +
+
+ + + + + { + updateConfiguration({ + enabled + }); + setConfigurationModified(false); + }} + > + Save configuration + + + +
+
+
+ ); +}; + +export default NetworkAdvertisementSettings; diff --git a/frontend/src/settings/connectivity/WifiConnectivity.tsx b/frontend/src/settings/connectivity/WifiConnectivity.tsx index 14d90633..b8b25581 100644 --- a/frontend/src/settings/connectivity/WifiConnectivity.tsx +++ b/frontend/src/settings/connectivity/WifiConnectivity.tsx @@ -20,6 +20,7 @@ import { import React from "react"; import { useWifiConfigurationMutation, + useWifiConfigurationPropertiesQuery, useWifiStatusQuery, WifiStatus } from "../../api"; @@ -42,6 +43,7 @@ import { } from "@mui/icons-material"; import PaperContainer from "../../components/PaperContainer"; import ConfirmationDialog from "../../components/ConfirmationDialog"; +import InfoBox from "../../components/InfoBox"; const StyledLoadingButton = styled(LoadingButton)(({theme}) => { @@ -178,8 +180,18 @@ const WifiConnectivity = (): JSX.Element => { refetch: refetchWifiStatus, } = useWifiStatusQuery(); + const { + data: properties, + isLoading: propertiesLoading, + isError: propertiesLoadError + } = useWifiConfigurationPropertiesQuery(); + - const {mutate: updateConfiguration, isLoading: configurationUpdating} = useWifiConfigurationMutation(); + const {mutate: updateConfiguration, isLoading: configurationUpdating} = useWifiConfigurationMutation({ + onSuccess: () => { + setFinalDialogOpen(true); + } + }); const [newSSID, setNewSSID] = React.useState(""); const [newPSK, setNewPSK] = React.useState(""); @@ -190,13 +202,13 @@ const WifiConnectivity = (): JSX.Element => { const [finalDialogOpen, setFinalDialogOpen] = React.useState(false); - if (wifiStatusLoading) { + if (wifiStatusLoading || propertiesLoading) { return ( ); } - if (wifiStatusLoadError || !wifiStatus) { + if (wifiStatusLoadError || !wifiStatus || propertiesLoadError || !properties) { return Error loading Wi-Fi Status; } @@ -242,67 +254,93 @@ const WifiConnectivity = (): JSX.Element => { Change Wi-Fi configuration - - - { - setNewSSID(e.target.value); - setConfigurationModified(true); - }} - /> - - - - PSK/Password - - { - setShowPasswordAsPlain(!showPasswordAsPlain); - }} - onMouseDown={e => { - e.preventDefault(); - }} - edge="end" - > - {showPasswordAsPlain ? : } - - - } - onChange={(e) => { - setNewPSK(e.target.value); + { + properties.provisionedReconfigurationSupported && + + + { + setNewSSID(e.target.value); setConfigurationModified(true); - }}/> - + }} + /> + + + + PSK/Password + + { + setShowPasswordAsPlain(!showPasswordAsPlain); + }} + onMouseDown={e => { + e.preventDefault(); + }} + edge="end" + > + {showPasswordAsPlain ? : } + + + } + onChange={(e) => { + setNewPSK(e.target.value); + setConfigurationModified(true); + }}/> + + - + } + + { + !properties.provisionedReconfigurationSupported && + + + To connect your robot to a different Wi-Fi network, you need to do a Wi-Fi reset. +

+ Note that the procedure is different depending on your model of robot, so please refer to the relevant documentation to figure out how to do that. + After having done that, simply connect to the Wi-Fi AP provided by the robot and then either use the Valetudo Webinterface + or the Companion app to enter new Wi-Fi credentials. +
+
+ } - - - { - setConfirmationDialogOpen(true); - }} - > - Save configuration - + + { + properties.provisionedReconfigurationSupported && + + + { + setConfirmationDialogOpen(true); + }} + > + Save configuration + + - + } { setConfirmationDialogOpen(false); }} onAccept={() => { - setFinalDialogOpen(true); updateConfiguration({ ssid: newSSID, credentials: { @@ -328,7 +365,10 @@ const WifiConnectivity = (): JSX.Element => { Are you sure you want to apply the new Wifi settings?
- Hint: You can always revert back to the integrated Wifi Hotspot. +
+ Hint: +
+ You can always revert back to the integrated Wifi Hotspot. Check the documentation supplied with your robot for instructions on how to do so.
diff --git a/frontend/src/settings/res/MapManagementHelp.ts b/frontend/src/settings/res/MapManagementHelp.ts index 973a4830..e9dfcc60 100644 --- a/frontend/src/settings/res/MapManagementHelp.ts +++ b/frontend/src/settings/res/MapManagementHelp.ts @@ -31,14 +31,4 @@ On most firmwares, the robot uses the segment data to optimize its navigation an Zones are just rectangles that you can draw on the map to send the robot there. Depending on the firmware of your robot, it might accept just one or multiple zones as an input. - -#### Zone Presets - -Zone Presets are named presets containing one or multiple zones stored by Valetudo, -which can be triggered either by the UI or via MQTT. - -#### GoTo Locations - -GoTo locations are basically the same as zone presets with the difference being that it is a single spot instead -of an area. You can trigger these either by the UI or via MQTT. `; diff --git a/frontend/src/settings/res/MapUtilitiesHelp.ts b/frontend/src/settings/res/MapUtilitiesHelp.ts new file mode 100644 index 00000000..a868588f --- /dev/null +++ b/frontend/src/settings/res/MapUtilitiesHelp.ts @@ -0,0 +1,6 @@ +export const MapUtilitiesHelp = ` +## Map Utilities + +In this section, you will find useful things built on top of the map data provided by the robot. + +`; diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index 5aa63fa9..ab9a6e37 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -2,7 +2,7 @@ import {ValetudoDataPoint} from "./api"; export function convertSecondsToHumans(seconds: number, showSeconds = true, showDays = true): string { - let levels = []; + let levels; if (showDays) { levels = [ @@ -62,6 +62,42 @@ export function convertSecondsToHumans(seconds: number, showSeconds = true, show return humanReadableTimespan.trim(); } +export function convertBytesToHumans(bytes: number): string { + if (bytes >= 1024*1024*1024) { + return `${(((bytes/1024)/1024)/1024).toFixed(2)} GiB`; + } else if (bytes >= 1024*1024) { + return `${((bytes/1024)/1024).toFixed(2)} MiB`; + } else if (bytes >= 1024) { + return `${(bytes/1024).toFixed(2)} KiB`; + } else { + return `${bytes} bytes`; + } +} + +//Adapted from https://stackoverflow.com/a/41358305 +export function convertNumberToRoman(num: number): string { + const symbols: Record = { + XC: 90, + L: 50, + XL: 40, + X: 10, + IX: 9, + V: 5, + IV: 4, + I: 1 + }; + let str = ""; + + for (const i of Object.keys(symbols)) { + const quantity = Math.floor(num / symbols[i]); + + num -= quantity * symbols[i]; + str += i.repeat(quantity); + } + + return str; +} + // Adapted from https://gist.github.com/erikvullings/ada7af09925082cbb89f40ed962d475e export const deepCopy = (target: T): T => { if (target === null) { @@ -93,11 +129,13 @@ const consumableTypeMapping: Record = { "brush": "Brush", "filter": "Filter", "sensor": "Sensor cleaning", - "mop": "Mop" + "mop": "Mop", + "detergent": "Detergent" }; const consumableSubtypeMapping: Record = { "main": "Main", + "secondary": "Secondary", "side_right": "Right", "side_left": "Left", "all": "", @@ -164,9 +202,9 @@ export function adjustColorBrightness(hexInput: string, percent: number) : strin hex = hex.replace(/(.)/g, "$1$1"); } - let r = parseInt(hex.substr(0, 2), 16); - let g = parseInt(hex.substr(2, 2), 16); - let b = parseInt(hex.substr(4, 2), 16); + let r = parseInt(hex.slice(0, 2), 16); + let g = parseInt(hex.slice(2, 4), 16); + let b = parseInt(hex.slice(4, 6), 16); const calculatedPercent = (100 + percent) / 100; diff --git a/frontend/src/valetudo/Log.tsx b/frontend/src/valetudo/Log.tsx index f839b510..c44fdad8 100644 --- a/frontend/src/valetudo/Log.tsx +++ b/frontend/src/valetudo/Log.tsx @@ -146,7 +146,7 @@ const Log = (): JSX.Element => { inputProps={{ "aria-label": "filter", value: filter, - onChange: (e) => { + onChange: (e: any) => { setFilter((e.target as HTMLInputElement).value); } }} @@ -176,8 +176,14 @@ const Log = (): JSX.Element => { { - logLevelRefetch().then(); - logRefetch().then(); + logLevelRefetch().catch(err => { + // eslint-disable-next-line no-console + console.error(err); + }); + logRefetch().catch(err => { + // eslint-disable-next-line no-console + console.error(err); + }); }} title="Refresh" > diff --git a/frontend/src/valetudo/SystemInformation.tsx b/frontend/src/valetudo/SystemInformation.tsx index 70bd0c91..94aaf0c9 100644 --- a/frontend/src/valetudo/SystemInformation.tsx +++ b/frontend/src/valetudo/SystemInformation.tsx @@ -28,6 +28,8 @@ import { useSystemHostInfoQuery, useSystemRuntimeInfoQuery, useValetudoVersionQuery, + useRobotPropertiesQuery, + useValetudoInformationQuery, } from "../api"; import RatioBar from "../components/RatioBar"; import {convertSecondsToHumans} from "../utils"; @@ -35,12 +37,15 @@ import {useIsMobileView} from "../hooks"; import ReloadableCard from "../components/ReloadableCard"; import LoadingFade from "../components/LoadingFade"; import PaperContainer from "../components/PaperContainer"; +import TextInformationGrid from "../components/TextInformationGrid"; const ThickLinearProgressWithTopMargin = styled(LinearProgress)({ marginTop: "2px", height: "6px" }); + + const SystemRuntimeInfo = (): JSX.Element => { const { data: systemRuntimeInfo, @@ -227,53 +232,100 @@ const SystemInformation = (): JSX.Element => { data: version, isLoading: versionLoading, } = useValetudoVersionQuery(); + const { + data: valetudoInformation, + isLoading: valetudoInformationLoading + } = useValetudoInformationQuery(); const { data: systemHostInfo, isLoading: systemHostInfoLoading, isFetching: systemHostInfoFetching, refetch: fetchSystemHostInfo, } = useSystemHostInfoQuery(); + const { + data: robotProperties, + isLoading: robotPropertiesLoading + } = useRobotPropertiesQuery(); + + const valetudoInformationViewLoading = versionLoading || valetudoInformationLoading; + + const valetudoInformationView = React.useMemo(() => { + if (valetudoInformationViewLoading) { + return ( + + ); + } - const systemLoading = robotInformationLoading || versionLoading || systemHostInfoLoading; + if (!version && !valetudoInformation) { + return No valetudo information; + } + + const items = [ + { + header: "Release", + body: version?.release + }, + { + header: "Commit", + body: version?.commit + }, + { + header: "Embedded", + body: valetudoInformation?.embedded ? "true" : "false" + }, + { + header: "System ID", + body: valetudoInformation?.systemId + } + ].filter(item => { + return item.body !== undefined; + }) as Array<{header: string, body: string}>; + + return ( + + ); + }, [valetudoInformationViewLoading, version, valetudoInformation]); - const systemInformation = React.useMemo(() => { - if (systemLoading) { + + const robotInformationViewLoading = robotInformationLoading || robotPropertiesLoading; + + const robotInformationView = React.useMemo(() => { + if (robotInformationViewLoading) { return ( ); } - if (!robotInformation || !version) { + if (!robotInformation && !robotProperties) { return No robot information; } - const items: Array<[header: string, body: string]> = [ - ["Manufacturer", robotInformation.manufacturer], - ["Model", robotInformation.modelName], - ["Valetudo Implementation", robotInformation.implementation], - ["Release", version.release], - ["Commit", version.commit], - ]; + const items = [ + { + header: "Manufacturer", + body: robotInformation?.manufacturer + }, + { + header: "Model", + body: robotInformation?.modelName + }, + { + header: "Valetudo Implementation", + body: robotInformation?.implementation + }, + { + header: "Firmware Version", + body: robotProperties?.firmwareVersion + } + ].filter(item => { + return item.body !== undefined; + }) as Array<{header: string, body: string}>; return ( - - {items.map(([header, body]) => { - return ( - - - {header} - - {body} - - ); - })} - + ); - }, [robotInformation, systemLoading, version]); + + }, [robotInformation, robotInformationViewLoading, robotProperties]); const systemHostInformation = React.useMemo(() => { if (systemHostInfoLoading) { @@ -383,10 +435,26 @@ const SystemInformation = (): JSX.Element => { > - System + Robot + + + {robotInformationView} + + + + + + + + Valetudo - {systemInformation} + {valetudoInformationView} diff --git a/frontend/src/valetudo/res/HelpText.ts b/frontend/src/valetudo/res/HelpText.ts index bd613a64..e0b73da2 100644 --- a/frontend/src/valetudo/res/HelpText.ts +++ b/frontend/src/valetudo/res/HelpText.ts @@ -15,4 +15,9 @@ If you zoom in on a segment label, it will display the segment ID, its name and Just tap on the bar at the bottom of the screen. +### How do I get the coordinates/parameters of segments/zones/go-to locations to trigger them via MQTT/REST? + +Simply configure/select the segments/zones/go-to locations like you'd normally do and then long-press the button that would start the action. +This will bring up a dialog providing you with everything you'll need. + `; diff --git a/frontend/src/valetudo/timers/ActionControls.tsx b/frontend/src/valetudo/timers/ActionControls.tsx index 96a22912..75093904 100644 --- a/frontend/src/valetudo/timers/ActionControls.tsx +++ b/frontend/src/valetudo/timers/ActionControls.tsx @@ -2,10 +2,8 @@ import React, { FunctionComponent } from "react"; import { TimerActionControlProps } from "./types"; import { Capability, - useGoToLocationPresetsQuery, useMapSegmentationPropertiesQuery, useSegmentsQuery, - useZonePresetsQuery, } from "../../api"; import { Box, @@ -34,80 +32,21 @@ export const validateParams: Record< full_cleanup: () => { return true; }, - zone_cleanup: (props) => { - return props.zone_id && props.zone_id !== "none"; - }, segment_cleanup: (props) => { return props.segment_ids?.length > 0 && (props.iterations ?? 1 > 0); }, - goto_location: (props) => { - return props.goto_id && props.goto_id !== "none"; - }, }; -export const FullCleanupControls: FunctionComponent = +export const FallbackControls: FunctionComponent = () => { - // No params for full_cleanup - return null; + return The currently configured action does not exist. Please select a different action.; }; -export const ZoneCleanupControls: FunctionComponent = - ({ disabled, params, setParams }) => { - const selectedZoneId = params.zone_id ?? "none"; - - const { - data: zonePresets, - isLoading: zonePresetsLoading, - isError: zonePresetsError, - } = useZonePresetsQuery(); - - const zoneMenuItems = React.useMemo(() => { - if (!zonePresets) { - return null; - } - return zonePresets.map(({ name, id }) => { - return ( - - {name || "Unnamed zone: " + id} - - ); - }); - }, [zonePresets]); - if (zonePresetsLoading) { - return ; - } - - if (zonePresetsError) { - return ( - - Error loading {Capability.ZoneCleaning} - - ); - } - - return ( - - Select zone - - - ); +export const FullCleanupControls: FunctionComponent = + () => { + // No params for full_cleanup + return null; }; export const SegmentCleanupControls: FunctionComponent = @@ -318,64 +257,3 @@ export const SegmentCleanupControls: FunctionComponent ); }; - -export const GoToLocationControls: FunctionComponent = - ({ params, setParams, disabled }) => { - const selectedGoToId = params.goto_id ?? "none"; - - const { - data: goToLocations, - isLoading: goToLocationPresetsLoading, - isError: goToLocationPresetLoadError, - } = useGoToLocationPresetsQuery(); - - const goToMenuItems = React.useMemo(() => { - if (!goToLocations) { - return null; - } - return goToLocations.map(({ name, id }) => { - return ( - - {name || "Unnamed go to location: " + id} - - ); - }); - }, [goToLocations]); - - if (goToLocationPresetsLoading) { - return ; - } - - if (goToLocationPresetLoadError) { - return ( - - Error loading {Capability.GoToLocation} - - ); - } - - return ( - - - Select go to location - - - - ); - }; diff --git a/frontend/src/valetudo/timers/TimerCard.tsx b/frontend/src/valetudo/timers/TimerCard.tsx index 27ede3a7..8449a066 100644 --- a/frontend/src/valetudo/timers/TimerCard.tsx +++ b/frontend/src/valetudo/timers/TimerCard.tsx @@ -21,13 +21,34 @@ import { Timer, TimerProperties } from "../../api"; import TimerEditDialog from "./TimerEditDialog"; export const weekdays = [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", + { + label: "Monday", + dow: 1 + }, + { + label: "Tuesday", + dow: 2 + }, + { + label: "Wednesday", + dow: 3 + }, + { + label: "Thursday", + dow: 4 + }, + { + label: "Friday", + dow: 5 + }, + { + label: "Saturday", + dow: 6 + }, + { + label: "Sunday", + dow: 0 + }, ]; type TimerCardProps = { @@ -39,9 +60,7 @@ type TimerCardProps = { export const timerActionLabels: Record = { full_cleanup: "Full cleanup", - zone_cleanup: "Zone cleanup", segment_cleanup: "Segment cleanup", - goto_location: "Go to location", }; function convertTime(hour: number, minute: number, offset: number) : { hour: number, minute: number } { @@ -73,17 +92,17 @@ const TimerCard: FunctionComponent = ({ const weekdayLabels = React.useMemo(() => { return weekdays.map((day, i) => { - const enabled = timer.dow.includes(i); + const enabled = timer.dow.includes(day.dow); return ( - {day.toUpperCase().slice(0, 3)} + {day.label.toUpperCase().slice(0, 3)} ); }); diff --git a/frontend/src/valetudo/timers/TimerEditDialog.tsx b/frontend/src/valetudo/timers/TimerEditDialog.tsx index c79e3078..2b84ec7f 100644 --- a/frontend/src/valetudo/timers/TimerEditDialog.tsx +++ b/frontend/src/valetudo/timers/TimerEditDialog.tsx @@ -24,11 +24,10 @@ import { timerActionLabels, weekdays } from "./TimerCard"; import { StaticTimePicker } from "@mui/lab"; import { TimerActionControlProps } from "./types"; import { + FallbackControls, FullCleanupControls, - GoToLocationControls, SegmentCleanupControls, validateParams, - ZoneCleanupControls, } from "./ActionControls"; const actionControls: Record< @@ -36,9 +35,7 @@ const actionControls: Record< React.ComponentType > = { full_cleanup: FullCleanupControls, - zone_cleanup: ZoneCleanupControls, segment_cleanup: SegmentCleanupControls, - goto_location: GoToLocationControls, }; type TimerDialogProps = { @@ -68,50 +65,60 @@ const TimerEditDialog: FunctionComponent = ({ }, [timer]); React.useEffect(() => { - setValidAction( - validateParams[editTimer.action.type](editTimer.action.params) - ); + if (validateParams[editTimer.action.type] !== undefined) { + setValidAction( + validateParams[editTimer.action.type](editTimer.action.params) + ); + } else { + setValidAction(false); + } }, [editTimer, open]); const setActionParams = React.useCallback( - (newParams) => { - setValidAction(validateParams[editTimer.action.type](newParams)); + (newParams: any) => { + if (validateParams[editTimer.action.type] !== undefined) { + setValidAction(validateParams[editTimer.action.type](newParams)); + } else { + setValidAction(false); + } + const newTimer = deepCopy(editTimer); newTimer.action.params = newParams; + setEditTimer(newTimer); }, [editTimer] ); const weekdayCheckboxes = React.useMemo(() => { - const checkboxes = weekdays.map((weekday, i) => { + const checkboxes = weekdays.map((weekday) => { if (!narrowScreen) { return ( - {weekday} + {weekday.label} ); } else { return ( { const newTimer = deepCopy(editTimer); if (e.target.checked) { - if (newTimer.dow.indexOf(i) === -1) { - newTimer.dow.push(i); + if (newTimer.dow.indexOf(weekday.dow) === -1) { + newTimer.dow.push(weekday.dow); } } else { - const idx = newTimer.dow.indexOf(i); + const idx = newTimer.dow.indexOf(weekday.dow); if (idx !== -1) { newTimer.dow.splice(idx, 1); } @@ -120,8 +127,8 @@ const TimerEditDialog: FunctionComponent = ({ }} /> } - label={weekday} - aria-label={weekday} + label={weekday.label} + aria-label={weekday.label} /> ); } @@ -166,7 +173,8 @@ const TimerEditDialog: FunctionComponent = ({ return date; }, [editTimer]); - const ActionControl = actionControls[editTimer.action.type]; + const ActionControl = actionControls[editTimer.action.type] ?? FallbackControls; + const CurrentBrowserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; return (

@@ -196,7 +204,7 @@ const TimerEditDialog: FunctionComponent = ({ = ({ newTimer.action.type = e.target.value; newTimer.action.params = {}; setEditTimer(newTimer); - setValidAction( - validateParams[newTimer.action.type]( - newTimer.action.params - ) - ); + + if (validateParams[newTimer.action.type] !== undefined) { + setValidAction( + validateParams[newTimer.action.type]( + newTimer.action.params + ) + ); + } else { + setValidAction(false); + } }} > {propertyMenuItems} diff --git a/frontend/src/valetudo/timers/res/TimersHelp.ts b/frontend/src/valetudo/timers/res/TimersHelp.ts index e5a37e42..d2863f9f 100644 --- a/frontend/src/valetudo/timers/res/TimersHelp.ts +++ b/frontend/src/valetudo/timers/res/TimersHelp.ts @@ -9,10 +9,6 @@ If that is disabled or unable to reach the configured NTP server, no timers will **Please note that timers are evaluated and stored as UTC. They are only displayed in your current browser timezone for your convenience.** -**If your country/state is taking part in that nonsensical Daylight Saving Time cult, you will have to -manually shift the timers back and forth each time you switch from and to DST.** - - Timers in Valetudo are provided as a convenience feature.
It is **highly recommended** to deploy a full-scale home automation system such as openHAB or Home Assistant to allow for better scheduled operation taking into account e.g. whether or not a room is currently occupied, you're currently on vacation etc. diff --git a/matrix.json b/matrix.json new file mode 100644 index 00000000..5d9b841f --- /dev/null +++ b/matrix.json @@ -0,0 +1,58 @@ +{ + "include": [ + { + "build_from": "arm32v7/alpine:3.14", + "image_name": "alpine-armv7", + "pkg_options": "expose-gc,max-heap-size=38", + "pkg_target": "node16-linuxstatic-armv7" + }, + { + "build_from": "arm64v8/alpine:3.14", + "image_name": "alpine-aarch64", + "pkg_options": "expose-gc,max-heap-size=64", + "pkg_target": "node16-linuxstatic-arm64" + }, + { + "build_from": "amd64/alpine:3.14", + "image_name": "alpine-amd64", + "pkg_options": "expose-gc,max-heap-size=64", + "pkg_target": "node16-linuxstatic-x64" + }, + { + "build_from": "i386/alpine:3.14", + "image_name": "alpine-i386", + "pkg_options": "expose-gc,max-heap-size=64", + "pkg_target": "node16-linuxstatic-x64" + }, + { + "build_from": "homeassistant/armhf-base:3.14", + "image_name": "homeassistant-armhf", + "pkg_options": "expose-gc,max-heap-size=38", + "pkg_target": "node16-linuxstatic-armv7" + }, + { + "build_from": "homeassistant/armv7-base:3.14", + "image_name": "homeassistant-armv7", + "pkg_options": "expose-gc,max-heap-size=38", + "pkg_target": "node16-linuxstatic-armv7" + }, + { + "build_from": "homeassistant/aarch64-base:3.14", + "image_name": "homeassistant-aarch64", + "pkg_options": "expose-gc,max-heap-size=64", + "pkg_target": "node16-linuxstatic-arm64" + }, + { + "build_from": "homeassistant/amd64-base:3.14", + "image_name": "homeassistant-amd64", + "pkg_options": "expose-gc,max-heap-size=64", + "pkg_target": "node16-linuxstatic-x64" + }, + { + "build_from": "homeassistant/i386-base:3.14", + "image_name": "homeassistant-i386", + "pkg_options": "expose-gc,max-heap-size=64", + "pkg_target": "node16-linuxstatic-x64" + } + ] +} diff --git a/old_frontend/.eslintignore b/old_frontend/.eslintignore deleted file mode 100644 index 17440724..00000000 --- a/old_frontend/.eslintignore +++ /dev/null @@ -1,7 +0,0 @@ -// ignore external libraries -/lib/js/onsenui.js -/lib/js/onsenui.min.js -/lib/js/angular-onsenui.js -/lib/js/angular-onsenui.min.js -/lib/js/geometry-polyfill.js -/lib/zone/geometry-polyfill.js diff --git a/old_frontend/.eslintrc b/old_frontend/.eslintrc deleted file mode 100644 index 71b8728c..00000000 --- a/old_frontend/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-console": "off", - "max-classes-per-file": "off" - } -} \ No newline at end of file diff --git a/old_frontend/jsconfig.json b/old_frontend/jsconfig.json deleted file mode 100644 index ca488d6c..00000000 --- a/old_frontend/jsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "checkJs": true, - "module": "commonJS", - "target": "es6", - "lib": ["es2019", "dom"], - "moduleResolution": "node", - "sourceMap": true, - "alwaysStrict": true, - "resolveJsonModule": true - }, - "include": ["lib/services", "global.d.ts"] -} diff --git a/old_frontend/lib/Readme.md b/old_frontend/lib/Readme.md deleted file mode 100644 index 43436a48..00000000 --- a/old_frontend/lib/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -The page is pretty much just the onsenUI demo hackishly modified for this usecase. - -At some point someone should optimize this. diff --git a/old_frontend/lib/about.html b/old_frontend/lib/about.html deleted file mode 100644 index 0727bad8..00000000 --- a/old_frontend/lib/about.html +++ /dev/null @@ -1,25 +0,0 @@ - - -
- Home -
-
About
-
- -

Valetudo - Free your vacuum from the cloud

-

- Another IoT Smarthome Node.js project by Hypfer. -
-
- Thanks to all contributors: -
- - https://github.com/Hypfer/Valetudo/graphs/contributors - -
-
- -

-

Made with ♥ for Castrop-Rauxel

-
-
\ No newline at end of file diff --git a/old_frontend/lib/apple-touch-icon.png b/old_frontend/lib/apple-touch-icon.png deleted file mode 100644 index fef14b7c..00000000 Binary files a/old_frontend/lib/apple-touch-icon.png and /dev/null differ diff --git a/old_frontend/lib/css/dark-onsen-css-components.min.css b/old_frontend/lib/css/dark-onsen-css-components.min.css deleted file mode 100644 index dbe698b2..00000000 --- a/old_frontend/lib/css/dark-onsen-css-components.min.css +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * Copyright 2013-2017 ASIAL CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *//*! - * Copyright 2012 Adobe Systems Inc.; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */.notification,.toolbar,body{overflow:hidden}.notification,.toolbar{-webkit-user-select:none;-ms-user-select:none}a,body,button,input,select,textarea{touch-action:manipulation}.page,.page__background,.page__content{background-color:#0d0d0d;position:absolute}.page,body{position:absolute}.page,.page--material,.page--material__content{font-weight:400}.switch,.switch__input{vertical-align:top;z-index:0}.page,.switch__input,.switch__toggle,body{top:0;left:0;right:0;bottom:0}.switch,.switch__handle{background-clip:padding-box;box-sizing:border-box}.switch__handle,.switch__toggle{transition-property:all;transition-duration:.35s}:disabled+.switch--material__toggle,:disabled+.switch__toggle{opacity:.3;cursor:default;pointer-events:none}.switch--material__handle:before,.switch__handle,.tabbar--material__button:after{content:''}.range__focus-ring,.range__input,.switch,.switch__handle{box-sizing:border-box}html{height:100%;width:100%}body{padding:0;margin:0;-webkit-text-size-adjust:100%}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}input,select,textarea{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto;-moz-user-select:text;-webkit-touch-callout:none}.notification,.toolbar{-moz-user-select:none;-moz-osx-font-smoothing:grayscale}input:active,input:focus,select:active,select:focus,textarea:active,textarea:focus{outline:0}h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4,h5,h6{font-size:18px}.page{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-moz-osx-font-smoothing:grayscale;overflow-x:visible;overflow-y:hidden;color:#fff;-ms-overflow-style:none;-webkit-font-smoothing:antialiased}.page--material,.page--material__content,.page__content h1,.page__content h2,.page__content h3,.page__content h4,.page__content h5{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.page::-webkit-scrollbar{display:none}.page__background,.page__content{top:0;left:0;right:0;bottom:0;box-sizing:border-box}.page--material,.page--material__background{background-color:#303030}.page__content h1,.page__content h2,.page__content h3,.page__content h4,.page__content h5{font-weight:400;font-weight:500;margin:.6em 0;padding:0}.page__content h1{font-size:28px}.page__content h2{font-size:24px}.page__content h3{font-size:20px}.page--material__content h1,.page--material__content h2,.page--material__content h3,.page--material__content h4,.page--material__content h5{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;font-weight:500;margin:.6em 0;padding:0}.page--material__content h1{font-size:28px}.page--material__content h2{font-size:24px}.page--material__content h3{font-size:20px}.switch{display:inline-block;position:relative;min-width:51px;font-size:17px;padding:0 20px;border:none;overflow:visible;width:51px;height:32px;text-align:left}.switch__input{position:absolute;padding:0;border:0;background-color:transparent;outline:0;width:100%;height:100%;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.range__input,.switch--material__input{outline:0;-webkit-appearance:none;vertical-align:top}.switch__toggle{background-color:#0d0d0d;position:absolute;border-radius:30px;transition-timing-function:ease-out;box-shadow:inset 0 0 0 2px #666}.switch__handle{position:absolute;border-radius:28px;height:28px;width:28px;background-color:#fff;left:1px;top:2px;transition-timing-function:cubic-bezier(.59,.01,.5,.99);box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25)}.switch--active__handle{transition:none}:checked+.switch__toggle{box-shadow:inset 0 0 0 2px #0076FF;background-color:#0076FF}:checked+.switch__toggle>.switch__handle{left:21px;box-shadow:0 3px 2px rgba(0,0,0,.25)}.switch__touch{position:absolute;top:-5px;bottom:-5px;left:-10px;right:-10px}.switch--material{width:36px;height:24px;padding:0 10px;min-width:36px}.switch--material__toggle{background-color:rgba(255,255,255,.3);margin-top:5px;height:14px;box-shadow:none}.switch--material__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;width:100%;height:100%;margin:0;-moz-appearance:none;appearance:none;z-index:0}.switch--material__handle{background-color:#bdbdbd;left:0;margin-top:-5px;width:20px;height:20px;box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4)}:checked+.switch--material__toggle{background-color:rgba(255,193,7,.5);box-shadow:none}.button--material,:checked+.switch--material__toggle>.switch--material__handle{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}:checked+.switch--material__toggle>.switch--material__handle{left:16px;background-color:#0076FF}.switch--material__handle:before{background:0 0;display:block;width:100%;height:100%;border-radius:50%;z-index:0;box-shadow:0 0 0 0 rgba(0,0,0,.12);transition:box-shadow .1s linear}.switch--material__toggle>.switch--active__handle:before{box-shadow:0 0 0 14px rgba(0,0,0,.12)}:checked+.switch--material__toggle>.switch--active__handle:before{box-shadow:0 0 0 14px rgba(255,193,7,.2)}.switch--material__touch{position:absolute;top:-10px;bottom:-10px;left:-15px;right:-15px}.range,.range__input{height:30px;position:relative;padding:0;margin:0}.range{display:inline-block;width:100px;background-image:linear-gradient(#6b6f74,#6b6f74);background-position:left center;background-size:100% 2px;background-repeat:no-repeat;background-color:transparent}.range__input{font:inherit;color:inherit;background:left center no-repeat;border:none;line-height:1;-moz-appearance:none;appearance:none;background-image:linear-gradient(#bbb,#bbb);background-size:0 2px;z-index:1;width:100%}.range__input::-moz-range-track{position:relative;border:none;background:0 0;box-shadow:none;top:0;margin:0;padding:0}.range__input::-ms-track{position:relative;border:none;background-color:#6b6f74;height:0;border-radius:50%}.range__input::-webkit-slider-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0;box-sizing:border-box;-webkit-appearance:none;appearance:none;top:0;z-index:1}.range__focus-ring,.segment__input{-moz-appearance:none;top:0;outline:0}.range__input::-moz-range-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0}.range__input::-ms-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0;top:0}.range__input::-ms-fill-lower{height:2px;background-color:#bbb}.range__input::-ms-tooltip{display:none}.range__input:disabled{opacity:1;pointer-events:none}.range__focus-ring{pointer-events:none;left:0;display:none;padding:0;margin:0;font:inherit;color:inherit;border:none;vertical-align:top;line-height:1;-webkit-appearance:none;appearance:none;background:0 0;height:30px;position:absolute;z-index:0;width:100%}.notification,.toolbar__item{box-sizing:border-box;font:inherit}.range--disabled{opacity:.3;cursor:default;pointer-events:none}.range--material{position:relative;background-image:linear-gradient(#525252,#525252)}.range--material__input{background-image:linear-gradient(#cecec5,#cecec5);background-position:center left;background-size:0 2px}.range--material__focus-ring{display:block}.range--material__focus-ring::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border:none;box-shadow:0 0 0 9px #cecec5;background-color:#cecec5;border-radius:50%;opacity:0;transition:opacity .25s ease-out,-webkit-transform .25s ease-out;transition:opacity .25s ease-out,transform .25s ease-out;transition:opacity .25s ease-out,transform .25s ease-out,-webkit-transform .25s ease-out}.range--material__input.range__input--active+.range--material__focus-ring::-webkit-slider-thumb{opacity:.2;-webkit-transform:scale(1.5,1.5,1.5);transform:scale(1.5,1.5,1.5)}.range--material__input::-webkit-slider-thumb{position:relative;box-sizing:border-box;border:none;background-color:transparent;width:14px;height:32px;border-radius:0;box-shadow:none;background-image:radial-gradient(circle farthest-corner,#cecec5 0,#cecec5 6.6px,transparent 7px);transition:-webkit-transform .1s linear;transition:transform .1s linear;transition:transform .1s linear,-webkit-transform .1s linear;overflow:visible}.range--material__input[_zero]::-webkit-slider-thumb{background-image:radial-gradient(circle farthest-corner,#0d0d0d 0,#0d0d0d 4px,#525252 4px,#525252 6.4px,transparent 7px)}.range--material__input[_zero]+.range--material__focus-ring::-webkit-slider-thumb{box-shadow:0 0 0 9px #525252}.bottom-bar,.toolbar{white-space:nowrap;word-spacing:0;cursor:default;box-shadow:none;border-bottom:none;z-index:2}.range--material__input::-moz-range-track{background:0 0}.range--material__input::-moz-range-thumb,.range--material__input:focus::-moz-range-thumb{box-sizing:border-box;border:none;width:14px;height:32px;border-radius:0;background-color:transparent;background-image:-moz-radial-gradient(circle farthest-corner,#cecec5 0,#cecec5 6.6px,transparent 7px);box-shadow:none}.range--material__input.range__input--active::-webkit-slider-thumb,.range--material__input:active::-webkit-slider-thumb{-webkit-transform:scale(1.5);transform:scale(1.5);transition:-webkit-transform .1s linear;transition:transform .1s linear;transition:transform .1s linear,-webkit-transform .1s linear}.button,.button:active,.button:hover{transition:none}.range--disabled.range--material{opacity:1}.range--disabled>.range--material__input{background-image:none}.range--material__input:disabled::-webkit-slider-thumb{background-image:radial-gradient(circle farthest-corner,#4f4f4f 0,#4f4f4f 4px,#303030 4.4px,#303030 7.6px,transparent 7.6px);transition:none}.range--material__input:disabled::-moz-range-thumb{background-image:-moz-radial-gradient(circle farthest-corner,#4f4f4f 0,#4f4f4f 4px,#303030 4.4px,#303030 7.6px,transparent 7.6px);transition:none}.notification{position:relative;display:inline-block;vertical-align:top;background:#fe3824;border:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;cursor:default;user-select:none;text-overflow:ellipsis;white-space:nowrap;text-decoration:none;margin:0;padding:0 4px;width:auto;height:19px;border-radius:19px;color:#fff;text-align:center;font-size:16px;min-width:19px;line-height:19px;font-weight:400}.notification--material,.toolbar{-webkit-font-smoothing:antialiased;color:#fff}.toolbar,.toolbar__item{padding:0;margin:0;border:none;height:44px}.notification:empty{display:none}.bottom-bar--aligned,.toolbar{display:-webkit-box;display:-webkit-flex}.notification--material{font-family:Roboto,Noto,sans-serif;background-color:#f50057;font-size:16px;font-weight:500}.toolbar{font:inherit;line-height:normal;user-select:none;display:flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;background:bottom no-repeat #181818;font-weight:400;width:100%;background-size:100% 1px;background-image:linear-gradient(0deg,#242424,#242424 100%)}.bottom-bar,.button{-ms-user-select:none}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.toolbar{background-image:linear-gradient(0deg,#242424,#242424 50%,transparent 50%)}}.toolbar__bg{background:#181818}.toolbar__item{color:inherit;background:0 0;line-height:normal;overflow:visible;display:block;vertical-align:middle}.toolbar__left,.toolbar__right{padding:0;margin:0;font:inherit;color:inherit;max-width:50%;width:27%;box-sizing:border-box;border:none;background:0 0}.toolbar__left{text-align:left;line-height:44px}.toolbar__right{text-align:right;line-height:44px}.bottom-bar,.toolbar__center,.toolbar__title{margin:0;color:#fff;padding:0}.toolbar__center{box-sizing:border-box;font:inherit;background:0 0;border:none;width:46%;text-align:center;line-height:44px;font-size:17px;font-weight:500}.toolbar__title{line-height:44px;font-size:17px;font-weight:500;overflow:visible}.toolbar__center:first-child:last-child{width:100%}.bottom-bar{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow:hidden;font:inherit;border:none;line-height:normal;-webkit-user-select:none;-moz-user-select:none;user-select:none;display:block;height:44px;background:top no-repeat #181818;font-weight:400;position:absolute;right:0;left:0;border-top:none;background-size:100% 1px;background-image:linear-gradient(180deg,#242424,#242424 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.bottom-bar{background-image:linear-gradient(180deg,#242424,#242424 50%,transparent 50%)}}.bottom-bar__line-height{line-height:44px;padding-bottom:0;padding-top:0}.bottom-bar--aligned{display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;line-height:44px}.toolbar--material__center,.toolbar--material__left,.toolbar--material__right{font-family:Roboto,Noto,sans-serif;font-size:20px;font-weight:500;height:56px;width:auto;line-height:56px;color:#fff;-webkit-font-smoothing:antialiased}.bottom-bar--transparent{background-color:transparent;background-image:none;border:none}.toolbar--material{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;height:56px;border-bottom:0;box-shadow:0 1px 5px rgba(0,0,0,.3);padding:0;background-color:#212121;background-size:0}.toolbar--noshadow,.toolbar--transparent{background-image:none;border-bottom:none}.toolbar--noshadow{box-shadow:none}.toolbar--material__left,.toolbar--material__right{min-width:72px}.toolbar--material__center{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;overflow:hidden;text-overflow:ellipsis;text-align:left}.toolbar--material__center:first-child{margin-left:16px}.toolbar--material__center:last-child{margin-right:16px}.button,.button--quiet{position:relative;box-sizing:border-box;margin:0;font:inherit;-moz-osx-font-smoothing:grayscale;cursor:default;-moz-user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;display:inline-block;-webkit-user-select:none;padding:4px 10px}.toolbar--material__left:empty,.toolbar--material__right:empty{min-width:16px}.toolbar--transparent{background-color:transparent;box-shadow:none}.button,.button--material{border:0 solid currentColor}.button{background:#0076FF;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;user-select:none;font-size:17px;line-height:32px;letter-spacing:0;color:#fff;vertical-align:middle;border-radius:3px}.button:active{background-color:#0076FF;opacity:.2}.button:focus{outline:0}.button:disabled,.button[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--outline{background-color:transparent;border:1px solid #0076FF;color:#0076FF}.button--outline:active{background-color:#ffe3b3;border:1px solid #0076FF;color:#0076FF;opacity:1}.button--outline:hover{border:1px solid #0076FF;transition:0}.button--light,.button--light:active{color:rgba(255,255,255,.4);border:1px solid rgba(255,255,255,.2)}.button--light{background-color:transparent}.button--light:active{background-color:rgba(255,255,255,.05);opacity:1}.button--cta,.button--quiet{border-radius:3px;transition:none}.button--quiet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-ms-user-select:none;user-select:none;font-size:17px;line-height:32px;letter-spacing:0;vertical-align:middle;box-shadow:none;background:0 0;color:#0076FF;border:none}.button--cta,.button--large--quiet{font:inherit;-moz-user-select:none;-ms-user-select:none;position:relative;box-sizing:border-box;margin:0;-moz-osx-font-smoothing:grayscale;cursor:default;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;letter-spacing:0;vertical-align:middle}.button--quiet:disabled,.button--quiet[disabled]{opacity:.3;cursor:default;pointer-events:none;border:none}.button--quiet:hover{transition:none}.button--quiet:focus{outline:0}.button--quiet:active{background-color:transparent;border:none;transition:none;opacity:.2;color:#0076FF}.button--cta{display:inline-block;background:#0076FF;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-webkit-user-select:none;user-select:none;padding:4px 10px;font-size:17px;line-height:32px;border:none;color:#fff}.button--large,.button--large--cta,.button--large--quiet{padding:4px 12px;width:100%;display:block}.button--cta:hover{transition:none}.button--cta:focus{outline:0}.button--cta:active{color:#fff;background-color:#0076FF;transition:none;opacity:.2}.button--cta:disabled,.button--cta[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large{font-size:17px;font-weight:500;line-height:36px;text-align:center}.button--large:active{background-color:#0076FF;opacity:.2;transition:none}.button--large--quiet,.button--large--quiet:active{color:#0076FF;background:0 0;box-shadow:none;transition:none}.button--large:disabled,.button--large[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large:hover{transition:none}.button--large:focus{outline:0}.button--large--quiet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-webkit-user-select:none;user-select:none;border-radius:3px;font-size:17px;font-weight:500;line-height:36px;border:1px solid transparent;text-align:center}.button--large--cta,.button--material{-moz-user-select:none;font:inherit;color:#fff}.button--large--quiet:active{opacity:.2;border:1px solid transparent}.button--large--quiet:disabled,.button--large--quiet[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large--quiet:hover{transition:none}.button--large--quiet:focus{outline:0}.button--large--cta{position:relative;box-sizing:border-box;margin:0;background:#0076FF;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;cursor:default;-webkit-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;letter-spacing:0;vertical-align:middle;border-radius:3px;transition:none;border:none;font-size:17px;font-weight:500;line-height:36px;text-align:center}.button--material,.button--material--flat{box-sizing:border-box;cursor:default;-ms-user-select:none;height:auto;vertical-align:middle;padding:0 16px;-moz-osx-font-smoothing:grayscale;margin:0;position:relative;text-transform:uppercase;min-height:36px;text-align:center}.button--material,.button--material--flat,.tabbar__button{overflow:hidden;display:inline-block;letter-spacing:0;text-overflow:ellipsis;text-decoration:none;white-space:nowrap}.button--large--cta:hover{transition:none}.button--large--cta:focus{outline:0}.button--large--cta:active{color:#fff;background-color:#0076FF;transition:none;opacity:.2}.button--material,.button--material:active,.button--material:hover{transition:all .25s linear}.button--large--cta:disabled,.button--large--cta[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--material{background:#0076FF;-webkit-user-select:none;user-select:none;border-radius:3px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;line-height:36px;font-size:14px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);font-weight:500;opacity:1}.button--material--flat,.checkbox,.tabbar__button{-webkit-user-select:none}.button--material--flat,.select-input--material,.text-input--material{-webkit-transform:translate3d(0,0,0)}.button--material:active{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.4);background-color:#0076FF;opacity:.9}.button--material:focus{outline:0}.button--material:disabled,.button--material[disabled]{transition:none;box-shadow:none;background-color:rgba(176,176,176,.74);color:rgba(255,255,255,.74);opacity:1}.button--material--flat,.button--material--flat:hover{transition:all .25s linear}.button--material--flat{font:inherit;background:0 0;-moz-user-select:none;user-select:none;border:0 solid currentColor;border-radius:3px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;line-height:36px;font-size:14px;transform:translate3d(0,0,0);font-weight:500;box-shadow:none;color:#0076FF}.checkbox,.tabbar__button{-moz-user-select:none;-ms-user-select:none}.button--material--flat:focus{box-shadow:none;background-color:transparent;color:#0076FF;outline:0;opacity:1;border:none}.button--material--flat:active{box-shadow:none;outline:0;opacity:1;border:none;background-color:rgba(102,102,102,.2);color:#0076FF;transition:all .25s linear}.button--material--flat:disabled,.button--material--flat[disabled]{transition:none;opacity:1;box-shadow:none;background-color:transparent;color:rgba(255,255,255,.74)}.button-bar__button:disabled,.segment__item:disabled,.tabbar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;margin:0;padding:0;border:none}.button-bar__button,.button-bar__item{border-radius:0;width:100%;padding:0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;box-sizing:border-box}.button-bar__item{margin:0;position:relative;overflow:hidden}.button-bar__button{background-color:transparent;color:#0076FF;border:1px solid #0076FF;font-size:13px;height:27px;line-height:27px;transition:background-color .2s linear,color .2s linear;border-width:1px 1px 1px 0}.button-bar__button:hover{transition:none}.button-bar__button:focus{outline:0}:checked+.button-bar__button{background-color:#0076FF;color:#fff;transition:none}.button-bar__button:active,:active+.button-bar__button{background-color:#332000;border:0 solid #0076FF;border-top:1px solid #0076FF;border-bottom:1px solid #0076FF;border-right:1px solid #0076FF;font-size:13px;width:100%;transition:none}.segment__button,.segment__input,.segment__item,.tabbar__item>input{background-color:transparent}.button-bar__item:first-child>.button-bar__button{border-left-width:1px;border-radius:4px 0 0 4px}.button-bar__item:last-child>.button-bar__button{border-right-width:1px;border-radius:0 4px 4px 0}.segment{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;margin:0;padding:0;border:none}.segment__item{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;border-radius:0;width:100%;padding:0;margin:0;position:relative;overflow:hidden;box-sizing:border-box;display:block;border:none}.segment__input,.tabbar{position:absolute;margin:0;width:100%;bottom:0;padding:0;left:0;right:0}.segment__input{border:0;z-index:1;vertical-align:top;height:100%;-webkit-appearance:none;appearance:none}.segment__button{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;border-radius:0;color:#0076FF;border:1px solid #0076FF;font-weight:400;padding:0;font-size:13px;height:29px;line-height:29px;width:100%;transition:background-color .2s linear,color .2s linear;box-sizing:border-box;text-align:center;border-width:1px 1px 1px 0}.segment__button:hover,:active+.segment--material__button,:active+.segment__button{transition:none}.segment__button:focus{outline:0}:active+.segment__button{background-color:#332000;border:0 solid #0076FF;border-top:1px solid #0076FF;border-bottom:1px solid #0076FF;border-right:1px solid #0076FF;font-size:13px;width:100%}:checked+.segment__button{background-color:#0076FF;color:#fff;transition:none}.segment--material__button,:active+.segment--material__button{background-color:#292929;font-size:14px;color:rgba(255,255,255,.62)}.segment__item:first-child>.segment__button{border-left-width:1px;border-radius:4px 0 0 4px}.segment__item:last-child>.segment__button{border-right-width:1px;border-radius:0 4px 4px 0}.segment--material__button,.segment--material__item:first-child>.segment--material__button,.segment--material__item:last-child>.segment--material__button,:active+.segment--material__button{border-width:0;border-radius:0}.segment--material{border-radius:2px;overflow:hidden;box-shadow:0 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.24)}.segment--material__button{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;height:32px;line-height:32px}.tabbar,.tabbar__item{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:checked+.segment--material__button{background-color:#404040;color:#cacaca;border-radius:0;border-width:0}.tabbar{display:-webkit-box;display:-webkit-flex;display:flex;white-space:nowrap;height:49px;background-color:#212121;border-top:1px solid #0d0d0d}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.tabbar{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#0d0d0d,#0d0d0d 50%,transparent 50%)}}.tabbar__item{position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-basis:0;flex-basis:0;width:auto;border-radius:0}.tabbar__button,.tabbar__item>input{vertical-align:top;width:100%;margin:0}.tabbar__item>input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;z-index:1;outline:0;height:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none}.tabbar__button{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;font:inherit;background:0 0;border:none;cursor:default;user-select:none;position:relative;padding:0;height:49px;color:#aaa;border-top:none;font-weight:400;line-height:49px}.tabbar__icon{font-size:24px;padding:0;margin:0;line-height:26px;display:block!important;height:28px}.tabbar__label{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:inline-block}.tabbar--material__button,.tabbar--material__label,.tabbar--material__label:first-child{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.tabbar__badge.notification{vertical-align:text-bottom;top:-1px;margin-left:5px;z-index:10;font-size:12px;height:16px;min-width:16px;line-height:16px;border-radius:8px}.tabbar__icon~.tabbar__badge.notification{position:absolute;top:5px;margin-left:0}.tabbar__icon+.tabbar__label{display:block;font-size:10px;line-height:1;margin:0;font-weight:400}.tabbar__label:first-child{font-size:16px;line-height:49px;margin:0;padding:0}:checked+.tabbar__button{color:#0076FF;background-color:transparent;box-shadow:none;border-top:none}.tabbar__button:focus{z-index:1;border-top:none;box-shadow:none;outline:0}.tabbar__content{position:absolute;top:0;left:0;right:0;bottom:49px;z-index:0}.tabbar--autogrow .tabbar__item{-webkit-flex-basis:auto;flex-basis:auto}.tabbar--top{position:relative;top:0;left:0;right:0;bottom:auto;border-top:none;border-bottom:1px solid #0d0d0d}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.tabbar__button{border-top:none}.tabbar--top{border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#0d0d0d,#0d0d0d 50%,transparent 50%)}}.tabbar--top__content{top:49px;left:0;right:0;bottom:0;z-index:0}.tabbar--top-border__button{background-color:transparent;border-bottom:4px solid transparent}:checked+.tabbar--top-border__button{background-color:transparent;border-bottom:4px solid #0076FF}.tabbar__border{position:absolute;bottom:0;left:0;width:0;height:4px;background-color:#0076FF}.tabbar--material{background:#212121;border-bottom-width:0;box-shadow:0 4px 2px -2px rgba(0,0,0,.14),0 3px 5px -2px rgba(0,0,0,.12),0 5px 1px -4px rgba(0,0,0,.2)}.tabbar--material__button{background-color:transparent;color:rgba(255,255,255,.5);text-transform:uppercase;font-size:14px;font-weight:400}.tabbar--material__button:after{display:block;width:0;height:2px;bottom:0;position:absolute;margin-top:-2px;background-color:#fff}:checked+.tabbar--material__button:after{width:100%;transition:width .2s ease-in-out}:checked+.tabbar--material__button{background-color:transparent;color:#fff}.tabbar--material__item:not([ripple]):active{background-color:#292929}.tabbar--material__border{height:2px;background-color:#fff}.back-button,.toolbar-button,.toolbar-button:active{background-color:rgba(0,0,0,0)}.tabbar--material__icon{font-size:22px!important;line-height:36px}.back-button,.back-button__label{display:inline-block;line-height:44px}.tabbar--material__label{font-weight:400}.tabbar--material__label:first-child{letter-spacing:.015em;font-weight:500;font-size:14px}.tabbar--material__icon+.tabbar--material__label{font-size:10px}.toolbar-button{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;padding:4px 10px;letter-spacing:0;color:#0076FF;border-radius:2px;border:1px solid transparent;font-weight:400;font-size:17px;transition:none}.toolbar-button:active{transition:none;opacity:.2}.toolbar-button:disabled,.toolbar-button[disabled]{opacity:.3;cursor:default;pointer-events:none}.toolbar-button:focus{outline:0;transition:none}.toolbar-button:hover{transition:none}.toolbar-button--outline{border:1px solid #0076FF;margin:auto 8px;padding-left:6px;padding-right:6px}.toolbar-button--material{font-size:22px;color:#0076FF;display:inline-block;padding:0 12px;height:100%;margin:0;border:none;border-radius:0;vertical-align:baseline;vertical-align:initial;transition:background-color .25s linear}.toolbar-button--material:first-of-type{margin-left:4px}.toolbar-button--material:last-of-type{margin-right:4px}.toolbar-button--material:active{opacity:1;transition:background-color .25s linear}.back-button{height:44px;padding-left:8px;color:#0076FF}.back-button:active{opacity:.2}.back-button__label{height:100%;vertical-align:top;font-size:17px;font-weight:500}.back-button__icon{margin-right:6px;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;fill:#0076FF;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:100%}.back-button--material{font-size:22px;color:#0076FF;display:inline-block;padding:0 12px;height:100%;margin:0 0 0 4px;border:none;border-radius:0;vertical-align:baseline;vertical-align:initial;line-height:56px}.back-button--material__label{display:none;font-size:20px}.back-button--material__icon{display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;fill:#0076FF;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:100%}.back-button--material:active{opacity:1}.checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;line-height:22px}.checkbox--noborder,.checkbox__checkmark{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-moz-osx-font-smoothing:grayscale;display:inline-block;vertical-align:top;cursor:default;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.checkbox__checkmark{box-sizing:border-box;background-clip:padding-box;user-select:none;position:relative;height:22px;width:22px;pointer-events:none}.checkbox__input,.checkbox__input:checked{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;outline:0;width:100%;height:100%;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.checkbox__checkmark:after,.checkbox__checkmark:before{position:absolute;background:0 0;content:''}.checkbox__checkmark:before{box-sizing:border-box;width:22px;height:22px;border:1px solid #c7c7cd;border-radius:22px;left:0}.checkbox__checkmark:after{top:7px;left:5px;width:11px;height:5px;border:2px solid #fff;border-width:1px;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}:checked+.checkbox__checkmark:before{background:#0076FF;border:none}:checked+.checkbox__checkmark:after{opacity:1}:disabled+.checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}:disabled:active+.checkbox__checkmark:before{background:0 0}.checkbox--noborder{user-select:none;line-height:22px;position:relative}.checkbox--noborder__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;outline:0;width:100%;height:100%;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.radio-button__input,.textarea{-webkit-appearance:none;-moz-appearance:none}.checkbox--noborder__checkmark{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;width:22px;height:22px;background:0 0;border:none}.checkbox--noborder__checkmark:before{content:'';position:absolute;width:22px;height:22px;background:0 0;border:none;border-radius:22px;left:0}.checkbox--noborder__checkmark:after{content:'';position:absolute;top:7px;left:4px;opacity:0;width:11px;height:4px;background:0 0;border:2px solid #0076FF;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}:checked+.checkbox--noborder__checkmark:before{background:0 0;border:none}:checked+.checkbox--noborder__checkmark:after{opacity:1}:focus+.checkbox--noborder__checkmark:before{border:none}:disabled+.checkbox--noborder__checkmark{opacity:.3;cursor:default;pointer-events:none}:disabled:active+.checkbox--noborder__checkmark:before{background:0 0;border:none}.checkbox--material{line-height:18px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;overflow:visible}.checkbox--material__checkmark{width:18px;height:18px}.checkbox--material__checkmark:before{border-radius:2px;height:18px;width:18px;border:2px solid #717171;transition:background-color .1s linear .2s,border-color .1s linear .2s;background-color:transparent}:checked+.checkbox--material__checkmark:before{border:2px solid #fff;background-color:#fff;transition:background-color .1s linear,border-color .1s linear}.checkbox--material__checkmark:after{border-color:#000;transition:-webkit-transform .2s ease 0;transition:transform .2s ease 0;transition:transform .2s ease 0,-webkit-transform .2s ease 0;width:10px;height:5px;top:4px;left:3px;-webkit-transform:scale(0) rotate(-45deg);transform:scale(0) rotate(-45deg);border-width:2px}:checked+.checkbox--material__checkmark:after{transition:-webkit-transform .2s ease .2s;transition:transform .2s ease .2s;transition:transform .2s ease .2s,-webkit-transform .2s ease .2s;width:10px;height:5px;top:4px;left:3px;-webkit-transform:scale(1) rotate(-45deg);transform:scale(1) rotate(-45deg);border-width:2px}.checkbox--material__input:before{content:'';opacity:0;position:absolute;top:0;left:0;width:18px;height:18px;box-shadow:0 0 0 11px #717171;box-sizing:border-box;border-radius:50%;background-color:#717171;pointer-events:none;display:block;-webkit-transform:scale3d(.2,.2,.2);transform:scale3d(.2,.2,.2);transition:opacity .25s ease-out,-webkit-transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out,-webkit-transform .1s ease-out}.radio-button,.radio-button__checkmark{display:inline-block;-webkit-user-select:none;-ms-user-select:none;vertical-align:top}.checkbox--material__input:checked:before{box-shadow:0 0 0 11px #fff;background-color:#fff}.checkbox--material__input:active:before{opacity:.15;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}:disabled+.checkbox--material__checkmark{opacity:1}:disabled+.checkbox--material__checkmark:before{border-color:#afafaf}:disabled:checked+.checkbox--material__checkmark:before{background-color:#afafaf}:disabled:checked+.checkbox--material__checkmark:after{border-color:#fff}.radio-button__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;outline:0;width:100%;height:100%;margin:0;appearance:none}.radio-button__input:active,.radio-button__input:focus{outline:0;-webkit-tap-highlight-color:transparent}.radio-button{cursor:default;-moz-user-select:none;user-select:none;position:relative;line-height:24px;text-align:left}.list,.radio-button__checkmark{cursor:default;-moz-user-select:none}.radio-button__checkmark:before{content:'';position:absolute;box-sizing:border-box;width:22px;height:22px;background:0 0;border:none;border-radius:22px;left:0}.radio-button__checkmark{box-sizing:border-box;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;position:relative;width:24px;height:24px;background:0 0;pointer-events:none}.list,.list-title{-webkit-user-select:none;-moz-osx-font-smoothing:grayscale}.dialog,.list,.list-title{-ms-user-select:none}.radio-button__checkmark:after{content:'';position:absolute;top:7px;left:4px;opacity:0;width:11px;height:4px;background:0 0;border:2px solid #0076FF;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}:checked+.radio-button__checkmark{background:rgba(0,0,0,0)}:checked+.radio-button__checkmark:after{opacity:1}:checked+.radio-button__checkmark:before{background:0 0;border:none}:disabled+.radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}.radio-button--material{line-height:22px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.radio-button--material__input:before{content:'';position:absolute;top:0;left:0;opacity:0;width:20px;height:20px;box-shadow:0 0 0 14px #8e8e8e;border:none;box-sizing:border-box;border-radius:50%;background-color:#8e8e8e;pointer-events:none;display:block;-webkit-transform:scale3d(.2,.2,.2);transform:scale3d(.2,.2,.2);transition:opacity .25s ease-out,-webkit-transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out,-webkit-transform .1s ease-out}.radio-button--material__input:checked:before{box-shadow:0 0 0 14px #0076FF;background-color:#0076FF}.list-item--material:first-child,.search-input{box-shadow:none}.radio-button--material__input:active:before{opacity:.15;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.radio-button--material__checkmark{width:20px;height:20px;overflow:visible}.radio-button--material__checkmark:before{background:0 0;border:2px solid #8e8e8e;box-sizing:border-box;border-radius:50%;width:20px;height:20px;transition:border .2s ease}.radio-button--material__checkmark:after{transition:background .2s ease,-webkit-transform .2s ease;transition:background .2s ease,transform .2s ease;transition:background .2s ease,transform .2s ease,-webkit-transform .2s ease;top:5px;left:5px;width:10px;height:10px;border:none;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}:checked+.radio-button--material__checkmark:before{background:0 0;border:2px solid #0076FF}.radio-button--material__input+.radio-button__checkmark:after{background:#8e8e8e;opacity:1;-webkit-transform:scale(0);transform:scale(0)}:checked+.radio-button--material__checkmark:after{opacity:1;background:#0076FF;-webkit-transform:scale(1);transform:scale(1)}:disabled+.radio-button--material__checkmark{opacity:1}:disabled+.radio-button--material__checkmark:after{background-color:#505050;border-color:#505050}:disabled+.radio-button--material__checkmark:before{border-color:#505050}.list{padding:0;margin:0;font:inherit;color:inherit;background:bottom no-repeat,top no-repeat #181818;line-height:normal;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;list-style-type:none;text-align:left;display:block;-webkit-overflow-scrolling:touch;overflow:hidden;background-image:linear-gradient(#242424,#242424),linear-gradient(#242424,#242424);background-size:100% 1px,100% 1px;border:none}.list-header,.list-item{list-style:none;color:#fff;position:relative}.list-item--expandable,.list-item__center,.list-item__right{background-position:bottom;border-bottom:none}.dialog,.list-title{cursor:default;-moz-user-select:none;text-align:left}.list-item,.list-item__top{display:-webkit-box;display:-webkit-flex;-webkit-box-orient:horizontal;width:100%;-webkit-box-direction:normal}.list-header,.list-item--expandable,.list-item__center,.list-item__right{background-size:100% 1px;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list{background-image:linear-gradient(0deg,#242424,#242424 50%,transparent 50%),linear-gradient(180deg,#242424,#242424 50%,transparent 50%)}}.list-item{box-sizing:border-box;display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:0 0 0 14px;margin:0 0 -1px;transition:background-color .2s linear}.list-item__top{display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-ordinal-group:1;-webkit-order:0;order:0}.list-item--expandable{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;background-image:linear-gradient(0deg,#242424,#242424 100%);background-position-x:14px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--expandable{background-image:linear-gradient(0deg,#242424,#242424 50%,transparent 50%)}}.list-item__expandable-content{display:none;width:100%;padding:12px 14px 12px 0;box-sizing:border-box;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;overflow:hidden}.list-item.expanded>.list-item__expandable-content{display:block;height:auto}.list-item__center,.list-item__left{display:-webkit-box;display:-webkit-flex;-webkit-align-self:stretch;line-height:1.2em;min-height:44px;box-sizing:border-box}.list-item__left{display:flex;padding:12px 14px 12px 0;-webkit-box-ordinal-group:1;-webkit-order:0;order:0;-webkit-box-align:center;-webkit-align-items:center;align-items:center;align-self:stretch}.list-item__left:empty{width:0;min-width:0;padding:0;margin:0}.list-item__center{display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;margin-right:auto;-webkit-box-align:center;-webkit-align-items:center;align-items:center;align-self:stretch;margin-left:0;background-image:linear-gradient(0deg,#242424,#242424 100%);padding:12px 6px 12px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item__center{background-image:linear-gradient(0deg,#242424,#242424 50%,transparent 50%)}}.list-item__right{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:flex;margin-left:auto;padding:12px 12px 12px 0;-webkit-box-ordinal-group:3;-webkit-order:2;order:2;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-align-self:stretch;align-self:stretch;background-image:linear-gradient(0deg,#242424,#242424 100%);line-height:1.2em;min-height:44px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item__right{background-image:linear-gradient(0deg,#242424,#242424 50%,transparent 50%)}}.list-header{margin:0;text-align:left;display:block;box-sizing:border-box;padding:0 0 0 15px;font-size:12px;font-weight:500;min-height:24px;line-height:25px;text-transform:uppercase;background-color:#111;background-position:top;background-image:linear-gradient(0deg,#242424,#242424 100%)}.list-item--material.list-item--expandable,.list-item--material__center,.list-item--material__left:empty,.list-item--material__right{background-size:100% 1px;background-repeat:no-repeat;background-position:bottom}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-header{background-image:linear-gradient(180deg,#242424,#242424 50%,transparent 50%)}}.list--noborder{border-top:none;border-bottom:none;background-image:none}.list-item--tappable:active{transition:none;background-color:#262626}.list--inset{margin:0 8px;border:1px solid #242424;border-radius:4px;background-image:none}.list-item__label{font-size:14px;padding:0 4px;opacity:.6}.list-item__title{-webkit-flex-basis:100%;flex-basis:100%;-webkit-align-self:flex-end;align-self:flex-end;-webkit-box-ordinal-group:1;-webkit-order:0;order:0}.list-item__subtitle{opacity:.75;font-size:14px;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;-webkit-flex-basis:100%;flex-basis:100%;-webkit-align-self:flex-start;align-self:flex-start}.list-item__thumbnail{width:40px;height:40px;border-radius:6px;display:block;margin:0}.list-item__icon{font-size:22px;padding:0 6px}.list--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;background-image:none;background-color:#363636}.list-item--material{border:0;padding:0 0 0 16px;line-height:normal}.list-item--material__subtitle{margin-top:4px}.list-item--material__left{padding:14px 0;min-width:56px;line-height:1;min-height:48px}.list-item--material__center,.list-item--material__left:empty{padding:14px 6px 14px 0;border-color:rgba(255,255,255,.12);border-bottom:none;background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 100%);min-height:48px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material__center,.list-item--material__left:empty{background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 50%,transparent 50%)}}.list-item--material__right{padding:14px 16px 14px 0;line-height:1;border-color:rgba(255,255,255,.12);border-bottom:none;background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 100%);min-height:48px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material__right{background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 50%,transparent 50%)}}.list-item--material.list-item--expandable{border-bottom:1px solid rgba(255,255,255,.12);border-bottom:none;background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 100%);background-position-x:16px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material.list-item--expandable{background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 50%,transparent 50%)}}.list-item--material.list-item--expandable.list-item--longdivider,.list-item--material.list-item--longdivider{border-bottom:1px solid rgba(255,255,255,.12);border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material.list-item--expandable.list-item--longdivider,.list-item--material.list-item--longdivider{background-image:linear-gradient(0deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 50%,transparent 50%)}}.list-header--material{background:#181818;border:none;font-size:14px;text-transform:none;margin:-1px 0 0;color:#8a8a8a;font-weight:500;padding:8px 16px}.list-header--material:not(:first-of-type){border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 100%);padding-top:16px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-header--material:not(:first-of-type){background-image:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,.12) 50%,transparent 50%)}}.list-item--material__thumbnail{width:40px;height:40px;border-radius:100%}.list-item--material__icon{font-size:20px;padding:0 4px}.list-item--chevron::before,.list-item__expand-chevron{border-right:2px solid #383833;border-bottom:2px solid #383833;width:7px;height:7px;background-color:transparent;z-index:5}.list-item--chevron::before{position:absolute;content:'';right:16px;top:50%;-webkit-transform:translateY(-50%) rotate(-45deg);transform:translateY(-50%) rotate(-45deg)}.list-item__expand-chevron{-webkit-transform:rotate(45deg);transform:rotate(45deg);margin:1px}.list-item--expandable.expanded .list-item__expand-chevron{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.list-item--chevron__right{padding-right:30px}.list-item--expandable .list-item__center,.list-item--expandable .list-item__right,.list-item--nodivider.list-item--expandable,.list-item--nodivider__center,.list-item--nodivider__right{border:none;background-image:none}.list-item--longdivider{border-bottom:1px solid #242424;border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#242424,#242424 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--longdivider{background-image:linear-gradient(0deg,#242424,#242424 50%,transparent 50%)}}.list-item--longdivider:last-of-type,.list-item--longdivider__center,.list-item--longdivider__right{border:none;background-image:none}.list-title{font:inherit;background:0 0;border:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;display:block;color:#6d6d72;box-sizing:border-box;padding:0 0 0 16px;margin:0;font-size:13px;font-weight:500;line-height:24px;text-transform:uppercase;letter-spacing:.04em}.list-title--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#757575;font-size:14px;margin:0;padding:12px 0 12px 16px;font-weight:500;line-height:24px}.search-input{font:inherit;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTNweCIgaGVpZ2h0PSIxNHB4IiB2aWV3Qm94PSIwIDAgMTMgMTQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQyICgzNjc4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+aW9zLXNlYXJjaC1pbnB1dC1pY29uPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9ImNvbXBvbmVudHMiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJpb3Mtc2VhcmNoLWlucHV0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDguMDAwMDAwLCAtNDMuMDAwMDAwKSIgZmlsbD0iIzdBNzk3QiI+CiAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDAuMDAwMDAwLCAzNi4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNi45OTcyNDgyLDE1LjUwNDE0NjYgQzE3LjA3NzM2NTcsMTUuNTQwNTkzOCAxNy4xNTIyNzMxLDE1LjU5MTYxMjkgMTcuMjE3NzUxNiwxNS42NTcwOTE0IEwyMC42NDk5OTEsMTkuMDg5MzMwOCBDMjAuOTQ0ODQ0OSwxOS4zODQxODQ3IDIwLjk0ODQ3NjQsMTkuODU4NjA2IDIwLjY1MzU0MTIsMjAuMTUzNTQxMiBDMjAuMzYwNjQ4LDIwLjQ0NjQzNDQgMTkuODgxMjcxNiwyMC40NDE5MzE3IDE5LjU4OTMzMDgsMjAuMTQ5OTkxIEwxNi4xNTcwOTE0LDE2LjcxNzc1MTYgQzE2LjA5MTM3LDE2LjY1MjAzMDEgMTYuMDQwMTE3MSwxNi41NzczODc0IDE2LjAwMzQxNDEsMTYuNDk3Nzk5NSBDMTUuMTY3MTY5NCwxNy4xMjcwNDExIDE0LjEyNzEzOTMsMTcuNSAxMywxNy41IEMxMC4yMzg1NzYzLDE3LjUgOCwxNS4yNjE0MjM3IDgsMTIuNSBDOCw5LjczODU3NjI1IDEwLjIzODU3NjMsNy41IDEzLDcuNSBDMTUuNzYxNDIzNyw3LjUgMTgsOS43Mzg1NzYyNSAxOCwxMi41IEMxOCwxMy42Mjc0Njg1IDE3LjYyNjgyMzIsMTQuNjY3Nzc2OCAxNi45OTcyNDgyLDE1LjUwNDE0NjYgWiBNMTMsMTYuNSBDMTUuMjA5MTM5LDE2LjUgMTcsMTQuNzA5MTM5IDE3LDEyLjUgQzE3LDEwLjI5MDg2MSAxNS4yMDkxMzksOC41IDEzLDguNSBDMTAuNzkwODYxLDguNSA5LDEwLjI5MDg2MSA5LDEyLjUgQzksMTQuNzA5MTM5IDEwLjc5MDg2MSwxNi41IDEzLDE2LjUgWiIgaWQ9Imlvcy1zZWFyY2gtaW5wdXQtaWNvbiI+PC9wYXRoPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=) 8px center no-repeat;border:none;vertical-align:top;outline:0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;box-sizing:border-box;height:28px;font-size:14px;background-color:rgba(255,255,255,.09);color:#fff;line-height:1.3;padding:0 8px 0 28px;margin:0;border-radius:5.5px;background-size:13px;font-weight:400;display:inline-block;text-indent:0}.search-input::-webkit-search-cancel-button{-webkit-appearance:textfield;appearance:textfield;display:none}.search-input::-webkit-search-decoration{display:none}.search-input:focus{outline:0}.search-input::-webkit-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input:-ms-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input::-ms-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input::placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;border-radius:2px;height:48px;background-color:#424242;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMThweCIgaGVpZ2h0PSIxOHB4IiB2aWV3Qm94PSIwIDAgMTggMTgiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQzLjIgKDM5MDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5TaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJhbmRyb2lkLXNlYXJjaC1pbnB1dC1pY29uIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGZpbGw9IiM4OTg5ODkiPgogICAgICAgICAgICA8ZyBpZD0iY29tcG9uZW50cyI+CiAgICAgICAgICAgICAgICA8ZyBpZD0ibWF0ZXJpYWwtc2VhcmNoIj4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0ic2VhcmNoIj4KICAgICAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ik1hdGVyaWFsL0ljb25zLWJsYWNrL3NlYXJjaCI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuNTAyLDYuNDkxIEwxMS43MDgsNi40OTEgTDExLjQzMiw2Ljc2NSBDMTIuNDA3LDcuOTAyIDEzLDkuMzc2IDEzLDEwLjk5MSBDMTMsMTQuNTgxIDEwLjA5LDE3LjQ5MSA2LjUsMTcuNDkxIEMyLjkxLDE3LjQ5MSAwLDE0LjU4MSAwLDEwLjk5MSBDMCw3LjQwMSAyLjkxLDQuNDkxIDYuNSw0LjQ5MSBDOC4xMTUsNC40OTEgOS41ODgsNS4wODMgMTAuNzI1LDYuMDU3IEwxMS4wMDEsNS43ODMgTDExLjAwMSw0Ljk5MSBMMTUuOTk5LDAgTDE3LjQ5LDEuNDkxIEwxMi41MDIsNi40OTEgTDEyLjUwMiw2LjQ5MSBaIE02LjUsNi40OTEgQzQuMDE0LDYuNDkxIDIsOC41MDUgMiwxMC45OTEgQzIsMTMuNDc2IDQuMDE0LDE1LjQ5MSA2LjUsMTUuNDkxIEM4Ljk4NSwxNS40OTEgMTEsMTMuNDc2IDExLDEwLjk5MSBDMTEsOC41MDUgOC45ODUsNi40OTEgNi41LDYuNDkxIEw2LjUsNi40OTEgWiIgaWQ9IlNoYXBlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4Ljc0NTAwMCwgOC43NDU1MDApIHNjYWxlKC0xLCAxKSByb3RhdGUoLTE4MC4wMDAwMDApIHRyYW5zbGF0ZSgtOC43NDUwMDAsIC04Ljc0NTUwMCkgIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);background-size:18px;background-position:18px center;font-size:14px;padding:0 24px 0 64px;box-shadow:0 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.24),0 1px 0 0 rgba(255,255,255,.06) inset}.text-input,.text-input--underbar{font:inherit;vertical-align:top;outline:0;-moz-osx-font-smoothing:grayscale;letter-spacing:0;box-shadow:none;padding:0;width:auto;height:31px;border:none;margin:0}.text-input{background:0 0;line-height:1;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;color:#fff;font-size:15px;font-weight:400;box-sizing:border-box}.text-input::-ms-clear{display:none}.text-input:disabled{opacity:.3;cursor:default;pointer-events:none}.text-input::-webkit-input-placeholder{color:#999}.text-input:-ms-input-placeholder{color:#999}.text-input::-ms-input-placeholder{color:#999}.text-input::placeholder{color:#999}.text-input:disabled::-webkit-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled:-ms-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled::-ms-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled::placeholder{border:none;background-color:transparent;color:#999}.text-input:invalid{border:none;background-color:transparent;color:#fff}.text-input--underbar{background:0 0;line-height:1;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;color:#fff;font-size:15px;font-weight:400;box-sizing:border-box;border-bottom:1px solid #242424;border-radius:0}.text-input--material,.textarea{box-sizing:border-box;font:inherit;-moz-osx-font-smoothing:grayscale;outline:0}.text-input--underbar:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent;border-bottom:1px solid #242424}.text-input--underbar:disabled::-webkit-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled:-ms-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled::-ms-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled::placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:invalid{color:#fff;border:none;background-color:transparent;border-bottom:1px solid #242424}.text-input--material{padding:0 0 2px;margin:0;color:inherit;background:center bottom no-repeat;line-height:1;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:rgba(255,255,255,.75);background-image:linear-gradient(to top,transparent 1px,rgba(255,255,255,.3) 1px);background-size:100% 2px;font-size:16px;font-weight:400;border:none;border-radius:0;height:24px;vertical-align:middle}.textarea,.textarea--transparent{margin:0;vertical-align:top;resize:none;box-shadow:none;width:auto;letter-spacing:0}.text-input--material__label{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:rgba(255,255,255,.3);position:absolute;left:0;top:2px;font-size:16px;font-weight:400;pointer-events:none}.text-input--material__label--active{color:rgba(255,255,255,.75);-webkit-transform:translate(0,-75%) scale(.75);transform:translate(0,-75%) scale(.75);-webkit-transform-origin:left top;transform-origin:left top;transition:color .1s ease-in,-webkit-transform .1s ease-in;transition:transform .1s ease-in,color .1s ease-in;transition:transform .1s ease-in,color .1s ease-in,-webkit-transform .1s ease-in}.alert-dialog,.dialog{-webkit-transform:translate(-50%,-50%)}.text-input--material:focus{background-image:linear-gradient(rgba(255,255,255,.75),rgba(255,255,255,.75)),linear-gradient(to top,transparent 1px,rgba(255,255,255,.3) 1px);-webkit-animation:material-text-input-animate .3s forwards;animation:material-text-input-animate .3s forwards}.text-input--material::-webkit-input-placeholder{color:rgba(255,255,255,.3);line-height:20px}.text-input--material:-ms-input-placeholder{color:rgba(255,255,255,.3);line-height:20px}.text-input--material::-ms-input-placeholder{color:rgba(255,255,255,.3);line-height:20px}.text-input--material::placeholder{color:rgba(255,255,255,.3);line-height:20px}@-webkit-keyframes material-text-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}@keyframes material-text-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}.textarea{background:#0d0d0d;line-height:normal;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;padding:5px;font-size:15px;font-weight:400;border-radius:4px;border:1px solid #242424;color:#fff;appearance:none}.dialog,.textarea--transparent{font:inherit;background:0 0;box-sizing:border-box;-moz-osx-font-smoothing:grayscale}.select-input,.textarea--transparent{-webkit-appearance:none;-moz-appearance:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea::-webkit-input-placeholder{color:#999}.textarea:-ms-input-placeholder{color:#999}.textarea::-ms-input-placeholder{color:#999}.textarea::placeholder{color:#999}.textarea--transparent{line-height:normal;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;padding:5px 0;font-size:15px;font-weight:400;border-radius:4px;border:none;color:#fff;appearance:none}.alert-dialog-button,.fab,.fab--material,.modal__content{vertical-align:middle}.textarea--transparent:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea--transparent::-webkit-input-placeholder{color:#999}.textarea--transparent:-ms-input-placeholder{color:#999}.textarea--transparent::-ms-input-placeholder{color:#999}.textarea--transparent::placeholder{color:#999}.dialog{padding:0;color:inherit;border:none;line-height:normal;-webkit-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);margin:auto;overflow:hidden;min-width:270px;min-height:100px}.alert-dialog,.dialog-mask{-ms-user-select:none;padding:0;cursor:default;position:absolute}.dialog-container{height:inherit;min-height:inherit;overflow:hidden;border-radius:4px;background-color:#0d0d0d;-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);color:#ffffff}.dialog-mask{margin:0;font:inherit;color:inherit;background:0 0;border:none;line-height:normal;-webkit-user-select:none;-moz-user-select:none;user-select:none;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,.2)}.dialog--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;text-align:left;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.dialog-container--material{border-radius:2px;background-color:#424242;color:#fff}.dialog-mask--material{background-color:rgba(0,0,0,.3)}.alert-dialog{box-sizing:border-box;font:inherit;background:#f4f4f4;border:none;line-height:normal;-webkit-user-select:none;-moz-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;top:50%;left:50%;transform:translate(-50%,-50%);width:270px;margin:auto;border-radius:8px;overflow:visible;max-width:95%;color:#1f1f21}.alert-dialog-container{height:inherit;padding-top:16px;overflow:hidden}.alert-dialog-title{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:17px;font-weight:500;padding:0 8px;text-align:center;color:#1f1f21}.alert-dialog-content{box-sizing:border-box;background-clip:padding-box;padding:4px 12px 8px;font-size:14px;min-height:36px;text-align:center;color:#1f1f21}.alert-dialog-footer{width:100%}.alert-dialog-button{box-sizing:border-box;font:inherit;background:0 0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none;letter-spacing:0;border:none;border-top:1px solid #ddd;font-size:16px;padding:0 8px;margin:0;display:block;width:100%;text-align:center;height:44px;line-height:44px;outline:0;color:#0076FF}.alert-dialog-button:active{background-color:rgba(0,0,0,.05)}.alert-dialog-button--primal{font-weight:500}.alert-dialog-footer--rowfooter{white-space:nowrap;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.alert-dialog-button--rowfooter{-webkit-box-flex:1;-webkit-flex:1;flex:1;display:block;width:100%;border-left:1px solid #ddd}.alert-dialog-button--rowfooter:first-child{border-left:none}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#ddd,#ddd 50%,transparent 50%)}.alert-dialog-button--rowfooter{border-top:none;border-left:none;background-size:100% 1px,1px 100%;background-repeat:no-repeat;background-position:top,left;background-image:linear-gradient(0deg,transparent,transparent 50%,#ddd 50%),linear-gradient(90deg,transparent,transparent 50%,#ddd 50%)}.alert-dialog-button--rowfooter:first-child{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top,left;background-image:linear-gradient(0deg,transparent,transparent 50%,#ddd 50%)}}.alert-dialog-mask{padding:0;margin:0;font:inherit;color:inherit;background:0 0;border:none;line-height:normal;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:absolute;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,.2)}.fab,.popover__content{-ms-user-select:none;box-sizing:border-box;-moz-osx-font-smoothing:grayscale;cursor:default}.alert-dialog--material{border-radius:2px;background-color:#424242}.alert-dialog-container--material{padding:22px 0 0;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.alert-dialog-content--material,.alert-dialog-title--material{text-align:left;padding:0 24px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.alert-dialog-title--material{font-size:20px;font-weight:500;color:#fff}.alert-dialog-content--material{font-size:16px;font-weight:400;line-height:20px;margin:24px 0 10px;min-height:0;color:rgba(255,255,255,.85)}.alert-dialog-footer--material{display:block;padding:0;height:52px;box-sizing:border-box;margin:0;line-height:1}.alert-dialog-button--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;text-transform:uppercase;display:inline-block;width:auto;float:right;background:0 0;border:none;border-radius:2px;font-size:14px;font-weight:500;outline:0;height:36px;line-height:36px;padding:0 8px;margin:8px 8px 8px 0;box-sizing:border-box;min-width:50px;color:#0076FF}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button--material{background:0 0}}.alert-dialog-button--material:active{background-color:initial}.alert-dialog-button--rowfooter--material,.alert-dialog-button--rowfooter--material:first-child{border:0}.alert-dialog-button--primal--material{font-weight:500}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button--primal--material,.alert-dialog-button--rowfooter--material,.alert-dialog-button--rowfooter--material:first-child{background:0 0}}.alert-dialog-mask--material{background-color:rgba(0,0,0,.3)}.popover{position:absolute;z-index:20001}.popover--bottom{bottom:0}.popover--top{top:0}.popover--left{left:0}.popover--right{right:0}.popover-mask{left:0;right:0;top:0;bottom:0;background-color:rgba(0,0,0,.2);position:absolute;z-index:19999}.popover__content{padding:0;margin:0;font:inherit;background:#242424;border:none;line-height:normal;-webkit-user-select:none;-moz-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;display:block;width:220px;overflow:auto;min-height:100px;max-height:100%;border-radius:8px;color:#fff;pointer-events:auto}.popover-mask--material,.popover__arrow{background-color:transparent}.popover__arrow{position:absolute;width:18px;height:18px;-webkit-transform-origin:50% 50% 0;transform-origin:50% 50% 0;background-image:linear-gradient(45deg,#242424,#242424 50%,transparent 50%);border-radius:0 0 0 4px;margin:0;z-index:20001}.popover--bottom__arrow{-webkit-transform:translateY(6px) translateX(-9px) rotate(-45deg);transform:translateY(6px) translateX(-9px) rotate(-45deg);bottom:0;margin-right:-18px}.popover--top__arrow{-webkit-transform:translateY(-6px) translateX(-9px) rotate(135deg);transform:translateY(-6px) translateX(-9px) rotate(135deg);top:0;margin-right:-18px}.popover--left__arrow{-webkit-transform:translateX(-6px) translateY(-9px) rotate(45deg);transform:translateX(-6px) translateY(-9px) rotate(45deg);left:0;margin-bottom:-18px}.popover--right__arrow{-webkit-transform:translateX(6px) translateY(-9px) rotate(225deg);transform:translateX(6px) translateY(-9px) rotate(225deg);right:0;margin-bottom:-18px}.popover--material__content{background-color:#424242;border-radius:2px;color:#fff;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.popover--material__arrow{display:none}.progress-bar{position:relative;height:2px;display:block;width:100%;background-color:transparent;background-clip:padding-box;margin:0;overflow:hidden;border-radius:4px}.progress-bar__primary,.progress-bar__secondary{position:absolute;background-color:#0076FF;top:0;bottom:0;transition:width .3s linear;z-index:100;border-radius:4px}.progress-bar__secondary{background-color:#003673;z-index:0}.progress-bar--indeterminate:after,.progress-bar--indeterminate:before{content:'';position:absolute;background-color:#0076FF;top:0;left:0;bottom:0;will-change:left,right;border-radius:4px}.progress-bar--indeterminate:before{-webkit-animation:progress-bar__indeterminate 2.1s cubic-bezier(.65,.815,.735,.395) infinite;animation:progress-bar__indeterminate 2.1s cubic-bezier(.65,.815,.735,.395) infinite}.progress-bar--indeterminate:after{-webkit-animation:progress-bar__indeterminate-short 2.1s cubic-bezier(.165,.84,.44,1) infinite;animation:progress-bar__indeterminate-short 2.1s cubic-bezier(.165,.84,.44,1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes progress-bar__indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@keyframes progress-bar__indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@-webkit-keyframes progress-bar__indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@keyframes progress-bar__indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}.progress-bar--material{height:4px;background-color:transparent;border-radius:0}.progress-bar--material__primary,.progress-bar--material__secondary{background-color:#0076FF;border-radius:0}.progress-bar--material__secondary{background-color:#003673;z-index:0}.fab--material__icon,.fab__icon{overflow:hidden;z-index:100;position:relative}.progress-bar--material.progress-bar--indeterminate:after,.progress-bar--material.progress-bar--indeterminate:before{background-color:#0076FF;border-radius:0}.progress-circular{height:32px;position:relative;width:32px;-webkit-transform:rotate(270deg);transform:rotate(270deg);-webkit-animation:none;animation:none}.progress-circular__background,.progress-circular__primary,.progress-circular__secondary{cx:50%;cy:50%;r:40%;-webkit-animation:none;animation:none;fill:none;stroke-width:5%;stroke-miterlimit:10}.progress-circular__background{stroke:transparent}.progress-circular__primary{stroke-dasharray:1,200;stroke-dashoffset:0;stroke:#0076FF;transition:all 1s cubic-bezier(.4,0,.2,1)}.progress-circular__secondary{stroke:#003673}.progress-circular--indeterminate{-webkit-animation:progress__rotate 2s linear infinite;animation:progress__rotate 2s linear infinite;-webkit-transform:none;transform:none}.progress-circular--indeterminate__primary{-webkit-animation:progress__dash 1.5s ease-in-out infinite;animation:progress__dash 1.5s ease-in-out infinite}.progress-circular--indeterminate__secondary{display:none}@-webkit-keyframes progress__rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes progress__rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes progress__dash{0%{stroke-dasharray:10%,241.32%;stroke-dashoffset:0}50%{stroke-dasharray:201%,50.322%;stroke-dashoffset:-100%}100%{stroke-dasharray:10%,241.32%;stroke-dashoffset:-251.32%}}@keyframes progress__dash{0%{stroke-dasharray:10%,241.32%;stroke-dashoffset:0}50%{stroke-dasharray:201%,50.322%;stroke-dashoffset:-100%}100%{stroke-dasharray:10%,241.32%;stroke-dashoffset:-251.32%}}.progress-circular--material__background,.progress-circular--material__primary,.progress-circular--material__secondary{stroke-width:9%}.progress-circular--material__background{stroke:transparent}.progress-circular--material__primary{stroke:#0076FF}.progress-circular--material__secondary{stroke:#003673}.fab{position:relative;display:inline-block;padding:0;margin:0;font:inherit;background:#0076FF;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:56px;height:56px;text-decoration:none;font-size:25px;line-height:56px;letter-spacing:0;color:#fff;text-align:center;border:0 solid currentColor;border-radius:50%;overflow:hidden;box-shadow:0 3px 6px rgba(0,0,0,.12);transition:all .1s linear}.fab:active{background-color:rgba(255,161,1,.7);transition:all .2s ease;box-shadow:0 0 6 rgba(0,0,0,.12)}.fab:focus{outline:0}.fab__icon{height:100%;width:100%;display:block;border-radius:100%;padding:0;line-height:56px}.fab:disabled,.fab[disabled]{background-color:rgba(0,0,0,.5);box-shadow:none;opacity:.3;cursor:default;pointer-events:none}.fab--material{position:relative;display:inline-block;box-sizing:border-box;padding:0;margin:0;font:inherit;background:#fff;-moz-osx-font-smoothing:grayscale;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;letter-spacing:0;text-align:center;border:0 solid currentColor;border-radius:50%;overflow:hidden;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;width:56px;height:56px;text-decoration:none;font-size:25px;line-height:56px;color:#31313a;box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4);transition:all .2s ease-in-out}.fab--material:active{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.4);background-color:rgba(255,255,255,.75);transition:all .2s ease}.fab--material:focus{outline:0}.fab--material__icon{height:100%;width:100%;display:block;border-radius:100%;padding:0;line-height:56px}.fab--mini,.fab--mini__icon{line-height:40px}.fab--material:disabled,.fab--material[disabled]{background-color:rgba(0,0,0,.5);box-shadow:none;opacity:.3;cursor:default;pointer-events:none}.fab--mini{width:40px;height:40px}.modal,.modal__content{overflow:hidden;word-spacing:0;padding:0;font:inherit;border:none}.speed-dial__item{position:absolute;-webkit-transform:scale(0);transform:scale(0)}.fab--top__right{top:20px;bottom:auto;right:20px;left:auto;position:absolute}.fab--bottom__right{top:auto;bottom:20px;right:20px;left:auto;position:absolute}.fab--top__left{top:20px;bottom:auto;right:auto;left:20px;position:absolute}.fab--bottom__left{top:auto;bottom:20px;right:auto;left:20px;position:absolute}.fab--bottom__center,.fab--top__center{margin-left:-28px;left:50%;right:auto;position:absolute}.fab--top__center{top:20px;bottom:auto}.fab--bottom__center{top:auto;bottom:20px}.modal{white-space:nowrap;margin:0;color:inherit;background:0 0;line-height:normal;box-sizing:border-box;background-clip:padding-box;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;background-color:rgba(0,0,0,.7);position:absolute;left:0;right:0;top:0;bottom:0;width:100%;height:100%;display:table;z-index:2147483647}.modal__content,.select-input{margin:0;color:#fff;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}.modal__content{background:0 0;line-height:normal;background-clip:padding-box;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;display:table-cell;text-align:center;white-space:normal}.select-input{font:inherit;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTBweCIgaGVpZ2h0PSI1cHgiIHZpZXdCb3g9IjAgMCAxMCA1IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0My4yICgzOTA2OSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+c2VsZWN0LWFsbG93PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9InNlbGVjdCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Imlvcy1zZWxlY3QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOTguMDAwMDAwLCAtMTE0LjAwMDAwMCkiIGZpbGw9IiM3NTc1NzUiPgogICAgICAgICAgICA8ZyBpZD0ibWVudS1iYXItKy1vcGVuLW1lbnUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMy4wMDAwMDAsIDEwMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJtZW51LWJhciI+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9InNlbGVjdC1hbGxvdyIgcG9pbnRzPSI3NSAxNCA4MCAxOSA4NSAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=) right center no-repeat;vertical-align:top;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;position:relative;font-size:17px;height:32px;line-height:32px;appearance:none;display:inline-block;border-radius:0;border:none;padding:0 20px 0 0;border-bottom:none}.select-input--material,.select-input--material__label{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.select-input::-ms-clear{display:none}.select-input::-webkit-input-placeholder{color:#999}.select-input:-ms-input-placeholder{color:#999}.select-input::-ms-input-placeholder{color:#999}.select-input::placeholder{color:#999}.select-input:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent}.select-input:disabled::-webkit-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled:-ms-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled::-ms-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled::placeholder{border:none;background-color:transparent;color:#999}.select-input:invalid{border:none;background-color:transparent;color:#fff}.select-input[multiple]{height:64px}.select-input--material{color:#fff;font-size:15px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTBweCIgaGVpZ2h0PSI1cHgiIHZpZXdCb3g9IjAgMCAxMCA1IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0My4yICgzOTA2OSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+c2VsZWN0LWFsbG93PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9InNlbGVjdCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Imlvcy1zZWxlY3QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOTguMDAwMDAwLCAtMTE0LjAwMDAwMCkiIGZpbGw9IiM3NTc1NzUiPgogICAgICAgICAgICA8ZyBpZD0ibWVudS1iYXItKy1vcGVuLW1lbnUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMy4wMDAwMDAsIDEwMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJtZW51LWJhciI+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9InNlbGVjdC1hbGxvdyIgcG9pbnRzPSI3NSAxNCA4MCAxOSA4NSAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=),linear-gradient(to top,rgba(255,255,255,.88) 50%,rgba(255,255,255,.88) 50%);background-size:auto,100% 1px;background-repeat:no-repeat;background-position:right center,left bottom;border:none;transform:translate3d(0,0,0)}.select-input--material__label{color:rgba(255,255,255,.19);position:absolute;left:0;top:2px;font-size:16px;pointer-events:none}.select-input--material__label--active{color:rgba(255,255,255,.85);-webkit-transform:translate(0,-75%) scale(.75);transform:translate(0,-75%) scale(.75);-webkit-transform-origin:left top;transform-origin:left top;transition:color .1s ease-in,-webkit-transform .1s ease-in;transition:transform .1s ease-in,color .1s ease-in;transition:transform .1s ease-in,color .1s ease-in,-webkit-transform .1s ease-in}.select-input--material::-webkit-input-placeholder{color:rgba(255,255,255,.19);line-height:20px}.select-input--material:-ms-input-placeholder{color:rgba(255,255,255,.19);line-height:20px}.select-input--material::-ms-input-placeholder{color:rgba(255,255,255,.19);line-height:20px}.select-input--material::placeholder{color:rgba(255,255,255,.19);line-height:20px}@-webkit-keyframes material-select-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}@keyframes material-select-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}.action-sheet-button,.action-sheet-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;height:56px;line-height:56px}.select-input--underbar{border:none;border-bottom:1px solid #242424}.select-input--underbar:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent;border-bottom:1px solid #242424}.select-input--underbar:disabled::-webkit-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled:-ms-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled::-ms-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled::placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:invalid{color:#fff;border:none;background-color:transparent;border-bottom:1px solid #242424}.action-sheet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;cursor:default;position:absolute;left:10px;right:10px;bottom:10px;z-index:2;max-height:100%;overflow-y:scroll}.action-sheet-button{box-sizing:border-box;font-size:20px;text-align:center;color:#0076FF;background-color:rgba(255,255,255,.9);border-radius:0;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;display:block;width:100%;background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 100%)}.action-sheet-button:first-child,.action-sheet-title:first-child{border-top-left-radius:12px;border-top-right-radius:12px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.action-sheet-button{background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 50%,transparent 50%)}}.action-sheet-button:active{background-color:#e9e9e9;background-image:none}.action-sheet-button:focus{outline:0}.action-sheet-button:nth-last-of-type(2){border-bottom-right-radius:12px;border-bottom-left-radius:12px;background-image:none}.action-sheet-button:last-of-type{border-radius:12px;margin:8px 0 0;background-color:#fff;background-image:none;font-weight:600}.action-sheet-button:last-of-type:active{background-color:#e9e9e9}.action-sheet-button--destructive{color:#fe3824}.action-sheet-title{box-sizing:border-box;font-size:13px;color:#8f8e94;text-align:center;background-color:rgba(255,255,255,.9);background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.action-sheet-title{background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 50%,transparent 50%)}}.action-sheet-button--material,.action-sheet-title--material{font-family:Roboto,Noto,sans-serif;background-image:none;text-align:left;font-size:16px;padding:0 0 0 16px;color:#686868;-webkit-font-smoothing:antialiased}.action-sheet-icon{display:none}.action-sheet-mask{position:absolute;left:0;top:0;right:0;bottom:0;background-color:rgba(0,0,0,.1);z-index:1}.action-sheet-button--material,.action-sheet-button--material:last-of-type,.action-sheet-title--material{border-radius:0;background-color:#fff;font-weight:400}.action-sheet--material{left:0;right:0;bottom:0;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.action-sheet-title--material{height:56px;line-height:56px}.action-sheet-title--material:first-child{border-radius:0}.action-sheet-button--material{height:52px;line-height:52px}.action-sheet-button--material:first-child,.action-sheet-button--material:nth-last-of-type(2){border-radius:0}.action-sheet-button--material:last-of-type{margin:0}.action-sheet-icon--material{display:inline-block;float:left;height:52px;line-height:52px;margin-right:32px;font-size:26px;width:.8em;text-align:center}.card,.card__title{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;display:block;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}.action-sheet-mask--material{background-color:rgba(0,0,0,.2)}.card{-webkit-font-smoothing:antialiased;font-weight:400;box-shadow:0 1px 2px rgba(0,0,0,.12);border-radius:8px;background-color:#242424;margin:8px;padding:16px;text-align:left;word-wrap:break-word}.card__content{margin:0;font-size:14px;line-height:1.4;color:#fff}.card__title{-webkit-font-smoothing:antialiased;font-weight:400;font-size:20px;margin:4px 0 8px;padding:0;color:#fff}.card--material,.card--material__title{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.card--material{background-color:#424242;border-radius:2px;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.card--material__content{font-size:14px;line-height:1.4;color:rgba(255,255,255,.46)}.card--material__title{font-size:24px;margin:8px 0 12px}.toast{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;position:absolute;z-index:2;left:8px;right:8px;bottom:0;margin:8px 0;border-radius:8px;background-color:#ccc;display:-webkit-box;display:-webkit-flex;display:flex;min-height:48px;line-height:1.5;box-sizing:border-box;padding:16px}.toast--material__button,.toast--material__message{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.toast__message{font-size:14px;color:#000;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;text-align:left;margin:0 16px 0 0;white-space:normal}.toast__button{font-size:14px;color:#000;-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background-color:transparent;cursor:default;text-transform:uppercase}.toast__button:focus{outline:0}.toast__button:active{opacity:.4}.toast--material{left:0;right:0;bottom:0;margin:0;background-color:#ccc;border-radius:0;padding:0 24px}.bottom-bar,.tabbar:not(.tabbar--top){padding-bottom:0}.toast--material__message{margin:0 24px 0 0}.toast--material__button{color:#583905}.toolbar{top:0;box-sizing:border-box;padding-top:0}.bottom-bar{bottom:0;box-sizing:border-box}.toolbar+.page__background{top:44px}.page__content{top:0;padding-top:0;bottom:0}.toolbar+.page__background+.page__content{top:44px;padding-top:0}.page-with-bottom-toolbar>.page__content{bottom:44px}.toolbar.toolbar--material+.page__background{top:56px}.toolbar.toolbar--material+.page__background+.page__content{top:56px;padding-top:0}.toolbar.toolbar--transparent+.page__background{top:0}.toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,.toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:44px}.toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,.toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:56px}.tabbar--top{padding-top:0}@media (orientation:portrait){html[onsflag-iphonex-portrait] .fab--top__center,html[onsflag-iphonex-portrait] .fab--top__left,html[onsflag-iphonex-portrait] .fab--top__right{top:64px}html[onsflag-iphonex-portrait] .fab--bottom__center,html[onsflag-iphonex-portrait] .fab--bottom__left,html[onsflag-iphonex-portrait] .fab--bottom__right{bottom:34px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .page__content{padding-left:44px;padding-right:44px}html[onsflag-iphonex-landscape] .dialog .page__content,html[onsflag-iphonex-landscape] .modal .page__content{padding-left:0;padding-right:0}html[onsflag-iphonex-landscape] .toolbar__left{padding-left:44px}html[onsflag-iphonex-landscape] .toolbar__right{padding-right:44px}html[onsflag-iphonex-landscape] .bottom-bar{padding-right:44px;padding-left:44px}html[onsflag-iphonex-landscape] .tabbar{padding-left:44px;padding-right:44px;width:calc(100% - 88px)}html[onsflag-iphonex-landscape] .fab--bottom__center,html[onsflag-iphonex-landscape] .fab--bottom__left,html[onsflag-iphonex-landscape] .fab--bottom__right{bottom:21px}html[onsflag-iphonex-landscape] .fab--bottom__left,html[onsflag-iphonex-landscape] .fab--top__left{left:44px}html[onsflag-iphonex-landscape] .fab--bottom__right,html[onsflag-iphonex-landscape] .fab--top__right{right:44px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .action-sheet{bottom:48px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .action-sheet{left:calc((100vw - 100vh + 20px)/ 2);right:calc((100vw - 100vh + 20px)/ 2);bottom:33px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .toast{bottom:34px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .toast{left:52px;right:52px;bottom:21px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .toolbar{top:0;box-sizing:content-box;padding-top:44px}html[onsflag-iphonex-portrait] .dialog .toolbar,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar{top:0;box-sizing:border-box;padding-top:0}html[onsflag-iphonex-portrait] .bottom-bar{bottom:0;box-sizing:content-box;padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .bottom-bar,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .bottom-bar,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .bottom-bar{bottom:0;box-sizing:border-box;padding-bottom:0}html[onsflag-iphonex-portrait] .page__content{top:0;padding-top:44px;bottom:0;padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .page__content{top:0;padding-top:0}html[onsflag-iphonex-portrait] .dialog .page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .page__content,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page__content{bottom:0;padding-bottom:0}html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content{top:88px;padding-top:0}html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content{top:44px;padding-top:0}html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content{bottom:78px;padding-bottom:0}html[onsflag-iphonex-portrait] .dialog .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar>.page__content{bottom:44px;padding-bottom:0}html[onsflag-iphonex-portrait] .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:88px}html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page__content{top:0;padding-top:44px}html[onsflag-iphonex-portrait] .tabbar--top{padding-top:44px}html[onsflag-iphonex-portrait] .dialog .tabbar--top,html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top{padding-top:0}html[onsflag-iphonex-portrait] .tabbar--top__content{top:93px}html[onsflag-iphonex-portrait] .dialog .tabbar--top__content,html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top__content{top:49px}html[onsflag-iphonex-portrait] .tabbar:not(.tabbar--top):not(.tabbar--top){padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .tabbar:not(.tabbar--top):not(.tabbar--top),html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .tabbar:not(.tabbar--top),html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top){padding-bottom:0}html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content){bottom:83px}html[onsflag-iphonex-portrait] .dialog .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content){bottom:49px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .bottom-bar{bottom:0;box-sizing:content-box;padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .bottom-bar,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .bottom-bar,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .bottom-bar{bottom:0;box-sizing:border-box;padding-bottom:0}html[onsflag-iphonex-landscape] .page__content{bottom:0;padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .page__content,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page__content{bottom:0;padding-bottom:0}html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content{bottom:65px;padding-bottom:0}html[onsflag-iphonex-landscape] .dialog .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar>.page__content{bottom:44px;padding-bottom:0}html[onsflag-iphonex-landscape] .tabbar:not(.tabbar--top){padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .tabbar:not(.tabbar--top),html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .tabbar:not(.tabbar--top),html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top){padding-bottom:0}html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content){bottom:70px}html[onsflag-iphonex-landscape] .dialog .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content){bottom:49px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset){margin-left:-44px;margin-right:-44px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-header{padding-left:59px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item{padding-left:58px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:60px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:50px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:56px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:74px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset){margin-left:0;margin-right:0}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-header{padding-left:15px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item{padding-left:14px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:16px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:6px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:12px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:30px}} diff --git a/old_frontend/lib/css/dark-valetudo-map.css b/old_frontend/lib/css/dark-valetudo-map.css deleted file mode 100644 index 793efb1e..00000000 --- a/old_frontend/lib/css/dark-valetudo-map.css +++ /dev/null @@ -1,40 +0,0 @@ -/*Dark theme for valetudo map. See valetudo-map.css for corresponding light theme*/ -:root { - --map-background-1: #222222; - --map-background-2: #111111; - --map-free: #0076ff; - --map-occupied: #333333; - --path: #000000; -} - -.map-page-container { - height: 100%; - width: 100%; - display: grid; - grid-template-columns: 1fr; - grid-template-rows: auto 1fr; - justify-items: stretch; - align-items: stretch; -} - -canvas#map-canvas { - height: 100%; - width: 100%; - touch-action: none; - background-image: linear-gradient(var(--map-background-1), var(--map-background-2)); -} - -.map-page-buttons { - position: absolute; - right: 1.5em; - bottom: 1.5em; - display: grid; - grid-template-columns: auto; - grid-template-rows: auto; - grid-gap: 0.5em; -} - -.map-page-buttons > ons-fab { - background-color: #212121; - color: #aaa; -} diff --git a/old_frontend/lib/css/font_awesome/css/font-awesome.min.css b/old_frontend/lib/css/font_awesome/css/font-awesome.min.css deleted file mode 100644 index 540440ce..00000000 --- a/old_frontend/lib/css/font_awesome/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/old_frontend/lib/css/font_awesome/fonts/FontAwesome.otf b/old_frontend/lib/css/font_awesome/fonts/FontAwesome.otf deleted file mode 100644 index 401ec0f3..00000000 Binary files a/old_frontend/lib/css/font_awesome/fonts/FontAwesome.otf and /dev/null differ diff --git a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.eot b/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca9..00000000 Binary files a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.svg b/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845e..00000000 --- a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.ttf b/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2f..00000000 Binary files a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.woff b/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a4..00000000 Binary files a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.woff2 b/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc60..00000000 Binary files a/old_frontend/lib/css/font_awesome/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/old_frontend/lib/css/ionicons/css/ionicons.min.css b/old_frontend/lib/css/ionicons/css/ionicons.min.css deleted file mode 100644 index 08168f9e..00000000 --- a/old_frontend/lib/css/ionicons/css/ionicons.min.css +++ /dev/null @@ -1,11 +0,0 @@ -@charset "UTF-8";/*! - Ionicons, v2.0.1 - Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ - https://twitter.com/benjsperry https://twitter.com/ionicframework - MIT License: https://github.com/driftyco/ionicons - - Android-style icons originally built by Google’s - Material Design Icons: https://github.com/google/material-design-icons - used under CC BY http://creativecommons.org/licenses/by/4.0/ - Modified icons to fit ionicon’s grid from original. -*/@font-face{font-family:"Ionicons";src:url("../fonts/ionicons.eot");src:url("../fonts/ionicons.eot") format("embedded-opentype"),url("../fonts/ionicons.ttf") format("truetype"),url("../fonts/ionicons.woff") format("woff"),url("../fonts/ionicons.svg") format("svg");font-weight:normal;font-style:normal}.ion,.ionicons,.ion-alert:before,.ion-alert-circled:before,.ion-android-add:before,.ion-android-add-circle:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done:before,.ion-android-done-all:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite:before,.ion-android-favorite-outline:before,.ion-android-film:before,.ion-android-folder:before,.ion-android-folder-open:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone:before,.ion-android-microphone-off:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person:before,.ion-android-person-add:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove:before,.ion-android-remove-circle:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share:before,.ion-android-share-alt:before,.ion-android-star:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace:before,.ion-backspace-outline:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox:before,.ion-chatbox-working:before,.ion-chatboxes:before,.ion-chatbubble:before,.ion-chatbubble-working:before,.ion-chatbubbles:before,.ion-checkmark:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close:before,.ion-close-circled:before,.ion-close-round:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code:before,.ion-code-download:before,.ion-code-working:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document:before,.ion-document-text:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email:before,.ion-email-unread:before,.ion-erlenmeyer-flask:before,.ion-erlenmeyer-flask-bubbles:before,.ion-eye:before,.ion-eye-disabled:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash:before,.ion-flash-off:before,.ion-folder:before,.ion-fork:before,.ion-fork-repo:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy:before,.ion-happy-outline:before,.ion-headphone:before,.ion-heart:before,.ion-heart-broken:before,.ion-help:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information:before,.ion-information-circled:before,.ion-ionic:before,.ion-ios-alarm:before,.ion-ios-alarm-outline:before,.ion-ios-albums:before,.ion-ios-albums-outline:before,.ion-ios-americanfootball:before,.ion-ios-americanfootball-outline:before,.ion-ios-analytics:before,.ion-ios-analytics-outline:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at:before,.ion-ios-at-outline:before,.ion-ios-barcode:before,.ion-ios-barcode-outline:before,.ion-ios-baseball:before,.ion-ios-baseball-outline:before,.ion-ios-basketball:before,.ion-ios-basketball-outline:before,.ion-ios-bell:before,.ion-ios-bell-outline:before,.ion-ios-body:before,.ion-ios-body-outline:before,.ion-ios-bolt:before,.ion-ios-bolt-outline:before,.ion-ios-book:before,.ion-ios-book-outline:before,.ion-ios-bookmarks:before,.ion-ios-bookmarks-outline:before,.ion-ios-box:before,.ion-ios-box-outline:before,.ion-ios-briefcase:before,.ion-ios-briefcase-outline:before,.ion-ios-browsers:before,.ion-ios-browsers-outline:before,.ion-ios-calculator:before,.ion-ios-calculator-outline:before,.ion-ios-calendar:before,.ion-ios-calendar-outline:before,.ion-ios-camera:before,.ion-ios-camera-outline:before,.ion-ios-cart:before,.ion-ios-cart-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatbubble:before,.ion-ios-chatbubble-outline:before,.ion-ios-checkmark:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock:before,.ion-ios-clock-outline:before,.ion-ios-close:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-cloud:before,.ion-ios-cloud-download:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloudy:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-outline:before,.ion-ios-cog:before,.ion-ios-cog-outline:before,.ion-ios-color-filter:before,.ion-ios-color-filter-outline:before,.ion-ios-color-wand:before,.ion-ios-color-wand-outline:before,.ion-ios-compose:before,.ion-ios-compose-outline:before,.ion-ios-contact:before,.ion-ios-contact-outline:before,.ion-ios-copy:before,.ion-ios-copy-outline:before,.ion-ios-crop:before,.ion-ios-crop-strong:before,.ion-ios-download:before,.ion-ios-download-outline:before,.ion-ios-drag:before,.ion-ios-email:before,.ion-ios-email-outline:before,.ion-ios-eye:before,.ion-ios-eye-outline:before,.ion-ios-fastforward:before,.ion-ios-fastforward-outline:before,.ion-ios-filing:before,.ion-ios-filing-outline:before,.ion-ios-film:before,.ion-ios-film-outline:before,.ion-ios-flag:before,.ion-ios-flag-outline:before,.ion-ios-flame:before,.ion-ios-flame-outline:before,.ion-ios-flask:before,.ion-ios-flask-outline:before,.ion-ios-flower:before,.ion-ios-flower-outline:before,.ion-ios-folder:before,.ion-ios-folder-outline:before,.ion-ios-football:before,.ion-ios-football-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-b:before,.ion-ios-game-controller-b-outline:before,.ion-ios-gear:before,.ion-ios-gear-outline:before,.ion-ios-glasses:before,.ion-ios-glasses-outline:before,.ion-ios-grid-view:before,.ion-ios-grid-view-outline:before,.ion-ios-heart:before,.ion-ios-heart-outline:before,.ion-ios-help:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-home:before,.ion-ios-home-outline:before,.ion-ios-infinite:before,.ion-ios-infinite-outline:before,.ion-ios-information:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-ionic-outline:before,.ion-ios-keypad:before,.ion-ios-keypad-outline:before,.ion-ios-lightbulb:before,.ion-ios-lightbulb-outline:before,.ion-ios-list:before,.ion-ios-list-outline:before,.ion-ios-location:before,.ion-ios-location-outline:before,.ion-ios-locked:before,.ion-ios-locked-outline:before,.ion-ios-loop:before,.ion-ios-loop-strong:before,.ion-ios-medical:before,.ion-ios-medical-outline:before,.ion-ios-medkit:before,.ion-ios-medkit-outline:before,.ion-ios-mic:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-minus:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-monitor:before,.ion-ios-monitor-outline:before,.ion-ios-moon:before,.ion-ios-moon-outline:before,.ion-ios-more:before,.ion-ios-more-outline:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate:before,.ion-ios-navigate-outline:before,.ion-ios-nutrition:before,.ion-ios-nutrition-outline:before,.ion-ios-paper:before,.ion-ios-paper-outline:before,.ion-ios-paperplane:before,.ion-ios-paperplane-outline:before,.ion-ios-partlysunny:before,.ion-ios-partlysunny-outline:before,.ion-ios-pause:before,.ion-ios-pause-outline:before,.ion-ios-paw:before,.ion-ios-paw-outline:before,.ion-ios-people:before,.ion-ios-people-outline:before,.ion-ios-person:before,.ion-ios-person-outline:before,.ion-ios-personadd:before,.ion-ios-personadd-outline:before,.ion-ios-photos:before,.ion-ios-photos-outline:before,.ion-ios-pie:before,.ion-ios-pie-outline:before,.ion-ios-pint:before,.ion-ios-pint-outline:before,.ion-ios-play:before,.ion-ios-play-outline:before,.ion-ios-plus:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetags:before,.ion-ios-pricetags-outline:before,.ion-ios-printer:before,.ion-ios-printer-outline:before,.ion-ios-pulse:before,.ion-ios-pulse-strong:before,.ion-ios-rainy:before,.ion-ios-rainy-outline:before,.ion-ios-recording:before,.ion-ios-recording-outline:before,.ion-ios-redo:before,.ion-ios-redo-outline:before,.ion-ios-refresh:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-reload:before,.ion-ios-reverse-camera:before,.ion-ios-reverse-camera-outline:before,.ion-ios-rewind:before,.ion-ios-rewind-outline:before,.ion-ios-rose:before,.ion-ios-rose-outline:before,.ion-ios-search:before,.ion-ios-search-strong:before,.ion-ios-settings:before,.ion-ios-settings-strong:before,.ion-ios-shuffle:before,.ion-ios-shuffle-strong:before,.ion-ios-skipbackward:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipforward:before,.ion-ios-skipforward-outline:before,.ion-ios-snowy:before,.ion-ios-speedometer:before,.ion-ios-speedometer-outline:before,.ion-ios-star:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-stopwatch:before,.ion-ios-stopwatch-outline:before,.ion-ios-sunny:before,.ion-ios-sunny-outline:before,.ion-ios-telephone:before,.ion-ios-telephone-outline:before,.ion-ios-tennisball:before,.ion-ios-tennisball-outline:before,.ion-ios-thunderstorm:before,.ion-ios-thunderstorm-outline:before,.ion-ios-time:before,.ion-ios-time-outline:before,.ion-ios-timer:before,.ion-ios-timer-outline:before,.ion-ios-toggle:before,.ion-ios-toggle-outline:before,.ion-ios-trash:before,.ion-ios-trash-outline:before,.ion-ios-undo:before,.ion-ios-undo-outline:before,.ion-ios-unlocked:before,.ion-ios-unlocked-outline:before,.ion-ios-upload:before,.ion-ios-upload-outline:before,.ion-ios-videocam:before,.ion-ios-videocam-outline:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass:before,.ion-ios-wineglass-outline:before,.ion-ios-world:before,.ion-ios-world-outline:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon:before,.ion-navicon-round:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person:before,.ion-person-add:before,.ion-person-stalker:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply:before,.ion-reply-all:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad:before,.ion-sad-outline:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android:before,.ion-social-android-outline:before,.ion-social-angular:before,.ion-social-angular-outline:before,.ion-social-apple:before,.ion-social-apple-outline:before,.ion-social-bitcoin:before,.ion-social-bitcoin-outline:before,.ion-social-buffer:before,.ion-social-buffer-outline:before,.ion-social-chrome:before,.ion-social-chrome-outline:before,.ion-social-codepen:before,.ion-social-codepen-outline:before,.ion-social-css3:before,.ion-social-css3-outline:before,.ion-social-designernews:before,.ion-social-designernews-outline:before,.ion-social-dribbble:before,.ion-social-dribbble-outline:before,.ion-social-dropbox:before,.ion-social-dropbox-outline:before,.ion-social-euro:before,.ion-social-euro-outline:before,.ion-social-facebook:before,.ion-social-facebook-outline:before,.ion-social-foursquare:before,.ion-social-foursquare-outline:before,.ion-social-freebsd-devil:before,.ion-social-github:before,.ion-social-github-outline:before,.ion-social-google:before,.ion-social-google-outline:before,.ion-social-googleplus:before,.ion-social-googleplus-outline:before,.ion-social-hackernews:before,.ion-social-hackernews-outline:before,.ion-social-html5:before,.ion-social-html5-outline:before,.ion-social-instagram:before,.ion-social-instagram-outline:before,.ion-social-javascript:before,.ion-social-javascript-outline:before,.ion-social-linkedin:before,.ion-social-linkedin-outline:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest:before,.ion-social-pinterest-outline:before,.ion-social-python:before,.ion-social-reddit:before,.ion-social-reddit-outline:before,.ion-social-rss:before,.ion-social-rss-outline:before,.ion-social-sass:before,.ion-social-skype:before,.ion-social-skype-outline:before,.ion-social-snapchat:before,.ion-social-snapchat-outline:before,.ion-social-tumblr:before,.ion-social-tumblr-outline:before,.ion-social-tux:before,.ion-social-twitch:before,.ion-social-twitch-outline:before,.ion-social-twitter:before,.ion-social-twitter-outline:before,.ion-social-usd:before,.ion-social-usd-outline:before,.ion-social-vimeo:before,.ion-social-vimeo-outline:before,.ion-social-whatsapp:before,.ion-social-whatsapp-outline:before,.ion-social-windows:before,.ion-social-windows-outline:before,.ion-social-wordpress:before,.ion-social-wordpress-outline:before,.ion-social-yahoo:before,.ion-social-yahoo-outline:before,.ion-social-yen:before,.ion-social-yen-outline:before,.ion-social-youtube:before,.ion-social-youtube-outline:before,.ion-soup-can:before,.ion-soup-can-outline:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle:before,.ion-toggle-filled:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt:before,.ion-tshirt-outline:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before{display:inline-block;font-family:"Ionicons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} \ No newline at end of file diff --git a/old_frontend/lib/css/ionicons/fonts/ionicons.eot b/old_frontend/lib/css/ionicons/fonts/ionicons.eot deleted file mode 100644 index 9caa3489..00000000 Binary files a/old_frontend/lib/css/ionicons/fonts/ionicons.eot and /dev/null differ diff --git a/old_frontend/lib/css/ionicons/fonts/ionicons.svg b/old_frontend/lib/css/ionicons/fonts/ionicons.svg deleted file mode 100644 index 781ea0ea..00000000 --- a/old_frontend/lib/css/ionicons/fonts/ionicons.svg +++ /dev/null @@ -1,2230 +0,0 @@ - - - - - -Created by FontForge 20120731 at Wed Jan 14 22:40:14 2015 - By Adam Bradley -Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/old_frontend/lib/css/ionicons/fonts/ionicons.ttf b/old_frontend/lib/css/ionicons/fonts/ionicons.ttf deleted file mode 100644 index 180ce515..00000000 Binary files a/old_frontend/lib/css/ionicons/fonts/ionicons.ttf and /dev/null differ diff --git a/old_frontend/lib/css/ionicons/fonts/ionicons.woff b/old_frontend/lib/css/ionicons/fonts/ionicons.woff deleted file mode 100644 index 5bb6aecb..00000000 Binary files a/old_frontend/lib/css/ionicons/fonts/ionicons.woff and /dev/null differ diff --git a/old_frontend/lib/css/old-onsen-css-components.min.css b/old_frontend/lib/css/old-onsen-css-components.min.css deleted file mode 100644 index b29c3f9a..00000000 --- a/old_frontend/lib/css/old-onsen-css-components.min.css +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * Copyright 2013-2017 ASIAL CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *//*! - * Copyright 2012 Adobe Systems Inc.; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */.notification,.toolbar,body{overflow:hidden}a,body,button,input,select,textarea{touch-action:manipulation}.page,.page__background,.page__content{background-color:#f9f9f9;position:absolute}.page,.switch__input,body{position:absolute}.page,.page--material,.page--material__content{font-weight:400}.page,.switch__input,.switch__toggle,body{top:0;left:0;right:0;bottom:0}.switch,.switch__handle{background-clip:padding-box;box-sizing:border-box}.switch--material__handle:before,.switch__handle,.tabbar--material__button:after{content:''}.switch,.switch__input{vertical-align:top;z-index:0}html{height:100%;width:100%}body{padding:0;margin:0;-webkit-text-size-adjust:100%}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}input,select,textarea{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto;-moz-user-select:text;-webkit-touch-callout:none}.notification,.toolbar{-webkit-user-select:none;-ms-user-select:none}input:active,input:focus,select:active,select:focus,textarea:active,textarea:focus{outline:0}h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4,h5,h6{font-size:18px}.page{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-moz-osx-font-smoothing:grayscale;overflow-x:visible;overflow-y:hidden;color:#1f1f21;-ms-overflow-style:none;-webkit-font-smoothing:antialiased}.page--material,.page--material__content,.page__content h1,.page__content h2,.page__content h3,.page__content h4,.page__content h5{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.page::-webkit-scrollbar{display:none}.page__background,.page__content{top:0;left:0;right:0;bottom:0;box-sizing:border-box}.page--material,.page--material__background{background-color:#fff}.page__content h1,.page__content h2,.page__content h3,.page__content h4,.page__content h5{font-weight:400;font-weight:500;margin:.6em 0;padding:0}.page__content h1{font-size:28px}.page__content h2{font-size:24px}.page__content h3{font-size:20px}.page--material__content h1,.page--material__content h2,.page--material__content h3,.page--material__content h4,.page--material__content h5{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;font-weight:500;margin:.6em 0;padding:0}.page--material__content h1{font-size:28px}.page--material__content h2{font-size:24px}.page--material__content h3{font-size:20px}.switch{display:inline-block;position:relative;min-width:51px;font-size:17px;padding:0 20px;border:none;overflow:visible;width:51px;height:32px;text-align:left}.switch__input{padding:0;border:0;background-color:transparent;outline:0;width:100%;height:100%;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.switch__handle,.switch__toggle{background-color:#fff;transition-property:all;transition-duration:.35s;position:absolute}.range__input,.switch--material__input{outline:0;-webkit-appearance:none;vertical-align:top}.switch__toggle{border-radius:30px;transition-timing-function:ease-out;box-shadow:inset 0 0 0 2px #e5e5e5}.switch__handle{border-radius:28px;height:28px;width:28px;left:1px;top:2px;transition-timing-function:cubic-bezier(.59,.01,.5,.99);box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25)}.switch--active__handle{transition:none}:checked+.switch__toggle{box-shadow:inset 0 0 0 2px #5198db;background-color:#5198db}:checked+.switch__toggle>.switch__handle{left:21px;box-shadow:0 3px 2px rgba(0,0,0,.25)}:disabled+.switch__toggle{opacity:.3;cursor:default;pointer-events:none}.switch__touch{position:absolute;top:-5px;bottom:-5px;left:-10px;right:-10px}.switch--material{width:36px;height:24px;padding:0 10px;min-width:36px}.switch--material__toggle{background-color:#b0afaf;margin-top:5px;height:14px;box-shadow:none}.switch--material__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;width:100%;height:100%;margin:0;-moz-appearance:none;appearance:none;z-index:0}.switch--material__handle{background-color:#f1f1f1;left:0;margin-top:-5px;width:20px;height:20px;box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4)}:checked+.switch--material__toggle{background-color:#77c2bb;box-shadow:none}.button--material,:checked+.switch--material__toggle>.switch--material__handle{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}:checked+.switch--material__toggle>.switch--material__handle{left:16px;background-color:#009688}:disabled+.switch--material__toggle{opacity:.3;cursor:default;pointer-events:none}.switch--material__handle:before{background:0 0;display:block;width:100%;height:100%;border-radius:50%;z-index:0;box-shadow:0 0 0 0 rgba(0,0,0,.12);transition:box-shadow .1s linear}.switch--material__toggle>.switch--active__handle:before{box-shadow:0 0 0 14px rgba(0,0,0,.12)}:checked+.switch--material__toggle>.switch--active__handle:before{box-shadow:0 0 0 14px rgba(0,150,136,.2)}.switch--material__touch{position:absolute;top:-10px;bottom:-10px;left:-15px;right:-15px}.range,.range__input{height:30px;position:relative;padding:0;margin:0}.range{display:inline-block;width:100px;background-image:linear-gradient(#a4aab3,#a4aab3);background-position:left center;background-size:100% 2px;background-repeat:no-repeat;background-color:transparent}.range__input{box-sizing:border-box;font:inherit;color:inherit;background:left center no-repeat;border:none;line-height:1;-moz-appearance:none;appearance:none;background-image:linear-gradient(rgba(24,103,194,.81),rgba(24,103,194,.81));background-size:0 2px;z-index:1;width:100%}.range__input::-moz-range-track{position:relative;border:none;background:0 0;box-shadow:none;top:0;margin:0;padding:0}.range__input::-ms-track{position:relative;border:none;background-color:#a4aab3;height:0;border-radius:50%}.range__input::-webkit-slider-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0;box-sizing:border-box;-webkit-appearance:none;appearance:none;top:0;z-index:1}.range__focus-ring,.segment__input{outline:0;-moz-appearance:none;top:0}.range__input::-moz-range-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0}.range__input::-ms-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0;top:0}.range__input::-ms-fill-lower{height:2px;background-color:rgba(24,103,194,.81)}.range__input::-ms-tooltip{display:none}.range__input:disabled{opacity:1;pointer-events:none}.range__focus-ring{pointer-events:none;left:0;display:none;box-sizing:border-box;padding:0;margin:0;font:inherit;color:inherit;border:none;vertical-align:top;line-height:1;-webkit-appearance:none;appearance:none;background:0 0;height:30px;position:absolute;z-index:0;width:100%}.notification,.toolbar__item{box-sizing:border-box;font:inherit}.range--disabled{opacity:.3;cursor:default;pointer-events:none}.range--material{position:relative;background-image:linear-gradient(#bdbdbd,#bdbdbd)}.range--material__input{background-image:linear-gradient(#009688,#009688);background-position:center left;background-size:0 2px}.range--material__focus-ring{display:block}.range--material__focus-ring::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border:none;box-shadow:0 0 0 9px #009688;background-color:#009688;border-radius:50%;opacity:0;transition:opacity .25s ease-out,-webkit-transform .25s ease-out;transition:opacity .25s ease-out,transform .25s ease-out;transition:opacity .25s ease-out,transform .25s ease-out,-webkit-transform .25s ease-out}.range--material__input.range__input--active+.range--material__focus-ring::-webkit-slider-thumb{opacity:.2;-webkit-transform:scale(1.5,1.5,1.5);transform:scale(1.5,1.5,1.5)}.range--material__input::-webkit-slider-thumb{position:relative;box-sizing:border-box;border:none;background-color:transparent;width:14px;height:32px;border-radius:0;box-shadow:none;background-image:radial-gradient(circle farthest-corner,#009688 0,#009688 6.6px,transparent 7px);transition:-webkit-transform .1s linear;transition:transform .1s linear;transition:transform .1s linear,-webkit-transform .1s linear;overflow:visible}.range--material__input[_zero]::-webkit-slider-thumb{background-image:radial-gradient(circle farthest-corner,#f2f2f2 0,#f2f2f2 4px,#bdbdbd 4px,#bdbdbd 6.4px,transparent 7px)}.range--material__input[_zero]+.range--material__focus-ring::-webkit-slider-thumb{box-shadow:0 0 0 9px #bdbdbd}.bottom-bar,.toolbar{-moz-osx-font-smoothing:grayscale;word-spacing:0;cursor:default;box-shadow:none;border-bottom:none;z-index:2}.range--material__input::-moz-range-track{background:0 0}.range--material__input::-moz-range-thumb,.range--material__input:focus::-moz-range-thumb{box-sizing:border-box;border:none;width:14px;height:32px;border-radius:0;background-color:transparent;background-image:-moz-radial-gradient(circle farthest-corner,#009688 0,#009688 6.6px,transparent 7px);box-shadow:none}.range--material__input.range__input--active::-webkit-slider-thumb,.range--material__input:active::-webkit-slider-thumb{-webkit-transform:scale(1.5);transform:scale(1.5);transition:-webkit-transform .1s linear;transition:transform .1s linear;transition:transform .1s linear,-webkit-transform .1s linear}.button,.button:active,.button:hover{transition:none}.range--disabled.range--material{opacity:1}.range--disabled>.range--material__input{background-image:none}.range--material__input:disabled::-webkit-slider-thumb{background-image:radial-gradient(circle farthest-corner,#b0b0b0 0,#b0b0b0 4px,#eee 4.4px,#eee 7.6px,transparent 7.6px);transition:none}.range--material__input:disabled::-moz-range-thumb{background-image:-moz-radial-gradient(circle farthest-corner,#b0b0b0 0,#b0b0b0 4px,#eee 4.4px,#eee 7.6px,transparent 7.6px);transition:none}.notification{position:relative;display:inline-block;vertical-align:top;background:#dc5236;border:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;cursor:default;-moz-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;text-decoration:none;margin:0;padding:0 4px;width:auto;height:19px;border-radius:19px;color:#fff;text-align:center;font-size:16px;min-width:19px;line-height:19px;font-weight:400}.notification--material,.toolbar{-webkit-font-smoothing:antialiased}.toolbar,.toolbar__item{padding:0;margin:0;border:none;height:44px}.notification:empty{display:none}.bottom-bar--aligned,.toolbar{display:-webkit-box;display:-webkit-flex}.notification--material{font-family:Roboto,Noto,sans-serif;background-color:#e91e63;font-size:16px;font-weight:500;color:#fff}.toolbar{font:inherit;line-height:normal;-moz-user-select:none;user-select:none;display:flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;background:bottom no-repeat #fff;color:#1f1f21;font-weight:400;width:100%;white-space:nowrap;background-size:100% 1px;background-image:linear-gradient(0deg,#bbb,#bbb 100%)}.bottom-bar,.button{-ms-user-select:none}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.toolbar{background-image:linear-gradient(0deg,#bbb,#bbb 50%,transparent 50%)}}.toolbar__bg{background:#fff}.toolbar__item{color:inherit;background:0 0;line-height:normal;overflow:visible;display:block;vertical-align:middle}.toolbar__left,.toolbar__right{padding:0;margin:0;font:inherit;color:inherit;max-width:50%;width:27%;box-sizing:border-box;background:0 0;border:none}.toolbar__left{text-align:left;line-height:44px}.toolbar__right{text-align:right;line-height:44px}.bottom-bar,.toolbar__center,.toolbar__title{margin:0;color:#1f1f21;padding:0}.toolbar__center{box-sizing:border-box;font:inherit;background:0 0;border:none;width:46%;text-align:center;line-height:44px;font-size:17px;font-weight:500}.toolbar__title{line-height:44px;font-size:17px;font-weight:500;overflow:visible}.toolbar__center:first-child:last-child{width:100%}.bottom-bar{-webkit-font-smoothing:antialiased;white-space:nowrap;overflow:hidden;font:inherit;border:none;line-height:normal;-webkit-user-select:none;-moz-user-select:none;user-select:none;display:block;height:44px;background:top no-repeat #fff;font-weight:400;position:absolute;right:0;left:0;border-top:none;background-size:100% 1px;background-image:linear-gradient(180deg,#bbb,#bbb 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.bottom-bar{background-image:linear-gradient(180deg,#bbb,#bbb 50%,transparent 50%)}}.bottom-bar__line-height{line-height:44px;padding-bottom:0;padding-top:0}.bottom-bar--aligned{display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;line-height:44px}.toolbar--material__center,.toolbar--material__left,.toolbar--material__right{font-family:Roboto,Noto,sans-serif;font-size:20px;font-weight:500;height:56px;width:auto;line-height:56px;color:#fff;-webkit-font-smoothing:antialiased}.bottom-bar--transparent{background-color:transparent;background-image:none;border:none}.toolbar--material{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;height:56px;border-bottom:0;box-shadow:0 1px 5px rgba(0,0,0,.3);padding:0;background-color:#009688;background-size:0}.toolbar--noshadow,.toolbar--transparent{background-image:none;border-bottom:none}.toolbar--noshadow{box-shadow:none}.toolbar--material__left,.toolbar--material__right{min-width:72px}.toolbar--material__center{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;overflow:hidden;text-overflow:ellipsis;text-align:left}.toolbar--material__center:first-child{margin-left:16px}.toolbar--material__center:last-child{margin-right:16px}.button,.button--quiet{position:relative;box-sizing:border-box;margin:0;font:inherit;-moz-osx-font-smoothing:grayscale;cursor:default;-webkit-user-select:none;-moz-user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;display:inline-block;padding:4px 10px}.toolbar--material__left:empty,.toolbar--material__right:empty{min-width:16px}.toolbar--transparent{background-color:transparent;box-shadow:none}.button,.button--material{border:0 solid currentColor}.button{background:0 0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;user-select:none;font-size:17px;line-height:32px;letter-spacing:0;color:#fff;vertical-align:middle;background-color:rgba(24,103,194,.81);border-radius:3px}.button--outline,.button--outline:active,.button--outline:hover{border:1px solid rgba(24,103,194,.81)}.button:active{background-color:rgba(24,103,194,.81);opacity:.2}.button:focus{outline:0}.button:disabled,.button[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--outline{background-color:transparent;color:rgba(24,103,194,.81)}.button--outline:active{background-color:rgba(186,209,237,.81);color:rgba(24,103,194,.81);opacity:1}.button--outline:hover{transition:0}.button--light,.button--light:active{color:rgba(0,0,0,.4);border:1px solid rgba(0,0,0,.2)}.button--light{background-color:transparent}.button--light:active{background-color:rgba(0,0,0,.05);opacity:1}.button--quiet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-ms-user-select:none;user-select:none;font-size:17px;line-height:32px;letter-spacing:0;color:#fff;vertical-align:middle;border-radius:3px;transition:none;box-shadow:none;background:0 0;color:rgba(24,103,194,.81);border:none}.button--cta,.button--large--quiet{font:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;position:relative;box-sizing:border-box;margin:0;-moz-osx-font-smoothing:grayscale;cursor:default;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;letter-spacing:0;vertical-align:middle;transition:none}.button--quiet:disabled,.button--quiet[disabled]{opacity:.3;cursor:default;pointer-events:none;border:none}.button--quiet:hover{transition:none}.button--quiet:focus{outline:0}.button--quiet:active{background-color:transparent;border:none;transition:none;opacity:.2;color:rgba(24,103,194,.81)}.button--cta{display:inline-block;background:#25a6d9;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;user-select:none;padding:4px 10px;font-size:17px;line-height:32px;border-radius:3px;border:none;color:#fff}.button--large,.button--large--cta,.button--large--quiet{padding:4px 12px;width:100%;text-align:center;display:block}.button--cta:hover{transition:none}.button--cta:focus{outline:0}.button--cta:active{color:#fff;background-color:#25a6d9;transition:none;opacity:.2}.button--cta:disabled,.button--cta[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large{font-size:17px;font-weight:500;line-height:36px}.button--large:active{background-color:rgba(24,103,194,.81);opacity:.2;transition:none}.button--large:disabled,.button--large[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large:hover{transition:none}.button--large:focus{outline:0}.button--large--quiet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;user-select:none;color:#fff;border-radius:3px;font-size:17px;font-weight:500;line-height:36px;background:0 0;border:1px solid transparent;box-shadow:none;color:rgba(24,103,194,.81)}.button--large--cta,.button--material{font:inherit;-webkit-user-select:none;-moz-user-select:none}.button--large--quiet:active{transition:none;opacity:.2;color:rgba(24,103,194,.81);background:0 0;border:1px solid transparent;box-shadow:none}.button--large--quiet:disabled,.button--large--quiet[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large--quiet:hover{transition:none}.button--large--quiet:focus{outline:0}.button--large--cta{position:relative;box-sizing:border-box;margin:0;background:#25a6d9;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;cursor:default;-ms-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;letter-spacing:0;vertical-align:middle;border-radius:3px;transition:none;border:none;color:#fff;font-size:17px;font-weight:500;line-height:36px}.button--material,.button--material--flat{display:inline-block;box-sizing:border-box;cursor:default;-ms-user-select:none;height:auto;vertical-align:middle;min-height:36px;padding:0 16px;-moz-osx-font-smoothing:grayscale;margin:0;position:relative;text-align:center;overflow:hidden;letter-spacing:0;text-transform:uppercase;text-overflow:ellipsis;text-decoration:none;white-space:nowrap}.button--large--cta:hover{transition:none}.button--large--cta:focus{outline:0}.button--large--cta:active{color:#fff;background-color:#25a6d9;transition:none;opacity:.2}.button--material,.button--material:active,.button--material:hover{transition:all .25s linear}.button--large--cta:disabled,.button--large--cta[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--material{background:#009688;user-select:none;border-radius:3px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;line-height:36px;font-size:14px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);color:#fff;font-weight:500;opacity:1}.button--material--flat,.select-input--material,.text-input--material{-webkit-transform:translate3d(0,0,0)}.button--material:active{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.4);background-color:#009688;opacity:.9}.button--material:focus{outline:0}.button--material:disabled,.button--material[disabled]{transition:none;box-shadow:none;background-color:rgba(79,79,79,.26);color:rgba(0,0,0,.26);opacity:1}.button--material--flat,.button--material--flat:hover{transition:all .25s linear}.button--material--flat{font:inherit;background:0 0;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:0 solid currentColor;border-radius:3px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;line-height:36px;font-size:14px;transform:translate3d(0,0,0);font-weight:500;box-shadow:none;color:#009688}.checkbox,.tabbar__button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.button--material--flat:focus{box-shadow:none;background-color:transparent;color:#009688;outline:0;opacity:1;border:none}.button--material--flat:active{box-shadow:none;outline:0;opacity:1;border:none;background-color:rgba(153,153,153,.2);color:#009688;transition:all .25s linear}.button--material--flat:disabled,.button--material--flat[disabled]{transition:none;opacity:1;box-shadow:none;background-color:transparent;color:rgba(0,0,0,.26)}.button-bar__button:disabled,.segment__item:disabled,.tabbar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;margin:0;padding:0;border:none}.button-bar__button,.button-bar__item{border-radius:0;width:100%;padding:0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;box-sizing:border-box}.button-bar__item{margin:0;position:relative;overflow:hidden}.button-bar__button{background-color:transparent;color:rgba(18,114,224,.77);border:1px solid rgba(18,114,224,.77);font-size:13px;height:27px;line-height:27px;transition:background-color .2s linear,color .2s linear;border-width:1px 1px 1px 0}.button-bar__button:hover{transition:none}.button-bar__button:focus{outline:0}:checked+.button-bar__button{background-color:rgba(18,114,224,.77);color:#fff;transition:none}.button-bar__button:active,:active+.button-bar__button{background-color:rgba(184,213,246,.77);border:0 solid rgba(18,114,224,.77);border-top:1px solid rgba(18,114,224,.77);border-bottom:1px solid rgba(18,114,224,.77);border-right:1px solid rgba(18,114,224,.77);font-size:13px;width:100%;transition:none}.segment__button,.segment__input,.segment__item{background-color:transparent}.button-bar__item:first-child>.button-bar__button{border-left-width:1px;border-radius:4px 0 0 4px}.button-bar__item:last-child>.button-bar__button{border-right-width:1px;border-radius:0 4px 4px 0}.segment{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;margin:0;padding:0;border:none}.segment__item{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;border-radius:0;width:100%;padding:0;margin:0;position:relative;overflow:hidden;box-sizing:border-box;display:block;border:none}.segment__input,.tabbar{position:absolute;margin:0;padding:0;width:100%;bottom:0;left:0}.segment__input{right:0;border:0;z-index:1;vertical-align:top;height:100%;-webkit-appearance:none;appearance:none}.checkbox--noborder__input,.checkbox__input,.checkbox__input:checked,.tabbar__item>input{-webkit-appearance:none;-moz-appearance:none;outline:0;right:0}.segment__button{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;border-radius:0;color:rgba(18,114,224,.77);border:1px solid rgba(18,114,224,.77);font-weight:400;padding:0;font-size:13px;height:29px;line-height:29px;width:100%;transition:background-color .2s linear,color .2s linear;box-sizing:border-box;text-align:center;border-width:1px 1px 1px 0}.segment__button:hover,:active+.segment--material__button,:active+.segment__button{transition:none}.segment__button:focus{outline:0}:active+.segment__button{background-color:rgba(184,213,246,.77);border:0 solid rgba(18,114,224,.77);border-top:1px solid rgba(18,114,224,.77);border-bottom:1px solid rgba(18,114,224,.77);border-right:1px solid rgba(18,114,224,.77);font-size:13px;width:100%}:checked+.segment__button{background-color:rgba(18,114,224,.77);color:#fff;transition:none}.segment--material__button,:active+.segment--material__button{background-color:#fafafa;font-size:14px;color:rgba(0,0,0,.38)}.segment__item:first-child>.segment__button{border-left-width:1px;border-radius:4px 0 0 4px}.segment__item:last-child>.segment__button{border-right-width:1px;border-radius:0 4px 4px 0}.segment--material__button,.segment--material__item:first-child>.segment--material__button,.segment--material__item:last-child>.segment--material__button,:active+.segment--material__button{border-width:0;border-radius:0}.segment--material{border-radius:2px;overflow:hidden;box-shadow:0 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.24)}.segment--material__button{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;height:32px;line-height:32px}.tabbar,.tabbar__item{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:checked+.segment--material__button{background-color:#c8c8c8;color:#353535;border-radius:0;border-width:0}.tabbar{display:-webkit-box;display:-webkit-flex;display:flex;right:0;white-space:nowrap;height:49px;background-color:#fff;border-top:1px solid #ccc}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.tabbar{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#ccc,#ccc 50%,transparent 50%)}}.tabbar__item{position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-basis:0;flex-basis:0;width:auto;border-radius:0}.tabbar__button,.tabbar__item>input{vertical-align:top;width:100%;margin:0;padding:0}.tabbar__item>input{position:absolute;top:0;left:0;bottom:0;border:0;background-color:transparent;z-index:1;height:100%;appearance:none}.tabbar__button{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;font:inherit;background:0 0;border:none;cursor:default;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative;display:inline-block;text-decoration:none;height:49px;letter-spacing:0;color:#999;border-top:none;font-weight:400;line-height:49px}.tabbar__icon{font-size:24px;padding:0;margin:0;line-height:26px;display:block!important;height:28px}.tabbar__label{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:inline-block}.tabbar--material__button,.tabbar--material__label,.tabbar--material__label:first-child{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.tabbar__badge.notification{vertical-align:text-bottom;top:-1px;margin-left:5px;z-index:10;font-size:12px;height:16px;min-width:16px;line-height:16px;border-radius:8px}.tabbar__icon~.tabbar__badge.notification{position:absolute;top:5px;margin-left:0}.tabbar__icon+.tabbar__label{display:block;font-size:10px;line-height:1;margin:0;font-weight:400}.tabbar__label:first-child{font-size:16px;line-height:49px;margin:0;padding:0}:checked+.tabbar__button{color:rgba(24,103,194,.81);background-color:transparent;box-shadow:none;border-top:none}.tabbar__button:focus{z-index:1;border-top:none;box-shadow:none;outline:0}.tabbar__content{position:absolute;top:0;left:0;right:0;bottom:49px;z-index:0}.tabbar--autogrow .tabbar__item{-webkit-flex-basis:auto;flex-basis:auto}.tabbar--top{position:relative;top:0;left:0;right:0;bottom:auto;border-top:none;border-bottom:1px solid #ccc}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.tabbar__button{border-top:none}.tabbar--top{border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.tabbar--top__content{top:49px;left:0;right:0;bottom:0;z-index:0}.tabbar--top-border__button{background-color:transparent;border-bottom:4px solid transparent}:checked+.tabbar--top-border__button{background-color:transparent;border-bottom:4px solid rgba(24,103,194,.81)}.tabbar__border{position:absolute;bottom:0;left:0;width:0;height:4px;background-color:rgba(24,103,194,.81)}.tabbar--material{background:#009688;border-bottom-width:0;box-shadow:0 4px 2px -2px rgba(0,0,0,.14),0 3px 5px -2px rgba(0,0,0,.12),0 5px 1px -4px rgba(0,0,0,.2)}.tabbar--material__button{background-color:transparent;color:rgba(255,255,255,.6);text-transform:uppercase;font-size:14px;font-weight:400}.tabbar--material__button:after{display:block;width:0;height:2px;bottom:0;position:absolute;margin-top:-2px;background-color:#fff}:checked+.tabbar--material__button:after{width:100%;transition:width .2s ease-in-out}:checked+.tabbar--material__button{background-color:transparent;color:#fff}.tabbar--material__item:not([ripple]):active{background-color:#26a69a}.tabbar--material__border{height:2px;background-color:#fff}.back-button,.toolbar-button,.toolbar-button:active{background-color:rgba(0,0,0,0)}.tabbar--material__icon{font-size:22px!important;line-height:36px}.back-button,.back-button__label{display:inline-block;line-height:44px}.tabbar--material__label{font-weight:400}.tabbar--material__label:first-child{letter-spacing:.015em;font-weight:500;font-size:14px}.tabbar--material__icon+.tabbar--material__label{font-size:10px}.toolbar-button{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;padding:4px 10px;letter-spacing:0;color:rgba(38,100,171,.81);border-radius:2px;border:1px solid transparent;font-weight:400;font-size:17px;transition:none}.toolbar-button:active{transition:none;opacity:.2}.toolbar-button:disabled,.toolbar-button[disabled]{opacity:.3;cursor:default;pointer-events:none}.toolbar-button:focus{outline:0;transition:none}.toolbar-button:hover{transition:none}.toolbar-button--outline{border:1px solid rgba(38,100,171,.81);margin:auto 8px;padding-left:6px;padding-right:6px}.toolbar-button--material{font-size:22px;color:#fff;display:inline-block;padding:0 12px;height:100%;margin:0;border:none;border-radius:0;vertical-align:baseline;vertical-align:initial;transition:background-color .25s linear}.toolbar-button--material:first-of-type{margin-left:4px}.toolbar-button--material:last-of-type{margin-right:4px}.toolbar-button--material:active{opacity:1;transition:background-color .25s linear}.back-button{height:44px;padding-left:8px;color:rgba(38,100,171,.81)}.back-button:active{opacity:.2}.back-button__label{height:100%;vertical-align:top;font-size:17px;font-weight:500}.back-button__icon{margin-right:6px;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;fill:rgba(38,100,171,.81);-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:100%}.back-button--material{font-size:22px;color:#fff;display:inline-block;padding:0 12px;height:100%;margin:0 0 0 4px;border:none;border-radius:0;vertical-align:baseline;vertical-align:initial;line-height:56px}.back-button--material__label{display:none;font-size:20px}.back-button--material__icon{display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;fill:#fff;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:100%}.back-button--material:active{opacity:1}.checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;line-height:22px}.checkbox--noborder,.checkbox__checkmark{cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-moz-osx-font-smoothing:grayscale;display:inline-block;vertical-align:top;-webkit-font-smoothing:antialiased;font-weight:400}.checkbox__checkmark{box-sizing:border-box;background-clip:padding-box;user-select:none;position:relative;height:22px;width:22px;pointer-events:none}.checkbox__input,.checkbox__input:checked{position:absolute;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;width:100%;height:100%;margin:0;appearance:none}.checkbox__checkmark:after,.checkbox__checkmark:before{position:absolute;background:0 0;content:''}.checkbox__checkmark:before{box-sizing:border-box;width:22px;height:22px;border:1px solid #c7c7cd;border-radius:22px;left:0}.checkbox__checkmark:after{top:7px;left:5px;width:11px;height:5px;border:2px solid #fff;border-width:1px;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}:checked+.checkbox__checkmark:before{background:rgba(24,103,194,.81);border:none}:checked+.checkbox__checkmark:after{opacity:1}:disabled+.checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}:disabled:active+.checkbox__checkmark:before{background:0 0}.checkbox--noborder{user-select:none;line-height:22px;position:relative}.checkbox--noborder__checkmark,.radio-button{cursor:default;-webkit-user-select:none;-ms-user-select:none}.checkbox--noborder__input{position:absolute;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;width:100%;height:100%;margin:0;appearance:none}.radio-button__input,.textarea{-webkit-appearance:none;-moz-appearance:none}.checkbox--noborder__checkmark{position:relative;display:inline-block;vertical-align:top;-moz-user-select:none;user-select:none;box-sizing:border-box;width:22px;height:22px;background:0 0;border:none}.checkbox--noborder__checkmark:before{content:'';position:absolute;width:22px;height:22px;background:0 0;border:none;border-radius:22px;left:0}.checkbox--noborder__checkmark:after{content:'';position:absolute;top:7px;left:4px;opacity:0;width:11px;height:4px;background:0 0;border:2px solid rgba(24,103,194,.81);border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}:checked+.checkbox--noborder__checkmark:before{background:0 0;border:none}:checked+.checkbox--noborder__checkmark:after{opacity:1}:focus+.checkbox--noborder__checkmark:before{border:none}:disabled+.checkbox--noborder__checkmark{opacity:.3;cursor:default;pointer-events:none}:disabled:active+.checkbox--noborder__checkmark:before{background:0 0;border:none}.checkbox--material{line-height:18px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;overflow:visible}.checkbox--material__checkmark{width:18px;height:18px}.checkbox--material__checkmark:before{border-radius:2px;height:18px;width:18px;border:2px solid #717171;transition:background-color .1s linear .2s,border-color .1s linear .2s;background-color:transparent}:checked+.checkbox--material__checkmark:before{border:2px solid #009688;background-color:#009688;transition:background-color .1s linear,border-color .1s linear}.checkbox--material__checkmark:after{border-color:#fff;transition:-webkit-transform .2s ease 0;transition:transform .2s ease 0;transition:transform .2s ease 0,-webkit-transform .2s ease 0;width:10px;height:5px;top:4px;left:3px;-webkit-transform:scale(0) rotate(-45deg);transform:scale(0) rotate(-45deg);border-width:2px}:checked+.checkbox--material__checkmark:after{transition:-webkit-transform .2s ease .2s;transition:transform .2s ease .2s;transition:transform .2s ease .2s,-webkit-transform .2s ease .2s;width:10px;height:5px;top:4px;left:3px;-webkit-transform:scale(1) rotate(-45deg);transform:scale(1) rotate(-45deg);border-width:2px}.checkbox--material__input:before{content:'';opacity:0;position:absolute;top:0;left:0;width:18px;height:18px;box-shadow:0 0 0 11px #717171;box-sizing:border-box;border-radius:50%;background-color:#717171;pointer-events:none;display:block;-webkit-transform:scale3d(.2,.2,.2);transform:scale3d(.2,.2,.2);transition:opacity .25s ease-out,-webkit-transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out,-webkit-transform .1s ease-out}.radio-button,.radio-button__checkmark{display:inline-block;-moz-user-select:none;vertical-align:top}.checkbox--material__input:checked:before{box-shadow:0 0 0 11px #009688;background-color:#009688}.checkbox--material__input:active:before{opacity:.15;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}:disabled+.checkbox--material__checkmark{opacity:1}:disabled+.checkbox--material__checkmark:before{border-color:#afafaf}:disabled:checked+.checkbox--material__checkmark:before{background-color:#afafaf}:disabled:checked+.checkbox--material__checkmark:after{border-color:#fff}.radio-button__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;outline:0;width:100%;height:100%;margin:0;appearance:none}.radio-button__input:active,.radio-button__input:focus{outline:0;-webkit-tap-highlight-color:transparent}.radio-button{user-select:none;position:relative;line-height:24px;text-align:left}.list,.radio-button__checkmark{cursor:default;-webkit-user-select:none;-ms-user-select:none;-moz-osx-font-smoothing:grayscale}.radio-button__checkmark:before{content:'';position:absolute;box-sizing:border-box;width:22px;height:22px;background:0 0;border:none;border-radius:22px;left:0}.radio-button__checkmark{box-sizing:border-box;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;position:relative;width:24px;height:24px;background:0 0;pointer-events:none}.dialog,.list,.list-title{-moz-user-select:none}.radio-button__checkmark:after{content:'';position:absolute;top:7px;left:4px;opacity:0;width:11px;height:4px;background:0 0;border:2px solid rgba(24,103,194,.81);border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}:checked+.radio-button__checkmark{background:rgba(0,0,0,0)}:checked+.radio-button__checkmark:after{opacity:1}:checked+.radio-button__checkmark:before{background:0 0;border:none}:disabled+.radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}.radio-button--material{line-height:22px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.radio-button--material__input:before{content:'';position:absolute;top:0;left:0;opacity:0;width:20px;height:20px;box-shadow:0 0 0 14px #717171;border:none;box-sizing:border-box;border-radius:50%;background-color:#717171;pointer-events:none;display:block;-webkit-transform:scale3d(.2,.2,.2);transform:scale3d(.2,.2,.2);transition:opacity .25s ease-out,-webkit-transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out,-webkit-transform .1s ease-out}.radio-button--material__input:checked:before{box-shadow:0 0 0 14px #009688;background-color:#009688}.radio-button--material__input:active:before{opacity:.15;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.radio-button--material__checkmark{width:20px;height:20px;overflow:visible}.radio-button--material__checkmark:before{background:0 0;border:2px solid #717171;box-sizing:border-box;border-radius:50%;width:20px;height:20px;transition:border .2s ease}.radio-button--material__checkmark:after{transition:background .2s ease,-webkit-transform .2s ease;transition:background .2s ease,transform .2s ease;transition:background .2s ease,transform .2s ease,-webkit-transform .2s ease;top:5px;left:5px;width:10px;height:10px;border:none;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}:checked+.radio-button--material__checkmark:before{background:0 0;border:2px solid #009688}.radio-button--material__input+.radio-button__checkmark:after{background:#717171;opacity:1;-webkit-transform:scale(0);transform:scale(0)}:checked+.radio-button--material__checkmark:after{opacity:1;background:#009688;-webkit-transform:scale(1);transform:scale(1)}:disabled+.radio-button--material__checkmark{opacity:1}:disabled+.radio-button--material__checkmark:after{background-color:#afafaf;border-color:#afafaf}:disabled+.radio-button--material__checkmark:before{border-color:#afafaf}.list{padding:0;margin:0;font:inherit;color:inherit;background:bottom no-repeat,top no-repeat #fff;line-height:normal;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;list-style-type:none;text-align:left;display:block;-webkit-overflow-scrolling:touch;overflow:hidden;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-size:100% 1px,100% 1px;border:none}.list-header,.list-item{list-style:none;color:#1f1f21;position:relative}.list-item--expandable,.list-item__center,.list-item__right{background-position:bottom;border-bottom:none}.dialog,.list-title{-ms-user-select:none;cursor:default;-webkit-user-select:none;text-align:left}.list-item,.list-item__top{display:-webkit-box;display:-webkit-flex;-webkit-box-orient:horizontal;width:100%;-webkit-box-direction:normal}.list-header,.list-item--expandable,.list-item__center,.list-item__right{background-size:100% 1px;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%),linear-gradient(180deg,#ccc,#ccc 50%,transparent 50%)}}.list-item{box-sizing:border-box;display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:0 0 0 14px;margin:0 0 -1px;transition:background-color .2s linear}.list-item__top{display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-ordinal-group:1;-webkit-order:0;order:0}.list-item--expandable{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;background-image:linear-gradient(0deg,#ccc,#ccc 100%);background-position-x:14px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--expandable{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-item__expandable-content{display:none;width:100%;padding:12px 14px 12px 0;box-sizing:border-box;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;overflow:hidden}.list-item.expanded>.list-item__expandable-content{display:block;height:auto}.list-item__center,.list-item__left{display:-webkit-box;display:-webkit-flex;-webkit-align-self:stretch;line-height:1.2em;min-height:44px;box-sizing:border-box}.list-item__left{display:flex;padding:12px 14px 12px 0;-webkit-box-ordinal-group:1;-webkit-order:0;order:0;-webkit-box-align:center;-webkit-align-items:center;align-items:center;align-self:stretch}.list-item__left:empty{width:0;min-width:0;padding:0;margin:0}.list-item__center{display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;margin-right:auto;-webkit-box-align:center;-webkit-align-items:center;align-items:center;align-self:stretch;margin-left:0;background-image:linear-gradient(0deg,#ccc,#ccc 100%);padding:12px 6px 12px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item__center{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-item__right{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:flex;margin-left:auto;padding:12px 12px 12px 0;-webkit-box-ordinal-group:3;-webkit-order:2;order:2;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-align-self:stretch;align-self:stretch;background-image:linear-gradient(0deg,#ccc,#ccc 100%);line-height:1.2em;min-height:44px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item__right{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-header{margin:0;text-align:left;display:block;box-sizing:border-box;padding:0 0 0 15px;font-size:12px;font-weight:500;min-height:24px;line-height:25px;text-transform:uppercase;background-color:#eee;background-position:top;background-image:linear-gradient(0deg,#ccc,#ccc 100%)}.list-item--material.list-item--expandable,.list-item--material__center,.list-item--material__left:empty,.list-item--material__right{background-size:100% 1px;background-repeat:no-repeat;background-position:bottom}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-header{background-image:linear-gradient(180deg,#ccc,#ccc 50%,transparent 50%)}}.list--noborder{border-top:none;border-bottom:none;background-image:none}.list-item--tappable:active{transition:none;background-color:#d9d9d9}.list--inset{margin:0 8px;border:1px solid #ccc;border-radius:4px;background-image:none}.list-item__label{font-size:14px;padding:0 4px;opacity:.6}.list-item__title{-webkit-flex-basis:100%;flex-basis:100%;-webkit-align-self:flex-end;align-self:flex-end;-webkit-box-ordinal-group:1;-webkit-order:0;order:0}.list-item__subtitle{opacity:.75;font-size:14px;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;-webkit-flex-basis:100%;flex-basis:100%;-webkit-align-self:flex-start;align-self:flex-start}.list-item__thumbnail{width:40px;height:40px;border-radius:6px;display:block;margin:0}.list-item__icon{font-size:22px;padding:0 6px}.list--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;background-image:none;background-color:#fff}.list-item--material{border:0;padding:0 0 0 16px;line-height:normal}.list-item--material__subtitle{margin-top:4px}.list-item--material:first-child{box-shadow:none}.list-item--material__left{padding:14px 0;min-width:56px;line-height:1;min-height:48px}.list-item--material__center,.list-item--material__left:empty{padding:14px 6px 14px 0;border-color:#eee;border-bottom:none;background-image:linear-gradient(0deg,#eee,#eee 100%);min-height:48px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material__center,.list-item--material__left:empty{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-item--material__right{padding:14px 16px 14px 0;line-height:1;border-color:#eee;border-bottom:none;background-image:linear-gradient(0deg,#eee,#eee 100%);min-height:48px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material__right{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-item--material.list-item--expandable{border-bottom:1px solid #eee;border-bottom:none;background-image:linear-gradient(0deg,#eee,#eee 100%);background-position-x:16px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material.list-item--expandable{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-item--material.list-item--expandable.list-item--longdivider,.list-item--material.list-item--longdivider{border-bottom:1px solid #eee;border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#eee,#eee 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material.list-item--expandable.list-item--longdivider,.list-item--material.list-item--longdivider{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-header--material{background:#fff;border:none;font-size:14px;text-transform:none;margin:-1px 0 0;color:#757575;font-weight:500;padding:8px 16px}.list-header--material:not(:first-of-type){border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#eee,#eee 100%);padding-top:16px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-header--material:not(:first-of-type){background-image:linear-gradient(180deg,#eee,#eee 50%,transparent 50%)}}.list-item--material__thumbnail{width:40px;height:40px;border-radius:100%}.list-item--material__icon{font-size:20px;padding:0 4px}.list-item--chevron::before,.list-item__expand-chevron{border-right:2px solid #c7c7cc;border-bottom:2px solid #c7c7cc;width:7px;height:7px;background-color:transparent;z-index:5}.list-item--chevron::before{position:absolute;content:'';right:16px;top:50%;-webkit-transform:translateY(-50%) rotate(-45deg);transform:translateY(-50%) rotate(-45deg)}.list-item__expand-chevron{-webkit-transform:rotate(45deg);transform:rotate(45deg);margin:1px}.list-item--expandable.expanded .list-item__expand-chevron{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.list-item--chevron__right{padding-right:30px}.list-item--expandable .list-item__center,.list-item--expandable .list-item__right,.list-item--nodivider.list-item--expandable,.list-item--nodivider__center,.list-item--nodivider__right{border:none;background-image:none}.list-item--longdivider{border-bottom:1px solid #ccc;border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#ccc,#ccc 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--longdivider{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-item--longdivider:last-of-type,.list-item--longdivider__center,.list-item--longdivider__right{border:none;background-image:none}.list-title{font:inherit;background:0 0;border:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:block;color:#6d6d72;box-sizing:border-box;padding:0 0 0 16px;margin:0;font-size:13px;font-weight:500;line-height:24px;text-transform:uppercase;letter-spacing:.04em}.list-title--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#757575;font-size:14px;margin:0;padding:12px 0 12px 16px;font-weight:500;line-height:24px}.search-input{font:inherit;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTNweCIgaGVpZ2h0PSIxNHB4IiB2aWV3Qm94PSIwIDAgMTMgMTQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQyICgzNjc4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+aW9zLXNlYXJjaC1pbnB1dC1pY29uPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9ImNvbXBvbmVudHMiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJpb3Mtc2VhcmNoLWlucHV0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDguMDAwMDAwLCAtNDMuMDAwMDAwKSIgZmlsbD0iIzdBNzk3QiI+CiAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDAuMDAwMDAwLCAzNi4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNi45OTcyNDgyLDE1LjUwNDE0NjYgQzE3LjA3NzM2NTcsMTUuNTQwNTkzOCAxNy4xNTIyNzMxLDE1LjU5MTYxMjkgMTcuMjE3NzUxNiwxNS42NTcwOTE0IEwyMC42NDk5OTEsMTkuMDg5MzMwOCBDMjAuOTQ0ODQ0OSwxOS4zODQxODQ3IDIwLjk0ODQ3NjQsMTkuODU4NjA2IDIwLjY1MzU0MTIsMjAuMTUzNTQxMiBDMjAuMzYwNjQ4LDIwLjQ0NjQzNDQgMTkuODgxMjcxNiwyMC40NDE5MzE3IDE5LjU4OTMzMDgsMjAuMTQ5OTkxIEwxNi4xNTcwOTE0LDE2LjcxNzc1MTYgQzE2LjA5MTM3LDE2LjY1MjAzMDEgMTYuMDQwMTE3MSwxNi41NzczODc0IDE2LjAwMzQxNDEsMTYuNDk3Nzk5NSBDMTUuMTY3MTY5NCwxNy4xMjcwNDExIDE0LjEyNzEzOTMsMTcuNSAxMywxNy41IEMxMC4yMzg1NzYzLDE3LjUgOCwxNS4yNjE0MjM3IDgsMTIuNSBDOCw5LjczODU3NjI1IDEwLjIzODU3NjMsNy41IDEzLDcuNSBDMTUuNzYxNDIzNyw3LjUgMTgsOS43Mzg1NzYyNSAxOCwxMi41IEMxOCwxMy42Mjc0Njg1IDE3LjYyNjgyMzIsMTQuNjY3Nzc2OCAxNi45OTcyNDgyLDE1LjUwNDE0NjYgWiBNMTMsMTYuNSBDMTUuMjA5MTM5LDE2LjUgMTcsMTQuNzA5MTM5IDE3LDEyLjUgQzE3LDEwLjI5MDg2MSAxNS4yMDkxMzksOC41IDEzLDguNSBDMTAuNzkwODYxLDguNSA5LDEwLjI5MDg2MSA5LDEyLjUgQzksMTQuNzA5MTM5IDEwLjc5MDg2MSwxNi41IDEzLDE2LjUgWiIgaWQ9Imlvcy1zZWFyY2gtaW5wdXQtaWNvbiI+PC9wYXRoPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=) 8px center no-repeat;border:none;vertical-align:top;outline:0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;box-sizing:border-box;height:28px;font-size:14px;background-color:rgba(3,3,3,.09);box-shadow:none;color:#1f1f21;line-height:1.3;padding:0 8px 0 28px;margin:0;border-radius:5.5px;background-size:13px;font-weight:400;display:inline-block;text-indent:0}.search-input::-webkit-search-cancel-button{-webkit-appearance:textfield;appearance:textfield;display:none}.search-input::-webkit-search-decoration{display:none}.search-input:focus{outline:0}.search-input::-webkit-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input:-ms-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input::-ms-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input::placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;border-radius:2px;height:48px;background-color:#fafafa;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMThweCIgaGVpZ2h0PSIxOHB4IiB2aWV3Qm94PSIwIDAgMTggMTgiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQzLjIgKDM5MDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5TaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJhbmRyb2lkLXNlYXJjaC1pbnB1dC1pY29uIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGZpbGw9IiM4OTg5ODkiPgogICAgICAgICAgICA8ZyBpZD0iY29tcG9uZW50cyI+CiAgICAgICAgICAgICAgICA8ZyBpZD0ibWF0ZXJpYWwtc2VhcmNoIj4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0ic2VhcmNoIj4KICAgICAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ik1hdGVyaWFsL0ljb25zLWJsYWNrL3NlYXJjaCI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuNTAyLDYuNDkxIEwxMS43MDgsNi40OTEgTDExLjQzMiw2Ljc2NSBDMTIuNDA3LDcuOTAyIDEzLDkuMzc2IDEzLDEwLjk5MSBDMTMsMTQuNTgxIDEwLjA5LDE3LjQ5MSA2LjUsMTcuNDkxIEMyLjkxLDE3LjQ5MSAwLDE0LjU4MSAwLDEwLjk5MSBDMCw3LjQwMSAyLjkxLDQuNDkxIDYuNSw0LjQ5MSBDOC4xMTUsNC40OTEgOS41ODgsNS4wODMgMTAuNzI1LDYuMDU3IEwxMS4wMDEsNS43ODMgTDExLjAwMSw0Ljk5MSBMMTUuOTk5LDAgTDE3LjQ5LDEuNDkxIEwxMi41MDIsNi40OTEgTDEyLjUwMiw2LjQ5MSBaIE02LjUsNi40OTEgQzQuMDE0LDYuNDkxIDIsOC41MDUgMiwxMC45OTEgQzIsMTMuNDc2IDQuMDE0LDE1LjQ5MSA2LjUsMTUuNDkxIEM4Ljk4NSwxNS40OTEgMTEsMTMuNDc2IDExLDEwLjk5MSBDMTEsOC41MDUgOC45ODUsNi40OTEgNi41LDYuNDkxIEw2LjUsNi40OTEgWiIgaWQ9IlNoYXBlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4Ljc0NTAwMCwgOC43NDU1MDApIHNjYWxlKC0xLCAxKSByb3RhdGUoLTE4MC4wMDAwMDApIHRyYW5zbGF0ZSgtOC43NDUwMDAsIC04Ljc0NTUwMCkgIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);background-size:18px;background-position:18px center;font-size:14px;padding:0 24px 0 64px;box-shadow:0 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.24),0 1px 0 0 rgba(255,255,255,.06) inset}.text-input,.text-input--underbar{font:inherit;vertical-align:top;outline:0;-moz-osx-font-smoothing:grayscale;letter-spacing:0;box-shadow:none;width:auto;height:31px;border:none;margin:0;padding:0}.text-input{background:0 0;line-height:1;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;color:#1f1f21;font-size:15px;font-weight:400;box-sizing:border-box}.text-input::-ms-clear{display:none}.text-input:disabled{opacity:.3;cursor:default;pointer-events:none}.text-input::-webkit-input-placeholder{color:#999}.text-input:-ms-input-placeholder{color:#999}.text-input::-ms-input-placeholder{color:#999}.text-input::placeholder{color:#999}.text-input:disabled::-webkit-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled:-ms-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled::-ms-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled::placeholder{border:none;background-color:transparent;color:#999}.text-input:invalid{border:none;background-color:transparent;color:#1f1f21}.text-input--underbar{background:0 0;line-height:1;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;color:#1f1f21;font-size:15px;font-weight:400;box-sizing:border-box;border-bottom:1px solid #ccc;border-radius:0}.text-input--material,.textarea{box-sizing:border-box;font:inherit;-moz-osx-font-smoothing:grayscale;outline:0}.text-input--underbar:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent;border-bottom:1px solid #ccc}.text-input--underbar:disabled::-webkit-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled:-ms-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled::-ms-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled::placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:invalid{color:#1f1f21;border:none;background-color:transparent;border-bottom:1px solid #ccc}.text-input--material{padding:0 0 2px;margin:0;background:center bottom no-repeat;line-height:1;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#212121;background-image:linear-gradient(to top,transparent 1px,#afafaf 1px);background-size:100% 2px;font-size:16px;font-weight:400;border:none;border-radius:0;height:24px;vertical-align:middle}.textarea,.textarea--transparent{margin:0;vertical-align:top;resize:none;box-shadow:none;width:auto;letter-spacing:0}.text-input--material__label{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#afafaf;position:absolute;left:0;top:2px;font-size:16px;font-weight:400;pointer-events:none}.text-input--material__label--active{color:#009688;-webkit-transform:translate(0,-75%) scale(.75);transform:translate(0,-75%) scale(.75);-webkit-transform-origin:left top;transform-origin:left top;transition:color .1s ease-in,-webkit-transform .1s ease-in;transition:transform .1s ease-in,color .1s ease-in;transition:transform .1s ease-in,color .1s ease-in,-webkit-transform .1s ease-in}.text-input--material:focus{background-image:linear-gradient(#009688,#009688),linear-gradient(to top,transparent 1px,#afafaf 1px);-webkit-animation:material-text-input-animate .3s forwards;animation:material-text-input-animate .3s forwards}.text-input--material::-webkit-input-placeholder{color:#afafaf;line-height:20px}.text-input--material:-ms-input-placeholder{color:#afafaf;line-height:20px}.text-input--material::-ms-input-placeholder{color:#afafaf;line-height:20px}.text-input--material::placeholder{color:#afafaf;line-height:20px}@-webkit-keyframes material-text-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}@keyframes material-text-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}.textarea{background:#f9f9f9;line-height:normal;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;padding:5px;font-size:15px;font-weight:400;border-radius:4px;border:1px solid #ccc;color:#1f1f21;appearance:none}.dialog,.textarea--transparent{box-sizing:border-box;font:inherit;background:0 0;-moz-osx-font-smoothing:grayscale}.select-input,.textarea--transparent{-webkit-appearance:none;-moz-appearance:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea::-webkit-input-placeholder{color:#999}.textarea:-ms-input-placeholder{color:#999}.textarea::-ms-input-placeholder{color:#999}.textarea::placeholder{color:#999}.textarea--transparent{line-height:normal;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;padding:5px 0;font-size:15px;font-weight:400;border-radius:4px;border:none;color:#1f1f21;appearance:none}.textarea--transparent:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea--transparent::-webkit-input-placeholder{color:#999}.textarea--transparent:-ms-input-placeholder{color:#999}.textarea--transparent::-ms-input-placeholder{color:#999}.textarea--transparent::placeholder{color:#999}.dialog{padding:0;color:inherit;border:none;line-height:normal;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);margin:auto;overflow:hidden;min-width:270px;min-height:100px}.alert-dialog,.dialog-mask{padding:0;-moz-user-select:none;position:absolute}.dialog-container{height:inherit;min-height:inherit;overflow:hidden;border-radius:4px;background-color:#f4f4f4;-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);color:#1f1f21}.dialog-mask{margin:0;font:inherit;color:inherit;background:0 0;border:none;line-height:normal;cursor:default;-webkit-user-select:none;-ms-user-select:none;user-select:none;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,.2)}.dialog--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;text-align:left;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.alert-dialog,.alert-dialog-button{box-sizing:border-box;font:inherit;-ms-user-select:none;cursor:default;-moz-osx-font-smoothing:grayscale}.dialog-container--material{border-radius:2px;background-color:#fff;color:#1f1f21}.dialog-mask--material{background-color:rgba(0,0,0,.3)}.alert-dialog{background:#f4f4f4;border:none;line-height:normal;-webkit-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:270px;margin:auto;border-radius:8px;overflow:visible;max-width:95%;color:#1f1f21}.alert-dialog-container{height:inherit;padding-top:16px;overflow:hidden}.alert-dialog-title{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:17px;font-weight:500;padding:0 8px;text-align:center;color:#1f1f21}.alert-dialog-content{box-sizing:border-box;background-clip:padding-box;padding:4px 12px 8px;font-size:14px;min-height:36px;text-align:center;color:#1f1f21}.alert-dialog-footer{width:100%}.alert-dialog-button{color:inherit;background:0 0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-webkit-user-select:none;-moz-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none;letter-spacing:0;vertical-align:middle;border:none;border-top:1px solid #ddd;font-size:16px;padding:0 8px;margin:0;display:block;width:100%;text-align:center;height:44px;line-height:44px;outline:0;color:rgba(24,103,194,.81)}.alert-dialog-button:active{background-color:rgba(0,0,0,.05)}.alert-dialog-button--primal{font-weight:500}.alert-dialog-footer--rowfooter{white-space:nowrap;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.alert-dialog-button--rowfooter{-webkit-box-flex:1;-webkit-flex:1;flex:1;display:block;width:100%;border-left:1px solid #ddd}.alert-dialog-button--rowfooter:first-child{border-left:none}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#ddd,#ddd 50%,transparent 50%)}.alert-dialog-button--rowfooter{border-top:none;border-left:none;background-size:100% 1px,1px 100%;background-repeat:no-repeat;background-position:top,left;background-image:linear-gradient(0deg,transparent,transparent 50%,#ddd 50%),linear-gradient(90deg,transparent,transparent 50%,#ddd 50%)}.alert-dialog-button--rowfooter:first-child{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top,left;background-image:linear-gradient(0deg,transparent,transparent 50%,#ddd 50%)}}.alert-dialog-mask{padding:0;margin:0;font:inherit;color:inherit;background:0 0;border:none;line-height:normal;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:absolute;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,.2)}.fab,.popover__content{-webkit-user-select:none;box-sizing:border-box}.alert-dialog--material{border-radius:2px;background-color:#fff}.fab,.modal{background:0 0}.alert-dialog-container--material{padding:22px 0 0;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.alert-dialog-content--material,.alert-dialog-title--material{text-align:left;padding:0 24px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.alert-dialog-title--material{font-size:20px;font-weight:500;color:#212121}.alert-dialog-content--material{font-size:16px;font-weight:400;line-height:20px;margin:24px 0 10px;min-height:0;color:#727272}.alert-dialog-footer--material{display:block;padding:0;height:52px;box-sizing:border-box;margin:0;line-height:1}.alert-dialog-button--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;text-transform:uppercase;display:inline-block;width:auto;float:right;background:0 0;border:none;border-radius:2px;font-size:14px;font-weight:500;outline:0;height:36px;line-height:36px;padding:0 8px;margin:8px 8px 8px 0;box-sizing:border-box;min-width:50px;color:#009688}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button--material{background:0 0}}.alert-dialog-button--material:active{background-color:initial}.alert-dialog-button--rowfooter--material,.alert-dialog-button--rowfooter--material:first-child{border:0}.alert-dialog-button--primal--material{font-weight:500}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button--primal--material,.alert-dialog-button--rowfooter--material,.alert-dialog-button--rowfooter--material:first-child{background:0 0}}.alert-dialog-mask--material{background-color:rgba(0,0,0,.3)}.popover{position:absolute;z-index:20001}.popover--bottom{bottom:0}.popover--top{top:0}.popover--left{left:0}.popover--right{right:0}.popover-mask{left:0;right:0;top:0;bottom:0;background-color:rgba(0,0,0,.2);position:absolute;z-index:19999}.popover__content{padding:0;margin:0;font:inherit;background:#fff;border:none;line-height:normal;cursor:default;-moz-user-select:none;-ms-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:block;width:220px;overflow:auto;min-height:100px;max-height:100%;border-radius:8px;color:#1f1f21;pointer-events:auto}.popover-mask--material,.popover__arrow{background-color:transparent}.popover__arrow{position:absolute;width:18px;height:18px;-webkit-transform-origin:50% 50% 0;transform-origin:50% 50% 0;background-image:linear-gradient(45deg,#fff,#fff 50%,transparent 50%);border-radius:0 0 0 4px;margin:0;z-index:20001}.popover--bottom__arrow{-webkit-transform:translateY(6px) translateX(-9px) rotate(-45deg);transform:translateY(6px) translateX(-9px) rotate(-45deg);bottom:0;margin-right:-18px}.popover--top__arrow{-webkit-transform:translateY(-6px) translateX(-9px) rotate(135deg);transform:translateY(-6px) translateX(-9px) rotate(135deg);top:0;margin-right:-18px}.popover--left__arrow{-webkit-transform:translateX(-6px) translateY(-9px) rotate(45deg);transform:translateX(-6px) translateY(-9px) rotate(45deg);left:0;margin-bottom:-18px}.popover--right__arrow{-webkit-transform:translateX(6px) translateY(-9px) rotate(225deg);transform:translateX(6px) translateY(-9px) rotate(225deg);right:0;margin-bottom:-18px}.popover--material__content{background-color:#fafafa;border-radius:2px;color:#1f1f21;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.fab,.fab--material{margin:0;-moz-osx-font-smoothing:grayscale;letter-spacing:0;color:#fff;overflow:hidden;vertical-align:middle;text-align:center;cursor:default}.popover--material__arrow{display:none}.progress-bar{position:relative;height:2px;display:block;width:100%;background-color:#b6b6b6;background-clip:padding-box;margin:0;overflow:hidden;border-radius:4px}.progress-bar__primary,.progress-bar__secondary{position:absolute;background-color:rgba(24,103,194,.81);top:0;bottom:0;transition:width .3s linear;z-index:100;border-radius:4px}.progress-bar__secondary{background-color:rgba(24,103,194,.4);z-index:0}.progress-bar--indeterminate:after,.progress-bar--indeterminate:before{content:'';position:absolute;background-color:rgba(24,103,194,.81);top:0;left:0;bottom:0;will-change:left,right;border-radius:4px}.progress-bar--indeterminate:before{-webkit-animation:progress-bar__indeterminate 2.1s cubic-bezier(.65,.815,.735,.395) infinite;animation:progress-bar__indeterminate 2.1s cubic-bezier(.65,.815,.735,.395) infinite}.progress-bar--indeterminate:after{-webkit-animation:progress-bar__indeterminate-short 2.1s cubic-bezier(.165,.84,.44,1) infinite;animation:progress-bar__indeterminate-short 2.1s cubic-bezier(.165,.84,.44,1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes progress-bar__indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@keyframes progress-bar__indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@-webkit-keyframes progress-bar__indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@keyframes progress-bar__indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}.progress-bar--material{height:4px;background-color:#e0e0e0;border-radius:0}.progress-bar--material__primary,.progress-bar--material__secondary{background-color:#009688;border-radius:0}.progress-bar--material__secondary{background-color:#80cbc4;z-index:0}.fab--material__icon,.fab__icon{padding:0;z-index:100;position:relative}.progress-bar--material.progress-bar--indeterminate:after,.progress-bar--material.progress-bar--indeterminate:before{background-color:#009688;border-radius:0}.progress-circular{height:32px;position:relative;width:32px;-webkit-transform:rotate(270deg);transform:rotate(270deg);-webkit-animation:none;animation:none}.progress-circular__background,.progress-circular__primary,.progress-circular__secondary{cx:50%;cy:50%;r:40%;-webkit-animation:none;animation:none;fill:none;stroke-width:5%;stroke-miterlimit:10}.progress-circular__background{stroke:#ddd}.progress-circular__primary{stroke-dasharray:1,200;stroke-dashoffset:0;stroke:rgba(24,103,194,.81);transition:all 1s cubic-bezier(.4,0,.2,1)}.progress-circular__secondary{stroke:rgba(24,103,194,.81)}.progress-circular--indeterminate{-webkit-animation:progress__rotate 2s linear infinite;animation:progress__rotate 2s linear infinite;-webkit-transform:none;transform:none}.progress-circular--indeterminate__primary{-webkit-animation:progress__dash 1.5s ease-in-out infinite;animation:progress__dash 1.5s ease-in-out infinite}.progress-circular--indeterminate__secondary{display:none}@-webkit-keyframes progress__rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes progress__rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes progress__dash{0%{stroke-dasharray:10%,241.32%;stroke-dashoffset:0}50%{stroke-dasharray:201%,50.322%;stroke-dashoffset:-100%}100%{stroke-dasharray:10%,241.32%;stroke-dashoffset:-251.32%}}@keyframes progress__dash{0%{stroke-dasharray:10%,241.32%;stroke-dashoffset:0}50%{stroke-dasharray:201%,50.322%;stroke-dashoffset:-100%}100%{stroke-dasharray:10%,241.32%;stroke-dashoffset:-251.32%}}.progress-circular--material__background,.progress-circular--material__primary,.progress-circular--material__secondary{stroke-width:9%}.progress-circular--material__background{stroke:#dbdbdb}.progress-circular--material__primary{stroke:#009688}.progress-circular--material__secondary{stroke:#80cbc4}.fab{position:relative;display:inline-block;padding:0;font:inherit;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-moz-user-select:none;-ms-user-select:none;user-select:none;width:56px;height:56px;text-decoration:none;font-size:25px;line-height:56px;background-color:rgba(24,103,194,.81);border:0 solid currentColor;border-radius:50%;box-shadow:0 3px 6px rgba(0,0,0,.12);transition:all .1s linear}.fab:active{background-color:rgba(24,103,194,.61);transition:all .2s ease;box-shadow:0 0 6 rgba(0,0,0,.12)}.fab:focus{outline:0}.fab__icon{overflow:hidden;height:100%;width:100%;display:block;border-radius:100%;line-height:56px}.fab:disabled,.fab[disabled]{background-color:rgba(0,0,0,.5);box-shadow:none;opacity:.3;cursor:default;pointer-events:none}.fab--material{position:relative;display:inline-block;box-sizing:border-box;padding:0;font:inherit;background:#009688;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:0 solid currentColor;border-radius:50%;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;width:56px;height:56px;text-decoration:none;font-size:25px;line-height:56px;box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4);transition:all .2s ease-in-out}.fab--material:active{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.4);background-color:rgba(0,150,136,.85);transition:all .2s ease}.fab--material:focus{outline:0}.fab--material__icon{overflow:hidden;height:100%;width:100%;display:block;border-radius:100%;line-height:56px}.fab--mini,.fab--mini__icon{line-height:40px}.fab--material:disabled,.fab--material[disabled]{background-color:rgba(0,0,0,.5);box-shadow:none;opacity:.3;cursor:default;pointer-events:none}.fab--mini{width:40px;height:40px}.modal,.modal__content{overflow:hidden;word-spacing:0;padding:0;font:inherit;border:none}.speed-dial__item{position:absolute;-webkit-transform:scale(0);transform:scale(0)}.fab--top__right{top:20px;bottom:auto;right:20px;left:auto;position:absolute}.fab--bottom__right{top:auto;bottom:20px;right:20px;left:auto;position:absolute}.fab--top__left{top:20px;bottom:auto;right:auto;left:20px;position:absolute}.fab--bottom__left{top:auto;bottom:20px;right:auto;left:20px;position:absolute}.fab--bottom__center,.fab--top__center{margin-left:-28px;left:50%;right:auto;position:absolute}.fab--top__center{top:20px;bottom:auto}.fab--bottom__center{top:auto;bottom:20px}.modal,.modal__content,.select-input{margin:0;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}.modal{white-space:nowrap;color:inherit;line-height:normal;background-clip:padding-box;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;background-color:rgba(0,0,0,.7);position:absolute;left:0;right:0;top:0;bottom:0;width:100%;height:100%;display:table;z-index:2147483647}.modal__content{background:0 0;line-height:normal;background-clip:padding-box;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;display:table-cell;vertical-align:middle;text-align:center;color:#fff;white-space:normal}.select-input{font:inherit;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTBweCIgaGVpZ2h0PSI1cHgiIHZpZXdCb3g9IjAgMCAxMCA1IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0My4yICgzOTA2OSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+c2VsZWN0LWFsbG93PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9InNlbGVjdCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Imlvcy1zZWxlY3QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOTguMDAwMDAwLCAtMTE0LjAwMDAwMCkiIGZpbGw9IiM3NTc1NzUiPgogICAgICAgICAgICA8ZyBpZD0ibWVudS1iYXItKy1vcGVuLW1lbnUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMy4wMDAwMDAsIDEwMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJtZW51LWJhciI+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9InNlbGVjdC1hbGxvdyIgcG9pbnRzPSI3NSAxNCA4MCAxOSA4NSAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=) right center no-repeat;vertical-align:top;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;position:relative;font-size:17px;height:32px;line-height:32px;color:#1f1f21;appearance:none;display:inline-block;border-radius:0;border:none;padding:0 20px 0 0;border-bottom:none}.select-input--material,.select-input--material__label{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.select-input::-ms-clear{display:none}.select-input::-webkit-input-placeholder{color:#999}.select-input:-ms-input-placeholder{color:#999}.select-input::-ms-input-placeholder{color:#999}.select-input::placeholder{color:#999}.select-input:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent}.select-input:disabled::-webkit-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled:-ms-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled::-ms-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled::placeholder{border:none;background-color:transparent;color:#999}.select-input:invalid{border:none;background-color:transparent;color:#1f1f21}.select-input[multiple]{height:64px}.select-input--material{color:#1f1f21;font-size:15px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTBweCIgaGVpZ2h0PSI1cHgiIHZpZXdCb3g9IjAgMCAxMCA1IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0My4yICgzOTA2OSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+c2VsZWN0LWFsbG93PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9InNlbGVjdCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Imlvcy1zZWxlY3QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOTguMDAwMDAwLCAtMTE0LjAwMDAwMCkiIGZpbGw9IiM3NTc1NzUiPgogICAgICAgICAgICA8ZyBpZD0ibWVudS1iYXItKy1vcGVuLW1lbnUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMy4wMDAwMDAsIDEwMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJtZW51LWJhciI+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9InNlbGVjdC1hbGxvdyIgcG9pbnRzPSI3NSAxNCA4MCAxOSA4NSAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=),linear-gradient(to top,rgba(0,0,0,.12) 50%,rgba(0,0,0,.12) 50%);background-size:auto,100% 1px;background-repeat:no-repeat;background-position:right center,left bottom;border:none;transform:translate3d(0,0,0)}.select-input--material__label{color:rgba(0,0,0,.81);position:absolute;left:0;top:2px;font-size:16px;pointer-events:none}.select-input--material__label--active{color:rgba(0,0,0,.15);-webkit-transform:translate(0,-75%) scale(.75);transform:translate(0,-75%) scale(.75);-webkit-transform-origin:left top;transform-origin:left top;transition:color .1s ease-in,-webkit-transform .1s ease-in;transition:transform .1s ease-in,color .1s ease-in;transition:transform .1s ease-in,color .1s ease-in,-webkit-transform .1s ease-in}.select-input--material::-webkit-input-placeholder{color:rgba(0,0,0,.81);line-height:20px}.select-input--material:-ms-input-placeholder{color:rgba(0,0,0,.81);line-height:20px}.select-input--material::-ms-input-placeholder{color:rgba(0,0,0,.81);line-height:20px}.select-input--material::placeholder{color:rgba(0,0,0,.81);line-height:20px}@-webkit-keyframes material-select-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}@keyframes material-select-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}.action-sheet-button,.action-sheet-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;height:56px;line-height:56px}.select-input--underbar{border:none;border-bottom:1px solid #ccc}.select-input--underbar:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent;border-bottom:1px solid #ccc}.select-input--underbar:disabled::-webkit-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled:-ms-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled::-ms-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled::placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:invalid{color:#1f1f21;border:none;background-color:transparent;border-bottom:1px solid #ccc}.action-sheet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;cursor:default;position:absolute;left:10px;right:10px;bottom:10px;z-index:2}.action-sheet-button{box-sizing:border-box;font-size:20px;text-align:center;color:rgba(24,103,194,.81);background-color:rgba(255,255,255,.9);border-radius:0;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;display:block;width:100%;background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 100%)}.action-sheet-button:first-child,.action-sheet-title:first-child{border-top-left-radius:12px;border-top-right-radius:12px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.action-sheet-button{background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 50%,transparent 50%)}}.action-sheet-button:active{background-color:#e9e9e9;background-image:none}.action-sheet-button:focus{outline:0}.action-sheet-button:nth-last-of-type(2){border-bottom-right-radius:12px;border-bottom-left-radius:12px;background-image:none}.action-sheet-button:last-of-type{border-radius:12px;margin:8px 0 0;background-color:#fff;background-image:none;font-weight:600}.action-sheet-button:last-of-type:active{background-color:#e9e9e9}.action-sheet-button--destructive{color:#fe3824}.action-sheet-title{box-sizing:border-box;font-size:13px;color:#8f8e94;text-align:center;background-color:rgba(255,255,255,.9);background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.action-sheet-title{background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 50%,transparent 50%)}}.action-sheet-button--material,.action-sheet-title--material{font-family:Roboto,Noto,sans-serif;background-image:none;text-align:left;font-size:16px;padding:0 0 0 16px;color:#686868;-webkit-font-smoothing:antialiased}.action-sheet-icon{display:none}.action-sheet-mask{position:absolute;left:0;top:0;right:0;bottom:0;background-color:rgba(0,0,0,.1);z-index:1}.action-sheet-button--material,.action-sheet-button--material:last-of-type,.action-sheet-title--material{border-radius:0;background-color:#fff;font-weight:400}.action-sheet--material{left:0;right:0;bottom:0;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.action-sheet-title--material{height:56px;line-height:56px}.action-sheet-title--material:first-child{border-radius:0}.action-sheet-button--material{height:52px;line-height:52px}.action-sheet-button--material:first-child,.action-sheet-button--material:nth-last-of-type(2){border-radius:0}.action-sheet-button--material:last-of-type{margin:0}.action-sheet-icon--material{display:inline-block;float:left;height:52px;line-height:52px;margin-right:32px;font-size:26px;width:.8em;text-align:center}.card,.card__title{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;display:block;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}.action-sheet-mask--material{background-color:rgba(0,0,0,.2)}.card,.card--material{background-color:#fff}.card{-webkit-font-smoothing:antialiased;font-weight:400;box-shadow:0 1px 2px rgba(0,0,0,.12);border-radius:8px;margin:8px;padding:16px;text-align:left;word-wrap:break-word}.card__content{margin:0;font-size:14px;line-height:1.4;color:#030303}.card__title{-webkit-font-smoothing:antialiased;font-weight:400;font-size:20px;margin:4px 0 8px;padding:0}.card--material,.card--material__title{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.card--material{border-radius:2px;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.card--material__content{font-size:14px;line-height:1.4;color:rgba(0,0,0,.54)}.card--material__title{font-size:24px;margin:8px 0 12px}.toast{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;position:absolute;z-index:2;left:8px;right:8px;bottom:0;margin:8px 0;border-radius:8px;background-color:rgba(0,0,0,.8);display:-webkit-box;display:-webkit-flex;display:flex;min-height:48px;line-height:1.5;box-sizing:border-box;padding:16px}.toast--material__button,.toast--material__message{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.toast__message{font-size:14px;color:#fff;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;text-align:left;margin:0 16px 0 0;white-space:normal}.toast__button{font-size:14px;color:#fff;-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background-color:transparent;cursor:default;text-transform:uppercase}.toast__button:focus{outline:0}.toast__button:active{opacity:.4}.toast--material{left:0;right:0;bottom:0;margin:0;background-color:rgba(0,0,0,.8);border-radius:0;padding:0 24px}.bottom-bar,.tabbar:not(.tabbar--top){padding-bottom:0}.toast--material__message{margin:0 24px 0 0}.toast--material__button{color:#bbdefb}.toolbar{top:0;box-sizing:border-box;padding-top:0}.bottom-bar{bottom:0;box-sizing:border-box}.toolbar+.page__background{top:44px}.page__content{top:0;padding-top:0;bottom:0}.toolbar+.page__background+.page__content{top:44px;padding-top:0}.page-with-bottom-toolbar>.page__content{bottom:44px}.toolbar.toolbar--material+.page__background{top:56px}.toolbar.toolbar--material+.page__background+.page__content{top:56px;padding-top:0}.toolbar.toolbar--transparent+.page__background{top:0}.toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,.toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:44px}.toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,.toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:56px}.tabbar--top{padding-top:0}@media (orientation:portrait){html[onsflag-iphonex-portrait] .fab--top__center,html[onsflag-iphonex-portrait] .fab--top__left,html[onsflag-iphonex-portrait] .fab--top__right{top:64px}html[onsflag-iphonex-portrait] .fab--bottom__center,html[onsflag-iphonex-portrait] .fab--bottom__left,html[onsflag-iphonex-portrait] .fab--bottom__right{bottom:34px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .page__content{padding-left:44px;padding-right:44px}html[onsflag-iphonex-landscape] .dialog .page__content,html[onsflag-iphonex-landscape] .modal .page__content{padding-left:0;padding-right:0}html[onsflag-iphonex-landscape] .toolbar__left{padding-left:44px}html[onsflag-iphonex-landscape] .toolbar__right{padding-right:44px}html[onsflag-iphonex-landscape] .bottom-bar{padding-right:44px;padding-left:44px}html[onsflag-iphonex-landscape] .tabbar{padding-left:44px;padding-right:44px;width:calc(100% - 88px)}html[onsflag-iphonex-landscape] .fab--bottom__center,html[onsflag-iphonex-landscape] .fab--bottom__left,html[onsflag-iphonex-landscape] .fab--bottom__right{bottom:21px}html[onsflag-iphonex-landscape] .fab--bottom__left,html[onsflag-iphonex-landscape] .fab--top__left{left:44px}html[onsflag-iphonex-landscape] .fab--bottom__right,html[onsflag-iphonex-landscape] .fab--top__right{right:44px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .action-sheet{bottom:48px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .action-sheet{left:calc((100vw - 100vh + 20px)/ 2);right:calc((100vw - 100vh + 20px)/ 2);bottom:33px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .toast{bottom:34px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .toast{left:52px;right:52px;bottom:21px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .toolbar{top:0;box-sizing:content-box;padding-top:44px}html[onsflag-iphonex-portrait] .dialog .toolbar,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar{top:0;box-sizing:border-box;padding-top:0}html[onsflag-iphonex-portrait] .bottom-bar{bottom:0;box-sizing:content-box;padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .bottom-bar,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .bottom-bar,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .bottom-bar{bottom:0;box-sizing:border-box;padding-bottom:0}html[onsflag-iphonex-portrait] .page__content{top:0;padding-top:44px;bottom:0;padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .page__content{top:0;padding-top:0}html[onsflag-iphonex-portrait] .dialog .page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .page__content,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page__content{bottom:0;padding-bottom:0}html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content{top:88px;padding-top:0}html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content{top:44px;padding-top:0}html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content{bottom:78px;padding-bottom:0}html[onsflag-iphonex-portrait] .dialog .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar>.page__content{bottom:44px;padding-bottom:0}html[onsflag-iphonex-portrait] .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:88px}html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page__content{top:0;padding-top:44px}html[onsflag-iphonex-portrait] .tabbar--top{padding-top:44px}html[onsflag-iphonex-portrait] .dialog .tabbar--top,html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top{padding-top:0}html[onsflag-iphonex-portrait] .tabbar--top__content{top:93px}html[onsflag-iphonex-portrait] .dialog .tabbar--top__content,html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top__content{top:49px}html[onsflag-iphonex-portrait] .tabbar:not(.tabbar--top):not(.tabbar--top){padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .tabbar:not(.tabbar--top):not(.tabbar--top),html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .tabbar:not(.tabbar--top),html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top){padding-bottom:0}html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content){bottom:83px}html[onsflag-iphonex-portrait] .dialog .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content){bottom:49px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .bottom-bar{bottom:0;box-sizing:content-box;padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .bottom-bar,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .bottom-bar,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .bottom-bar{bottom:0;box-sizing:border-box;padding-bottom:0}html[onsflag-iphonex-landscape] .page__content{bottom:0;padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .page__content,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page__content{bottom:0;padding-bottom:0}html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content{bottom:65px;padding-bottom:0}html[onsflag-iphonex-landscape] .dialog .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar>.page__content{bottom:44px;padding-bottom:0}html[onsflag-iphonex-landscape] .tabbar:not(.tabbar--top){padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .tabbar:not(.tabbar--top),html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .tabbar:not(.tabbar--top),html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top){padding-bottom:0}html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content){bottom:70px}html[onsflag-iphonex-landscape] .dialog .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content){bottom:49px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset){margin-left:-44px;margin-right:-44px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-header{padding-left:59px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item{padding-left:58px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:60px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:50px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:56px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:74px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset){margin-left:0;margin-right:0}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-header{padding-left:15px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item{padding-left:14px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:16px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:6px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:12px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:30px}} \ No newline at end of file diff --git a/old_frontend/lib/css/onsen-css-components.min.css b/old_frontend/lib/css/onsen-css-components.min.css deleted file mode 100644 index 78634d1e..00000000 --- a/old_frontend/lib/css/onsen-css-components.min.css +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * Copyright 2013-2017 ASIAL CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - *//*! - * Copyright 2012 Adobe Systems Inc.; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */.notification,.toolbar,body{overflow:hidden}.notification,.toolbar{-webkit-user-select:none}a,body,button,input,select,textarea{touch-action:manipulation}.page,.page__background,.page__content{background-color:#efeff4;position:absolute}.page,.switch__input,body{position:absolute}.page,.page--material,.page--material__content{font-weight:400}.page,.switch__input,.switch__toggle,body{top:0;left:0;right:0;bottom:0}.switch,.switch__handle{background-clip:padding-box;box-sizing:border-box}:disabled+.switch--material__toggle,:disabled+.switch__toggle{opacity:.3;cursor:default;pointer-events:none}.switch--material__handle:before,.switch__handle,.tabbar--material__button:after{content:''}.switch,.switch__input{vertical-align:top;z-index:0}.range__focus-ring,.range__input,.switch,.switch__handle{box-sizing:border-box}html{height:100%;width:100%}body{padding:0;margin:0;-webkit-text-size-adjust:100%}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}input,select,textarea{-webkit-user-select:auto;-ms-user-select:auto;user-select:auto;-moz-user-select:text;-webkit-touch-callout:none}.notification,.toolbar{-moz-osx-font-smoothing:grayscale;-moz-user-select:none;-ms-user-select:none}input:active,input:focus,select:active,select:focus,textarea:active,textarea:focus{outline:0}h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4,h5,h6{font-size:18px}.page{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-moz-osx-font-smoothing:grayscale;overflow-x:visible;overflow-y:hidden;color:#1f1f21;-ms-overflow-style:none;-webkit-font-smoothing:antialiased}.page--material,.page--material__content,.page__content h1,.page__content h2,.page__content h3,.page__content h4,.page__content h5{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.page::-webkit-scrollbar{display:none}.page__background,.page__content{top:0;left:0;right:0;bottom:0;box-sizing:border-box}.page--material,.page--material__background{background-color:#eceff1}.page__content h1,.page__content h2,.page__content h3,.page__content h4,.page__content h5{font-weight:400;font-weight:500;margin:.6em 0;padding:0}.page__content h1{font-size:28px}.page__content h2{font-size:24px}.page__content h3{font-size:20px}.page--material__content h1,.page--material__content h2,.page--material__content h3,.page--material__content h4,.page--material__content h5{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;font-weight:500;margin:.6em 0;padding:0}.page--material__content h1{font-size:28px}.page--material__content h2{font-size:24px}.page--material__content h3{font-size:20px}.switch{display:inline-block;position:relative;min-width:51px;font-size:17px;padding:0 20px;border:none;overflow:visible;width:51px;height:32px;text-align:left}.switch__input{padding:0;border:0;background-color:transparent;outline:0;width:100%;height:100%;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.switch__handle,.switch__toggle{background-color:#fff;transition-property:all;transition-duration:.35s;position:absolute}.range__input,.switch--material__input{-webkit-appearance:none;vertical-align:top;outline:0}.switch__toggle{border-radius:30px;transition-timing-function:ease-out;box-shadow:inset 0 0 0 2px #e5e5e5}.switch__handle{border-radius:28px;height:28px;width:28px;left:1px;top:2px;transition-timing-function:cubic-bezier(.59,.01,.5,.99);box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25)}.switch--active__handle{transition:none}:checked+.switch__toggle{box-shadow:inset 0 0 0 2px #44db5e;background-color:#44db5e}:checked+.switch__toggle>.switch__handle{left:21px;box-shadow:0 3px 2px rgba(0,0,0,.25)}.switch__touch{position:absolute;top:-5px;bottom:-5px;left:-10px;right:-10px}.switch--material{width:36px;height:24px;padding:0 10px;min-width:36px}.switch--material__toggle{background-color:#b0afaf;margin-top:5px;height:14px;box-shadow:none}.switch--material__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;width:100%;height:100%;margin:0;-moz-appearance:none;appearance:none;z-index:0}.switch--material__handle{background-color:#f1f1f1;left:0;margin-top:-5px;width:20px;height:20px;box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4)}:checked+.switch--material__toggle{background-color:rgba(55,71,79,.5);box-shadow:none}:checked+.switch--material__toggle>.switch--material__handle{left:16px;background-color:#37474f;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.switch--material__handle:before{background:0 0;display:block;width:100%;height:100%;border-radius:50%;z-index:0;box-shadow:0 0 0 0 rgba(0,0,0,.12);transition:box-shadow .1s linear}.switch--material__toggle>.switch--active__handle:before{box-shadow:0 0 0 14px rgba(0,0,0,.12)}:checked+.switch--material__toggle>.switch--active__handle:before{box-shadow:0 0 0 14px rgba(55,71,79,.2)}.switch--material__touch{position:absolute;top:-10px;bottom:-10px;left:-15px;right:-15px}.range,.range__input{height:30px;position:relative;padding:0;margin:0}.range{display:inline-block;width:100px;background-image:linear-gradient(#a4aab3,#a4aab3);background-position:left center;background-size:100% 2px;background-repeat:no-repeat;background-color:transparent}.range__input{font:inherit;color:inherit;background:left center no-repeat;border:none;line-height:1;-moz-appearance:none;appearance:none;background-image:linear-gradient(#0076ff,#0076ff);background-size:0 2px;z-index:1;width:100%}.range__input::-moz-range-track{position:relative;border:none;background:0 0;box-shadow:none;top:0;margin:0;padding:0}.range__input::-ms-track{position:relative;border:none;background-color:#a4aab3;height:0;border-radius:50%}.range__input::-webkit-slider-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0;box-sizing:border-box;-webkit-appearance:none;appearance:none;top:0;z-index:1}.range__input::-moz-range-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0}.range__input::-ms-thumb{cursor:pointer;position:relative;height:28px;width:28px;background-color:#fff;border:none;box-shadow:0 0 1px 0 rgba(0,0,0,.25),0 3px 2px rgba(0,0,0,.25);border-radius:50%;margin:0;padding:0;top:0}.range__input::-ms-fill-lower{height:2px;background-color:#0076ff}.range__input::-ms-tooltip{display:none}.range__input:disabled{opacity:1;pointer-events:none}.range__focus-ring{pointer-events:none;top:0;left:0;display:none;padding:0;margin:0;font:inherit;color:inherit;border:none;vertical-align:top;outline:0;line-height:1;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0 0;height:30px;position:absolute;z-index:0;width:100%}.notification,.toolbar__item{box-sizing:border-box;font:inherit}.range--disabled{opacity:.3;cursor:default;pointer-events:none}.range--material{position:relative;background-image:linear-gradient(#bdbdbd,#bdbdbd)}.range--material__input{background-image:linear-gradient(#31313a,#31313a);background-position:center left;background-size:0 2px}.range--material__focus-ring{display:block}.button,.notification{position:relative;display:inline-block}.range--material__focus-ring::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:14px;height:14px;border:none;box-shadow:0 0 0 9px #31313a;background-color:#31313a;border-radius:50%;opacity:0;transition:opacity .25s ease-out,-webkit-transform .25s ease-out;transition:opacity .25s ease-out,transform .25s ease-out;transition:opacity .25s ease-out,transform .25s ease-out,-webkit-transform .25s ease-out}.range--material__input.range__input--active+.range--material__focus-ring::-webkit-slider-thumb{opacity:.2;-webkit-transform:scale(1.5,1.5,1.5);transform:scale(1.5,1.5,1.5)}.range--material__input::-webkit-slider-thumb{position:relative;box-sizing:border-box;border:none;background-color:transparent;width:14px;height:32px;border-radius:0;box-shadow:none;background-image:radial-gradient(circle farthest-corner,#31313a 0,#31313a 6.6px,transparent 7px);transition:-webkit-transform .1s linear;transition:transform .1s linear;transition:transform .1s linear,-webkit-transform .1s linear;overflow:visible}.range--material__input[_zero]::-webkit-slider-thumb{background-image:radial-gradient(circle farthest-corner,#f2f2f2 0,#f2f2f2 4px,#bdbdbd 4px,#bdbdbd 6.4px,transparent 7px)}.range--material__input[_zero]+.range--material__focus-ring::-webkit-slider-thumb{box-shadow:0 0 0 9px #bdbdbd}.bottom-bar,.toolbar{word-spacing:0;box-shadow:none;border-bottom:none;z-index:2}.range--material__input::-moz-range-track{background:0 0}.range--material__input::-moz-range-thumb,.range--material__input:focus::-moz-range-thumb{box-sizing:border-box;border:none;width:14px;height:32px;border-radius:0;background-color:transparent;background-image:-moz-radial-gradient(circle farthest-corner,#31313a 0,#31313a 6.6px,transparent 7px);box-shadow:none}.range--material__input.range__input--active::-webkit-slider-thumb,.range--material__input:active::-webkit-slider-thumb{-webkit-transform:scale(1.5);transform:scale(1.5);transition:-webkit-transform .1s linear;transition:transform .1s linear;transition:transform .1s linear,-webkit-transform .1s linear}.button,.button:active,.button:hover{transition:none}.range--disabled.range--material{opacity:1}.range--disabled>.range--material__input{background-image:none}.range--material__input:disabled::-webkit-slider-thumb{background-image:radial-gradient(circle farthest-corner,#b0b0b0 0,#b0b0b0 4px,#eee 4.4px,#eee 7.6px,transparent 7.6px);transition:none}.range--material__input:disabled::-moz-range-thumb{background-image:-moz-radial-gradient(circle farthest-corner,#b0b0b0 0,#b0b0b0 4px,#eee 4.4px,#eee 7.6px,transparent 7.6px);transition:none}.notification{vertical-align:top;background:#fe3824;border:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;cursor:default;user-select:none;text-overflow:ellipsis;white-space:nowrap;text-decoration:none;margin:0;padding:0 4px;width:auto;height:19px;border-radius:19px;color:#fff;text-align:center;font-size:16px;min-width:19px;line-height:19px;font-weight:400}.notification--material,.toolbar{-webkit-font-smoothing:antialiased}.toolbar,.toolbar__item{padding:0;margin:0;border:none;height:44px}.notification:empty{display:none}.bottom-bar--aligned,.toolbar{display:-webkit-box;display:-webkit-flex}.notification--material{font-family:Roboto,Noto,sans-serif;background-color:#e91e63;font-size:16px;font-weight:500;color:#fff}.toolbar{font:inherit;line-height:normal;cursor:default;user-select:none;display:flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;background:bottom no-repeat #fafafa;color:#1f1f21;font-weight:400;width:100%;white-space:nowrap;background-size:100% 1px;background-image:linear-gradient(0deg,#b2b2b2,#b2b2b2 100%)}.bottom-bar,.button{-moz-osx-font-smoothing:grayscale;cursor:default;-ms-user-select:none}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.toolbar{background-image:linear-gradient(0deg,#b2b2b2,#b2b2b2 50%,transparent 50%)}}.toolbar__bg{background:#fafafa}.toolbar__item{color:inherit;background:0 0;line-height:normal;overflow:visible;display:block;vertical-align:middle}.toolbar__left,.toolbar__right{padding:0;margin:0;font:inherit;color:inherit;max-width:50%;width:27%;background:0 0;border:none;box-sizing:border-box}.toolbar__left{text-align:left;line-height:44px}.toolbar__right{text-align:right;line-height:44px}.bottom-bar,.toolbar__center,.toolbar__title{color:#1f1f21;padding:0;margin:0}.toolbar__center{box-sizing:border-box;font:inherit;background:0 0;border:none;width:46%;text-align:center;line-height:44px;font-size:17px;font-weight:500}.toolbar__title{line-height:44px;font-size:17px;font-weight:500;overflow:visible}.toolbar__center:first-child:last-child{width:100%}.bottom-bar{-webkit-font-smoothing:antialiased;white-space:nowrap;overflow:hidden;font:inherit;border:none;line-height:normal;-webkit-user-select:none;-moz-user-select:none;user-select:none;display:block;height:44px;background:top no-repeat #fafafa;font-weight:400;position:absolute;right:0;left:0;border-top:none;background-size:100% 1px;background-image:linear-gradient(180deg,#b2b2b2,#b2b2b2 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.bottom-bar{background-image:linear-gradient(180deg,#b2b2b2,#b2b2b2 50%,transparent 50%)}}.bottom-bar__line-height{line-height:44px;padding-bottom:0;padding-top:0}.bottom-bar--aligned{display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;line-height:44px}.toolbar--material__center,.toolbar--material__left,.toolbar--material__right{font-family:Roboto,Noto,sans-serif;font-size:20px;font-weight:500;color:#31313a;height:56px;width:auto;line-height:56px;-webkit-font-smoothing:antialiased}.bottom-bar--transparent{background-color:transparent;background-image:none;border:none}.toolbar--material{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;height:56px;border-bottom:0;box-shadow:0 1px 5px rgba(0,0,0,.3);padding:0;background-color:#fff;background-size:0}.toolbar--noshadow,.toolbar--transparent{background-image:none;border-bottom:none}.toolbar--noshadow{box-shadow:none}.toolbar--material__left,.toolbar--material__right{min-width:72px}.toolbar--material__center{-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;overflow:hidden;text-overflow:ellipsis;text-align:left}.button,.button--quiet{font:inherit;-webkit-user-select:none;-moz-user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;letter-spacing:0;vertical-align:middle}.toolbar--material__center:first-child{margin-left:16px}.toolbar--material__center:last-child{margin-right:16px}.toolbar--material__left:empty,.toolbar--material__right:empty{min-width:16px}.toolbar--transparent{background-color:transparent;box-shadow:none}.button,.button--material{border:0 solid currentColor}.button{box-sizing:border-box;margin:0;background:#0076ff;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;user-select:none;padding:4px 10px;font-size:17px;line-height:32px;color:#fff;border-radius:3px}.button--cta,.button--quiet{position:relative;display:inline-block;box-sizing:border-box;margin:0;-moz-osx-font-smoothing:grayscale;cursor:default;-ms-user-select:none;padding:4px 10px}.button:active{background-color:#0076ff;opacity:.2}.button:focus{outline:0}.button:disabled,.button[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--outline{background-color:transparent;border:1px solid #0076ff;color:#0076ff}.button--outline:active{background-color:#b3d6ff;border:1px solid #0076ff;color:#0076ff;opacity:1}.button--outline:hover{border:1px solid #0076ff;transition:0}.button--light,.button--light:active{color:rgba(0,0,0,.4);border:1px solid rgba(0,0,0,.2)}.button--cta,.button--cta:active,.button--cta:hover,.button--quiet,.button--quiet:hover{transition:none}.button--light{background-color:transparent}.button--light:active{background-color:rgba(0,0,0,.05);opacity:1}.button--quiet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;user-select:none;font-size:17px;line-height:32px;border-radius:3px;box-shadow:none;background:0 0;color:#0076ff;border:none}.button--cta,.button--large--quiet{font:inherit;-webkit-user-select:none;-moz-user-select:none}.button--quiet:disabled,.button--quiet[disabled]{opacity:.3;cursor:default;pointer-events:none;border:none}.button--quiet:focus{outline:0}.button--quiet:active{background-color:transparent;border:none;transition:none;opacity:.2;color:#0076ff}.button--cta{background:#25a6d9;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;font-size:17px;line-height:32px;letter-spacing:0;vertical-align:middle;border-radius:3px;border:none;color:#fff}.button--large--cta,.button--large--quiet{position:relative;box-sizing:border-box;margin:0;-moz-osx-font-smoothing:grayscale;cursor:default;-ms-user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;height:auto;text-decoration:none;letter-spacing:0;vertical-align:middle}.button--large,.button--large--cta,.button--large--quiet{padding:4px 12px;width:100%;text-align:center;display:block}.button--cta:focus{outline:0}.button--cta:active{color:#fff;background-color:#25a6d9;opacity:.2}.button--cta:disabled,.button--cta[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large{font-size:17px;font-weight:500;line-height:36px}.button--large:active{background-color:#0076ff;opacity:.2;transition:none}.button--large--quiet,.button--large--quiet:active{color:#0076ff;background:0 0;box-shadow:none;transition:none}.button--large:disabled,.button--large[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large:hover{transition:none}.button--large:focus{outline:0}.button--large--quiet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;user-select:none;border-radius:3px;font-size:17px;font-weight:500;line-height:36px;border:1px solid transparent}.button--large--cta,.button--material{font:inherit;-webkit-user-select:none;-moz-user-select:none}.button--large--quiet:active{opacity:.2;border:1px solid transparent}.button--large--quiet:disabled,.button--large--quiet[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--large--quiet:hover{transition:none}.button--large--quiet:focus{outline:0}.button--large--cta{background:#25a6d9;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;user-select:none;border-radius:3px;transition:none;border:none;color:#fff;font-size:17px;font-weight:500;line-height:36px}.button--material,.button--material--flat{display:inline-block;box-sizing:border-box;cursor:default;-ms-user-select:none;height:auto;vertical-align:middle;padding:0 16px;-moz-osx-font-smoothing:grayscale;margin:0;position:relative;overflow:hidden;letter-spacing:0;text-transform:uppercase;min-height:36px;text-overflow:ellipsis;text-decoration:none;white-space:nowrap;text-align:center}.button--large--cta:hover{transition:none}.button--large--cta:focus{outline:0}.button--large--cta:active{color:#fff;background-color:#25a6d9;transition:none;opacity:.2}.button--material,.button--material:active,.button--material:hover{transition:all .25s linear}.button--large--cta:disabled,.button--large--cta[disabled]{opacity:.3;cursor:default;pointer-events:none}.button--material{background:#2979ff;user-select:none;border-radius:3px;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2);font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;line-height:36px;font-size:14px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);color:#fff;font-weight:500;opacity:1}.button--material:active{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.4);background-color:#2979ff;opacity:.9}.button--material:focus{outline:0}.button--material:disabled,.button--material[disabled]{transition:none;box-shadow:none;background-color:rgba(79,79,79,.26);color:rgba(0,0,0,.26);opacity:1}.button--material--flat,.button--material--flat:hover{transition:all .25s linear}.button--material--flat{font:inherit;background:0 0;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:0 solid currentColor;border-radius:3px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;line-height:36px;font-size:14px;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);font-weight:500;box-shadow:none;color:#2979ff}.checkbox,.tabbar__button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.button--material--flat:focus{box-shadow:none;background-color:transparent;color:#2979ff;outline:0;opacity:1;border:none}.button--material--flat:active{box-shadow:none;outline:0;opacity:1;border:none;background-color:rgba(153,153,153,.2);color:#2979ff;transition:all .25s linear}.button--material--flat:disabled,.button--material--flat[disabled]{transition:none;opacity:1;box-shadow:none;background-color:transparent;color:rgba(0,0,0,.26)}.button-bar__button:disabled,.segment__item:disabled,.tabbar__button:disabled{opacity:.3;cursor:default;pointer-events:none}.button-bar{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;margin:0;padding:0;border:none}.button-bar__button,.button-bar__item{border-radius:0;width:100%;padding:0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;box-sizing:border-box}.button-bar__item{margin:0;position:relative;overflow:hidden}.button-bar__button{background-color:transparent;color:#0076ff;border:1px solid #0076ff;font-size:13px;height:27px;line-height:27px;transition:background-color .2s linear,color .2s linear;border-width:1px 1px 1px 0}.button-bar__button:hover{transition:none}.button-bar__button:focus{outline:0}:checked+.button-bar__button{background-color:#0076ff;color:#fff;transition:none}.button-bar__button:active,:active+.button-bar__button{background-color:#b3d6ff;border:0 solid #0076ff;border-top:1px solid #0076ff;border-bottom:1px solid #0076ff;border-right:1px solid #0076ff;font-size:13px;width:100%;transition:none}.segment__button,.segment__input,.segment__item{background-color:transparent}.button-bar__item:first-child>.button-bar__button{border-left-width:1px;border-radius:4px 0 0 4px}.button-bar__item:last-child>.button-bar__button{border-right-width:1px;border-radius:0 4px 4px 0}.segment{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;-webkit-box-align:stretch;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;-webkit-flex-wrap:nowrap;flex-wrap:nowrap;margin:0;padding:0;border:none}.segment__item{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;border-radius:0;width:100%;padding:0;margin:0;position:relative;overflow:hidden;box-sizing:border-box;display:block;border:none}.segment__input,.tabbar{position:absolute;margin:0;padding:0;width:100%;bottom:0;left:0}.segment__input{right:0;top:0;border:0;z-index:1;vertical-align:top;outline:0;height:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none}.checkbox--noborder__input,.checkbox__input,.checkbox__input:checked,.tabbar__item>input{-webkit-appearance:none;-moz-appearance:none;outline:0;right:0}.segment__button{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;border-radius:0;color:#0076ff;border:1px solid #0076ff;font-weight:400;padding:0;font-size:13px;height:29px;line-height:29px;width:100%;transition:background-color .2s linear,color .2s linear;box-sizing:border-box;text-align:center;border-width:1px 1px 1px 0}.segment__button:hover,:active+.segment--material__button,:active+.segment__button{transition:none}.segment__button:focus{outline:0}:active+.segment__button{background-color:#b3d6ff;border:0 solid #0076ff;border-top:1px solid #0076ff;border-bottom:1px solid #0076ff;border-right:1px solid #0076ff;font-size:13px;width:100%}:checked+.segment__button{background-color:#0076ff;color:#fff;transition:none}.segment--material__button,:active+.segment--material__button{background-color:#fafafa;font-size:14px;color:rgba(0,0,0,.38)}.segment__item:first-child>.segment__button{border-left-width:1px;border-radius:4px 0 0 4px}.segment__item:last-child>.segment__button{border-right-width:1px;border-radius:0 4px 4px 0}.segment--material__button,.segment--material__item:first-child>.segment--material__button,.segment--material__item:last-child>.segment--material__button,:active+.segment--material__button{border-width:0;border-radius:0}.segment--material{border-radius:2px;overflow:hidden;box-shadow:0 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.24)}.segment--material__button{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;height:32px;line-height:32px}.tabbar,.tabbar__item{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:checked+.segment--material__button{background-color:#c8c8c8;color:#353535;border-radius:0;border-width:0}.tabbar{display:-webkit-box;display:-webkit-flex;display:flex;right:0;white-space:nowrap;height:49px;background-color:#fafafa;border-top:1px solid #ccc}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.tabbar{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#ccc,#ccc 50%,transparent 50%)}}.tabbar__item{position:relative;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-basis:0;flex-basis:0;width:auto;border-radius:0}.tabbar__button,.tabbar__item>input{vertical-align:top;width:100%;margin:0;padding:0}.tabbar__item>input{position:absolute;top:0;left:0;bottom:0;border:0;background-color:transparent;z-index:1;height:100%;appearance:none}.tabbar__button{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;font:inherit;background:0 0;border:none;cursor:default;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;position:relative;display:inline-block;text-decoration:none;height:49px;letter-spacing:0;color:#999;border-top:none;font-weight:400;line-height:49px}.tabbar__icon{font-size:24px;padding:0;margin:0;line-height:26px;display:block!important;height:28px}.tabbar__label{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:inline-block}.tabbar--material__button,.tabbar--material__label,.tabbar--material__label:first-child{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.tabbar__badge.notification{vertical-align:text-bottom;top:-1px;margin-left:5px;z-index:10;font-size:12px;height:16px;min-width:16px;line-height:16px;border-radius:8px}.tabbar__icon~.tabbar__badge.notification{position:absolute;top:5px;margin-left:0}.tabbar__icon+.tabbar__label{display:block;font-size:10px;line-height:1;margin:0;font-weight:400}.tabbar__label:first-child{font-size:16px;line-height:49px;margin:0;padding:0}:checked+.tabbar__button{color:#0076ff;background-color:transparent;box-shadow:none;border-top:none}.tabbar__button:focus{z-index:1;border-top:none;box-shadow:none;outline:0}.tabbar__content{position:absolute;top:0;left:0;right:0;bottom:49px;z-index:0}.tabbar--autogrow .tabbar__item{-webkit-flex-basis:auto;flex-basis:auto}.tabbar--top{position:relative;top:0;left:0;right:0;bottom:auto;border-top:none;border-bottom:1px solid #ccc}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.tabbar__button{border-top:none}.tabbar--top{border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.tabbar--top__content{top:49px;left:0;right:0;bottom:0;z-index:0}.tabbar--top-border__button{background-color:transparent;border-bottom:4px solid transparent}:checked+.tabbar--top-border__button{background-color:transparent;border-bottom:4px solid #0076ff}.tabbar__border{position:absolute;bottom:0;left:0;width:0;height:4px;background-color:#0076ff}.tabbar--material{background:#fff;border-bottom-width:0;box-shadow:0 4px 2px -2px rgba(0,0,0,.14),0 3px 5px -2px rgba(0,0,0,.12),0 5px 1px -4px rgba(0,0,0,.2)}.tabbar--material__button{background-color:transparent;color:#31313a;text-transform:uppercase;font-size:14px;font-weight:400}.tabbar--material__button:after{display:block;width:0;height:2px;bottom:0;position:absolute;margin-top:-2px;background-color:#31313a}:checked+.tabbar--material__button:after{width:100%;transition:width .2s ease-in-out}:checked+.tabbar--material__button{background-color:transparent;color:#31313a}.tabbar--material__item:not([ripple]):active{background-color:rgba(49,49,58,.1)}.tabbar--material__border{height:2px;background-color:#31313a}.back-button,.toolbar-button,.toolbar-button:active{background-color:rgba(0,0,0,0)}.tabbar--material__icon{font-size:22px!important;line-height:36px}.back-button,.back-button__label{display:inline-block;line-height:44px}.tabbar--material__label{font-weight:400}.tabbar--material__label:first-child{letter-spacing:.015em;font-weight:500;font-size:14px}.tabbar--material__icon+.tabbar--material__label{font-size:10px}.toolbar-button{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;padding:4px 10px;letter-spacing:0;color:#0076ff;border-radius:2px;border:1px solid transparent;font-weight:400;font-size:17px;transition:none}.toolbar-button:active{transition:none;opacity:.2}.toolbar-button:disabled,.toolbar-button[disabled]{opacity:.3;cursor:default;pointer-events:none}.toolbar-button:focus{outline:0;transition:none}.toolbar-button:hover{transition:none}.toolbar-button--outline{border:1px solid #0076ff;margin:auto 8px;padding-left:6px;padding-right:6px}.toolbar-button--material{font-size:22px;color:#1e88e5;display:inline-block;padding:0 12px;height:100%;margin:0;border:none;border-radius:0;vertical-align:baseline;vertical-align:initial;transition:background-color .25s linear}.toolbar-button--material:first-of-type{margin-left:4px}.toolbar-button--material:last-of-type{margin-right:4px}.toolbar-button--material:active{opacity:1;transition:background-color .25s linear}.back-button{height:44px;padding-left:8px;color:#0076ff}.back-button:active{opacity:.2}.back-button__label{height:100%;vertical-align:top;font-size:17px;font-weight:500}.back-button__icon{margin-right:6px;display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;fill:#0076ff;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:100%}.back-button--material{font-size:22px;color:#1e88e5;display:inline-block;padding:0 12px;height:100%;margin:0 0 0 4px;border:none;border-radius:0;vertical-align:baseline;vertical-align:initial;line-height:56px}.back-button--material__label{display:none;font-size:20px}.back-button--material__icon{display:-webkit-inline-box;display:-webkit-inline-flex;display:inline-flex;fill:#1e88e5;-webkit-box-align:center;-webkit-align-items:center;align-items:center;height:100%}.back-button--material:active{opacity:1}.checkbox{position:relative;display:inline-block;vertical-align:top;cursor:default;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;line-height:22px}.checkbox--noborder,.checkbox__checkmark{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-moz-osx-font-smoothing:grayscale;display:inline-block;vertical-align:top;cursor:default;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.checkbox__checkmark{box-sizing:border-box;background-clip:padding-box;user-select:none;position:relative;height:22px;width:22px;pointer-events:none}.checkbox__input,.checkbox__input:checked{position:absolute;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;width:100%;height:100%;margin:0;appearance:none}.checkbox__checkmark:after,.checkbox__checkmark:before{position:absolute;background:0 0;content:''}.checkbox__checkmark:before{box-sizing:border-box;width:22px;height:22px;border:1px solid #c7c7cd;border-radius:22px;left:0}.checkbox__checkmark:after{top:7px;left:5px;width:11px;height:5px;border:2px solid #fff;border-width:1px;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}:checked+.checkbox__checkmark:before{background:#0076ff;border:none}:checked+.checkbox__checkmark:after{opacity:1}:disabled+.checkbox__checkmark{opacity:.3;cursor:default;pointer-events:none}:disabled:active+.checkbox__checkmark:before{background:0 0}.checkbox--noborder{user-select:none;line-height:22px;position:relative}.checkbox--noborder__input{position:absolute;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;width:100%;height:100%;margin:0;appearance:none}.radio-button__input,.textarea{-webkit-appearance:none;-moz-appearance:none}.checkbox--noborder__checkmark{position:relative;display:inline-block;vertical-align:top;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;width:22px;height:22px;background:0 0;border:none}.checkbox--noborder__checkmark:before{content:'';position:absolute;width:22px;height:22px;background:0 0;border:none;border-radius:22px;left:0}.checkbox--noborder__checkmark:after{content:'';position:absolute;top:7px;left:4px;opacity:0;width:11px;height:4px;background:0 0;border:2px solid #0076ff;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}:checked+.checkbox--noborder__checkmark:before{background:0 0;border:none}:checked+.checkbox--noborder__checkmark:after{opacity:1}:focus+.checkbox--noborder__checkmark:before{border:none}:disabled+.checkbox--noborder__checkmark{opacity:.3;cursor:default;pointer-events:none}:disabled:active+.checkbox--noborder__checkmark:before{background:0 0;border:none}.checkbox--material{line-height:18px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;overflow:visible}.checkbox--material__checkmark{width:18px;height:18px}.checkbox--material__checkmark:before{border-radius:2px;height:18px;width:18px;border:2px solid #717171;transition:background-color .1s linear .2s,border-color .1s linear .2s;background-color:transparent}:checked+.checkbox--material__checkmark:before{border:2px solid #37474f;background-color:#37474f;transition:background-color .1s linear,border-color .1s linear}.checkbox--material__checkmark:after{border-color:#fff;transition:-webkit-transform .2s ease 0;transition:transform .2s ease 0;transition:transform .2s ease 0,-webkit-transform .2s ease 0;width:10px;height:5px;top:4px;left:3px;-webkit-transform:scale(0) rotate(-45deg);transform:scale(0) rotate(-45deg);border-width:2px}:checked+.checkbox--material__checkmark:after{transition:-webkit-transform .2s ease .2s;transition:transform .2s ease .2s;transition:transform .2s ease .2s,-webkit-transform .2s ease .2s;width:10px;height:5px;top:4px;left:3px;-webkit-transform:scale(1) rotate(-45deg);transform:scale(1) rotate(-45deg);border-width:2px}.checkbox--material__input:before{content:'';opacity:0;position:absolute;top:0;left:0;width:18px;height:18px;box-shadow:0 0 0 11px #717171;box-sizing:border-box;border-radius:50%;background-color:#717171;pointer-events:none;display:block;-webkit-transform:scale3d(.2,.2,.2);transform:scale3d(.2,.2,.2);transition:opacity .25s ease-out,-webkit-transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out,-webkit-transform .1s ease-out}.radio-button,.radio-button__checkmark{display:inline-block;cursor:default;-webkit-user-select:none;-ms-user-select:none;vertical-align:top}.checkbox--material__input:checked:before{box-shadow:0 0 0 11px #37474f;background-color:#37474f}.checkbox--material__input:active:before{opacity:.15;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}:disabled+.checkbox--material__checkmark{opacity:1}:disabled+.checkbox--material__checkmark:before{border-color:#afafaf}:disabled:checked+.checkbox--material__checkmark:before{background-color:#afafaf}:disabled:checked+.checkbox--material__checkmark:after{border-color:#fff}.radio-button__input{position:absolute;right:0;top:0;left:0;bottom:0;padding:0;border:0;background-color:transparent;z-index:1;vertical-align:top;outline:0;width:100%;height:100%;margin:0;appearance:none}.radio-button__input:active,.radio-button__input:focus{outline:0;-webkit-tap-highlight-color:transparent}.radio-button{-moz-user-select:none;user-select:none;position:relative;line-height:24px;text-align:left}.radio-button__checkmark:before{content:'';position:absolute;box-sizing:border-box;width:22px;height:22px;background:0 0;border:none;border-radius:22px;left:0}.radio-button__checkmark{box-sizing:border-box;-moz-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;position:relative;width:24px;height:24px;background:0 0;pointer-events:none}.list,.list-title{-webkit-user-select:none;-moz-osx-font-smoothing:grayscale;cursor:default}.dialog,.list,.list-title{-ms-user-select:none}.radio-button__checkmark:after{content:'';position:absolute;top:7px;left:4px;opacity:0;width:11px;height:4px;background:0 0;border:2px solid #0076ff;border-top:none;border-right:none;border-radius:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}:checked+.radio-button__checkmark{background:rgba(0,0,0,0)}:checked+.radio-button__checkmark:after{opacity:1}:checked+.radio-button__checkmark:before{background:0 0;border:none}:disabled+.radio-button__checkmark{opacity:.3;cursor:default;pointer-events:none}.radio-button--material{line-height:22px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.radio-button--material__input:before{content:'';position:absolute;top:0;left:0;opacity:0;width:20px;height:20px;box-shadow:0 0 0 14px #717171;border:none;box-sizing:border-box;border-radius:50%;background-color:#717171;pointer-events:none;display:block;-webkit-transform:scale3d(.2,.2,.2);transform:scale3d(.2,.2,.2);transition:opacity .25s ease-out,-webkit-transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out;transition:opacity .25s ease-out,transform .1s ease-out,-webkit-transform .1s ease-out}.radio-button--material__input:checked:before{box-shadow:0 0 0 14px #37474f;background-color:#37474f}.list-item--material:first-child,.search-input{box-shadow:none}.radio-button--material__input:active:before{opacity:.15;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}.radio-button--material__checkmark{width:20px;height:20px;overflow:visible}.radio-button--material__checkmark:before{background:0 0;border:2px solid #717171;box-sizing:border-box;border-radius:50%;width:20px;height:20px;transition:border .2s ease}.radio-button--material__checkmark:after{transition:background .2s ease,-webkit-transform .2s ease;transition:background .2s ease,transform .2s ease;transition:background .2s ease,transform .2s ease,-webkit-transform .2s ease;top:5px;left:5px;width:10px;height:10px;border:none;border-radius:50%;-webkit-transform:scale(0);transform:scale(0)}:checked+.radio-button--material__checkmark:before{background:0 0;border:2px solid #37474f}.radio-button--material__input+.radio-button__checkmark:after{background:#717171;opacity:1;-webkit-transform:scale(0);transform:scale(0)}:checked+.radio-button--material__checkmark:after{opacity:1;background:#37474f;-webkit-transform:scale(1);transform:scale(1)}:disabled+.radio-button--material__checkmark{opacity:1}:disabled+.radio-button--material__checkmark:after{background-color:#afafaf;border-color:#afafaf}:disabled+.radio-button--material__checkmark:before{border-color:#afafaf}.list{padding:0;margin:0;font:inherit;color:inherit;background:bottom no-repeat,top no-repeat #fff;line-height:normal;-moz-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;list-style-type:none;text-align:left;display:block;-webkit-overflow-scrolling:touch;overflow:hidden;background-image:linear-gradient(#ccc,#ccc),linear-gradient(#ccc,#ccc);background-size:100% 1px,100% 1px;border:none}.list-header,.list-item{list-style:none;color:#1f1f21;position:relative}.list-item--expandable,.list-item__center,.list-item__right{background-position:bottom;border-bottom:none}.dialog,.list-title{-moz-user-select:none;text-align:left}.list-item,.list-item__top{display:-webkit-box;display:-webkit-flex;-webkit-box-orient:horizontal;width:100%;-webkit-box-direction:normal}.list-header,.list-item--expandable,.list-item__center,.list-item__right{background-size:100% 1px;background-repeat:no-repeat}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%),linear-gradient(180deg,#ccc,#ccc 50%,transparent 50%)}}.list-item{box-sizing:border-box;display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center;padding:0 0 0 14px;margin:0 0 -1px;transition:background-color .2s linear}.list-item__top{display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-box-ordinal-group:1;-webkit-order:0;order:0}.list-item--expandable{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column;background-image:linear-gradient(0deg,#ccc,#ccc 100%);background-position-x:14px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--expandable{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-item__expandable-content{display:none;width:100%;padding:12px 14px 12px 0;box-sizing:border-box;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;overflow:hidden}.list-item.expanded>.list-item__expandable-content{display:block;height:auto}.list-item__center,.list-item__left{display:-webkit-box;display:-webkit-flex;-webkit-align-self:stretch;line-height:1.2em;min-height:44px;box-sizing:border-box}.list-item__left{display:flex;padding:12px 14px 12px 0;-webkit-box-ordinal-group:1;-webkit-order:0;order:0;-webkit-box-align:center;-webkit-align-items:center;align-items:center;align-self:stretch}.list-item__left:empty{width:0;min-width:0;padding:0;margin:0}.list-item__center{display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;margin-right:auto;-webkit-box-align:center;-webkit-align-items:center;align-items:center;align-self:stretch;margin-left:0;background-image:linear-gradient(0deg,#ccc,#ccc 100%);padding:12px 6px 12px 0}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item__center{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-item__right{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:flex;margin-left:auto;padding:12px 12px 12px 0;-webkit-box-ordinal-group:3;-webkit-order:2;order:2;-webkit-box-align:center;-webkit-align-items:center;align-items:center;-webkit-align-self:stretch;align-self:stretch;background-image:linear-gradient(0deg,#ccc,#ccc 100%);line-height:1.2em;min-height:44px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item__right{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-header{margin:0;text-align:left;display:block;box-sizing:border-box;padding:0 0 0 15px;font-size:12px;font-weight:500;min-height:24px;line-height:25px;text-transform:uppercase;background-color:#eee;background-position:top;background-image:linear-gradient(0deg,#ccc,#ccc 100%)}.list-item--material.list-item--expandable,.list-item--material__center,.list-item--material__left:empty,.list-item--material__right{background-size:100% 1px;background-repeat:no-repeat;background-position:bottom}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-header{background-image:linear-gradient(180deg,#ccc,#ccc 50%,transparent 50%)}}.list--noborder{border-top:none;border-bottom:none;background-image:none}.list-item--tappable:active{transition:none;background-color:#d9d9d9}.list--inset{margin:0 8px;border:1px solid #ccc;border-radius:4px;background-image:none}.list-item__label{font-size:14px;padding:0 4px;opacity:.6}.list-item__title{-webkit-flex-basis:100%;flex-basis:100%;-webkit-align-self:flex-end;align-self:flex-end;-webkit-box-ordinal-group:1;-webkit-order:0;order:0}.list-item__subtitle{opacity:.75;font-size:14px;-webkit-box-ordinal-group:2;-webkit-order:1;order:1;-webkit-flex-basis:100%;flex-basis:100%;-webkit-align-self:flex-start;align-self:flex-start}.list-item__thumbnail{width:40px;height:40px;border-radius:6px;display:block;margin:0}.list-item__icon{font-size:22px;padding:0 6px}.list--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;background-image:none;background-color:#fff}.list-item--material{border:0;padding:0 0 0 16px;line-height:normal}.list-item--material__subtitle{margin-top:4px}.list-item--material__left{padding:14px 0;min-width:56px;line-height:1;min-height:48px}.list-item--material__center,.list-item--material__left:empty{padding:14px 6px 14px 0;border-color:#eee;border-bottom:none;background-image:linear-gradient(0deg,#eee,#eee 100%);min-height:48px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material__center,.list-item--material__left:empty{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-item--material__right{padding:14px 16px 14px 0;line-height:1;border-color:#eee;border-bottom:none;background-image:linear-gradient(0deg,#eee,#eee 100%);min-height:48px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material__right{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-item--material.list-item--expandable{border-bottom:1px solid #eee;border-bottom:none;background-image:linear-gradient(0deg,#eee,#eee 100%);background-position-x:16px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material.list-item--expandable{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-item--material.list-item--expandable.list-item--longdivider,.list-item--material.list-item--longdivider{border-bottom:1px solid #eee;border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#eee,#eee 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--material.list-item--expandable.list-item--longdivider,.list-item--material.list-item--longdivider{background-image:linear-gradient(0deg,#eee,#eee 50%,transparent 50%)}}.list-header--material{background:#fff;border:none;font-size:14px;text-transform:none;margin:-1px 0 0;color:#757575;font-weight:500;padding:8px 16px}.list-header--material:not(:first-of-type){border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#eee,#eee 100%);padding-top:16px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-header--material:not(:first-of-type){background-image:linear-gradient(180deg,#eee,#eee 50%,transparent 50%)}}.list-item--material__thumbnail{width:40px;height:40px;border-radius:100%}.list-item--material__icon{font-size:20px;padding:0 4px}.list-item--chevron::before,.list-item__expand-chevron{border-right:2px solid #c7c7cc;border-bottom:2px solid #c7c7cc;width:7px;height:7px;background-color:transparent;z-index:5}.list-item--chevron::before{position:absolute;content:'';right:16px;top:50%;-webkit-transform:translateY(-50%) rotate(-45deg);transform:translateY(-50%) rotate(-45deg)}.list-item__expand-chevron{-webkit-transform:rotate(45deg);transform:rotate(45deg);margin:1px}.list-item--expandable.expanded .list-item__expand-chevron{-webkit-transform:rotate(225deg);transform:rotate(225deg)}.list-item--chevron__right{padding-right:30px}.list-item--expandable .list-item__center,.list-item--expandable .list-item__right,.list-item--nodivider.list-item--expandable,.list-item--nodivider__center,.list-item--nodivider__right{border:none;background-image:none}.list-item--longdivider{border-bottom:1px solid #ccc;border-bottom:none;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;background-image:linear-gradient(0deg,#ccc,#ccc 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.list-item--longdivider{background-image:linear-gradient(0deg,#ccc,#ccc 50%,transparent 50%)}}.list-item--longdivider:last-of-type,.list-item--longdivider__center,.list-item--longdivider__right{border:none;background-image:none}.list-title{font:inherit;background:0 0;border:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;display:block;color:#6d6d72;box-sizing:border-box;padding:0 0 0 16px;margin:0;font-size:13px;font-weight:500;line-height:24px;text-transform:uppercase;letter-spacing:.04em}.list-title--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#757575;font-size:14px;margin:0;padding:12px 0 12px 16px;font-weight:500;line-height:24px}.search-input{font:inherit;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTNweCIgaGVpZ2h0PSIxNHB4IiB2aWV3Qm94PSIwIDAgMTMgMTQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQyICgzNjc4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+aW9zLXNlYXJjaC1pbnB1dC1pY29uPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9ImNvbXBvbmVudHMiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJpb3Mtc2VhcmNoLWlucHV0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDguMDAwMDAwLCAtNDMuMDAwMDAwKSIgZmlsbD0iIzdBNzk3QiI+CiAgICAgICAgICAgIDxnIGlkPSJHcm91cCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDAuMDAwMDAwLCAzNi4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNi45OTcyNDgyLDE1LjUwNDE0NjYgQzE3LjA3NzM2NTcsMTUuNTQwNTkzOCAxNy4xNTIyNzMxLDE1LjU5MTYxMjkgMTcuMjE3NzUxNiwxNS42NTcwOTE0IEwyMC42NDk5OTEsMTkuMDg5MzMwOCBDMjAuOTQ0ODQ0OSwxOS4zODQxODQ3IDIwLjk0ODQ3NjQsMTkuODU4NjA2IDIwLjY1MzU0MTIsMjAuMTUzNTQxMiBDMjAuMzYwNjQ4LDIwLjQ0NjQzNDQgMTkuODgxMjcxNiwyMC40NDE5MzE3IDE5LjU4OTMzMDgsMjAuMTQ5OTkxIEwxNi4xNTcwOTE0LDE2LjcxNzc1MTYgQzE2LjA5MTM3LDE2LjY1MjAzMDEgMTYuMDQwMTE3MSwxNi41NzczODc0IDE2LjAwMzQxNDEsMTYuNDk3Nzk5NSBDMTUuMTY3MTY5NCwxNy4xMjcwNDExIDE0LjEyNzEzOTMsMTcuNSAxMywxNy41IEMxMC4yMzg1NzYzLDE3LjUgOCwxNS4yNjE0MjM3IDgsMTIuNSBDOCw5LjczODU3NjI1IDEwLjIzODU3NjMsNy41IDEzLDcuNSBDMTUuNzYxNDIzNyw3LjUgMTgsOS43Mzg1NzYyNSAxOCwxMi41IEMxOCwxMy42Mjc0Njg1IDE3LjYyNjgyMzIsMTQuNjY3Nzc2OCAxNi45OTcyNDgyLDE1LjUwNDE0NjYgWiBNMTMsMTYuNSBDMTUuMjA5MTM5LDE2LjUgMTcsMTQuNzA5MTM5IDE3LDEyLjUgQzE3LDEwLjI5MDg2MSAxNS4yMDkxMzksOC41IDEzLDguNSBDMTAuNzkwODYxLDguNSA5LDEwLjI5MDg2MSA5LDEyLjUgQzksMTQuNzA5MTM5IDEwLjc5MDg2MSwxNi41IDEzLDE2LjUgWiIgaWQ9Imlvcy1zZWFyY2gtaW5wdXQtaWNvbiI+PC9wYXRoPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=) 8px center no-repeat;border:none;vertical-align:top;outline:0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-appearance:textfield;-moz-appearance:textfield;appearance:textfield;box-sizing:border-box;height:28px;font-size:14px;background-color:rgba(3,3,3,.09);color:#1f1f21;line-height:1.3;padding:0 8px 0 28px;margin:0;border-radius:5.5px;background-size:13px;font-weight:400;display:inline-block;text-indent:0}.search-input::-webkit-search-cancel-button{-webkit-appearance:textfield;appearance:textfield;display:none}.search-input::-webkit-search-decoration{display:none}.search-input:focus{outline:0}.search-input::-webkit-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input:-ms-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input::-ms-input-placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input::placeholder{color:#7a797b;font-size:14px;text-indent:0}.search-input:disabled{opacity:.3;cursor:default;pointer-events:none}.search-input--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;border-radius:2px;height:48px;background-color:#fafafa;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMThweCIgaGVpZ2h0PSIxOHB4IiB2aWV3Qm94PSIwIDAgMTggMTgiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQzLjIgKDM5MDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5TaGFwZTwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJhbmRyb2lkLXNlYXJjaC1pbnB1dC1pY29uIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGZpbGw9IiM4OTg5ODkiPgogICAgICAgICAgICA8ZyBpZD0iY29tcG9uZW50cyI+CiAgICAgICAgICAgICAgICA8ZyBpZD0ibWF0ZXJpYWwtc2VhcmNoIj4KICAgICAgICAgICAgICAgICAgICA8ZyBpZD0ic2VhcmNoIj4KICAgICAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ik1hdGVyaWFsL0ljb25zLWJsYWNrL3NlYXJjaCI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuNTAyLDYuNDkxIEwxMS43MDgsNi40OTEgTDExLjQzMiw2Ljc2NSBDMTIuNDA3LDcuOTAyIDEzLDkuMzc2IDEzLDEwLjk5MSBDMTMsMTQuNTgxIDEwLjA5LDE3LjQ5MSA2LjUsMTcuNDkxIEMyLjkxLDE3LjQ5MSAwLDE0LjU4MSAwLDEwLjk5MSBDMCw3LjQwMSAyLjkxLDQuNDkxIDYuNSw0LjQ5MSBDOC4xMTUsNC40OTEgOS41ODgsNS4wODMgMTAuNzI1LDYuMDU3IEwxMS4wMDEsNS43ODMgTDExLjAwMSw0Ljk5MSBMMTUuOTk5LDAgTDE3LjQ5LDEuNDkxIEwxMi41MDIsNi40OTEgTDEyLjUwMiw2LjQ5MSBaIE02LjUsNi40OTEgQzQuMDE0LDYuNDkxIDIsOC41MDUgMiwxMC45OTEgQzIsMTMuNDc2IDQuMDE0LDE1LjQ5MSA2LjUsMTUuNDkxIEM4Ljk4NSwxNS40OTEgMTEsMTMuNDc2IDExLDEwLjk5MSBDMTEsOC41MDUgOC45ODUsNi40OTEgNi41LDYuNDkxIEw2LjUsNi40OTEgWiIgaWQ9IlNoYXBlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4Ljc0NTAwMCwgOC43NDU1MDApIHNjYWxlKC0xLCAxKSByb3RhdGUoLTE4MC4wMDAwMDApIHRyYW5zbGF0ZSgtOC43NDUwMDAsIC04Ljc0NTUwMCkgIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);background-size:18px;background-position:18px center;font-size:14px;padding:0 24px 0 64px;box-shadow:0 0 2px 0 rgba(0,0,0,.12),0 2px 2px 0 rgba(0,0,0,.24),0 1px 0 0 rgba(255,255,255,.06) inset}.text-input,.text-input--underbar{font:inherit;vertical-align:top;letter-spacing:0;box-shadow:none;padding:0;width:auto;height:31px;border:none;box-sizing:border-box;margin:0;-moz-osx-font-smoothing:grayscale;outline:0}.text-input{background:0 0;line-height:1;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;color:#1f1f21;font-size:15px;font-weight:400}.text-input::-ms-clear{display:none}.text-input:disabled{opacity:.3;cursor:default;pointer-events:none}.text-input::-webkit-input-placeholder{color:#999}.text-input:-ms-input-placeholder{color:#999}.text-input::-ms-input-placeholder{color:#999}.text-input::placeholder{color:#999}.text-input:disabled::-webkit-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled:-ms-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled::-ms-input-placeholder{border:none;background-color:transparent;color:#999}.text-input:disabled::placeholder{border:none;background-color:transparent;color:#999}.text-input:invalid{border:none;background-color:transparent;color:#1f1f21}.text-input--underbar{background:0 0;line-height:1;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;color:#1f1f21;font-size:15px;font-weight:400;border-bottom:1px solid #ccc;border-radius:0}.alert-dialog-button,.fab,.fab--material,.modal__content,.text-input--material{vertical-align:middle}.text-input--underbar:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent;border-bottom:1px solid #ccc}.text-input--underbar:disabled::-webkit-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled:-ms-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled::-ms-input-placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:disabled::placeholder{color:#999;border:none;background-color:transparent}.text-input--underbar:invalid{color:#1f1f21;border:none;background-color:transparent;border-bottom:1px solid #ccc}.text-input--material{box-sizing:border-box;padding:0 0 2px;margin:0;font:inherit;background:center bottom no-repeat;outline:0;line-height:1;-moz-osx-font-smoothing:grayscale;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#212121;background-image:linear-gradient(to top,transparent 1px,#afafaf 1px);background-size:100% 2px;font-size:16px;font-weight:400;border:none;border-radius:0;height:24px;-webkit-transform:translate3d(0,0,0)}.text-input--material__label{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;color:#afafaf;position:absolute;left:0;top:2px;font-size:16px;font-weight:400;pointer-events:none}.text-input--material__label--active{color:#3d5afe;-webkit-transform:translate(0,-75%) scale(.75);transform:translate(0,-75%) scale(.75);-webkit-transform-origin:left top;transform-origin:left top;transition:color .1s ease-in,-webkit-transform .1s ease-in;transition:transform .1s ease-in,color .1s ease-in;transition:transform .1s ease-in,color .1s ease-in,-webkit-transform .1s ease-in}.text-input--material:focus{background-image:linear-gradient(#3d5afe,#3d5afe),linear-gradient(to top,transparent 1px,#afafaf 1px);-webkit-animation:material-text-input-animate .3s forwards;animation:material-text-input-animate .3s forwards}.text-input--material::-webkit-input-placeholder{color:#afafaf;line-height:20px}.text-input--material:-ms-input-placeholder{color:#afafaf;line-height:20px}.text-input--material::-ms-input-placeholder{color:#afafaf;line-height:20px}.text-input--material::placeholder{color:#afafaf;line-height:20px}.textarea,.textarea--transparent{margin:0;font:inherit;vertical-align:top;resize:none;box-shadow:none;width:auto;-moz-osx-font-smoothing:grayscale;box-sizing:border-box;letter-spacing:0}@-webkit-keyframes material-text-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}@keyframes material-text-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}.textarea{background:#efeff4;line-height:normal;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;outline:0;padding:5px;font-size:15px;font-weight:400;border-radius:4px;border:1px solid #ccc;color:#1f1f21;appearance:none}.select-input,.textarea--transparent{-webkit-appearance:none;-moz-appearance:none;outline:0}.textarea:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea::-webkit-input-placeholder{color:#999}.textarea:-ms-input-placeholder{color:#999}.textarea::-ms-input-placeholder{color:#999}.textarea::placeholder{color:#999}.textarea--transparent{background:0 0;line-height:normal;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;padding:5px 0;font-size:15px;font-weight:400;border-radius:4px;border:none;color:#1f1f21;appearance:none}.dialog,.dialog-mask{font:inherit;background:0 0;cursor:default}.textarea--transparent:disabled{opacity:.3;cursor:default;pointer-events:none}.textarea--transparent::-webkit-input-placeholder{color:#999}.textarea--transparent:-ms-input-placeholder{color:#999}.textarea--transparent::-ms-input-placeholder{color:#999}.textarea--transparent::placeholder{color:#999}.dialog{box-sizing:border-box;padding:0;color:inherit;border:none;line-height:normal;-webkit-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);margin:auto;overflow:hidden;min-width:270px;min-height:100px}.alert-dialog,.dialog-mask{padding:0;-moz-user-select:none;position:absolute}.dialog-container{height:inherit;min-height:inherit;overflow:hidden;border-radius:4px;background-color:#f4f4f4;-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);color:#1f1f21}.dialog-mask{margin:0;color:inherit;border:none;line-height:normal;-webkit-user-select:none;-ms-user-select:none;user-select:none;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,.2)}.alert-dialog,.alert-dialog-button{cursor:default;-ms-user-select:none;-moz-osx-font-smoothing:grayscale}.dialog--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;text-align:left;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.dialog-container--material{border-radius:2px;background-color:#fff;color:#1f1f21}.dialog-mask--material{background-color:rgba(0,0,0,.3)}.alert-dialog{box-sizing:border-box;font:inherit;background:#f4f4f4;border:none;line-height:normal;-webkit-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:270px;margin:auto;border-radius:8px;overflow:visible;max-width:95%;color:#1f1f21}.alert-dialog-container{height:inherit;padding-top:16px;overflow:hidden}.alert-dialog-title{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:17px;font-weight:500;padding:0 8px;text-align:center;color:#1f1f21}.alert-dialog-content{box-sizing:border-box;background-clip:padding-box;padding:4px 12px 8px;font-size:14px;min-height:36px;text-align:center;color:#1f1f21}.alert-dialog-footer{width:100%}.alert-dialog-button{box-sizing:border-box;font:inherit;background:0 0;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;-webkit-user-select:none;-moz-user-select:none;user-select:none;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;text-decoration:none;letter-spacing:0;border:none;border-top:1px solid #ddd;font-size:16px;padding:0 8px;margin:0;display:block;width:100%;text-align:center;height:44px;line-height:44px;outline:0;color:#0076ff}.alert-dialog-mask,.popover__content{-moz-user-select:none;-ms-user-select:none;cursor:default}.alert-dialog-button:active{background-color:rgba(0,0,0,.05)}.alert-dialog-button--primal{font-weight:500}.alert-dialog-footer--rowfooter{white-space:nowrap;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.alert-dialog-button--rowfooter{-webkit-box-flex:1;-webkit-flex:1;flex:1;display:block;width:100%;border-left:1px solid #ddd}.alert-dialog-button--rowfooter:first-child{border-left:none}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top;background-image:linear-gradient(180deg,#ddd,#ddd 50%,transparent 50%)}.alert-dialog-button--rowfooter{border-top:none;border-left:none;background-size:100% 1px,1px 100%;background-repeat:no-repeat;background-position:top,left;background-image:linear-gradient(0deg,transparent,transparent 50%,#ddd 50%),linear-gradient(90deg,transparent,transparent 50%,#ddd 50%)}.alert-dialog-button--rowfooter:first-child{border-top:none;background-size:100% 1px;background-repeat:no-repeat;background-position:top,left;background-image:linear-gradient(0deg,transparent,transparent 50%,#ddd 50%)}}.alert-dialog-mask{padding:0;margin:0;font:inherit;color:inherit;background:0 0;border:none;line-height:normal;-webkit-user-select:none;user-select:none;position:absolute;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,.2)}.alert-dialog--material{border-radius:2px;background-color:#fff}.alert-dialog-container--material{padding:22px 0 0;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.alert-dialog-content--material,.alert-dialog-title--material{text-align:left;padding:0 24px;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased}.alert-dialog-title--material{font-size:20px;font-weight:500;color:#31313a}.alert-dialog-content--material{font-size:16px;font-weight:400;line-height:20px;margin:24px 0 10px;min-height:0;color:rgba(49,49,58,.85)}.alert-dialog-footer--material{display:block;padding:0;height:52px;box-sizing:border-box;margin:0;line-height:1}.alert-dialog-button--material{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;text-transform:uppercase;display:inline-block;width:auto;float:right;background:0 0;border:none;border-radius:2px;font-size:14px;font-weight:500;outline:0;height:36px;line-height:36px;padding:0 8px;margin:8px 8px 8px 0;box-sizing:border-box;min-width:50px;color:#37474f}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button--material{background:0 0}}.alert-dialog-button--material:active{background-color:initial}.alert-dialog-button--rowfooter--material,.alert-dialog-button--rowfooter--material:first-child{border:0}.alert-dialog-button--primal--material{font-weight:500}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.alert-dialog-button--primal--material,.alert-dialog-button--rowfooter--material,.alert-dialog-button--rowfooter--material:first-child{background:0 0}}.alert-dialog-mask--material{background-color:rgba(0,0,0,.3)}.popover{position:absolute;z-index:20001}.popover--bottom{bottom:0}.popover--top{top:0}.popover--left{left:0}.popover--right{right:0}.popover-mask{left:0;right:0;top:0;bottom:0;background-color:rgba(0,0,0,.2);position:absolute;z-index:19999}.popover__content{box-sizing:border-box;padding:0;margin:0;font:inherit;background:#fff;border:none;line-height:normal;-webkit-user-select:none;user-select:none;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;display:block;width:220px;overflow:auto;min-height:100px;max-height:100%;border-radius:8px;color:#1f1f21;pointer-events:auto}.popover-mask--material,.popover__arrow{background-color:transparent}.popover__arrow{position:absolute;width:18px;height:18px;-webkit-transform-origin:50% 50% 0;transform-origin:50% 50% 0;background-image:linear-gradient(45deg,#fff,#fff 50%,transparent 50%);border-radius:0 0 0 4px;margin:0;z-index:20001}.popover--bottom__arrow{-webkit-transform:translateY(6px) translateX(-9px) rotate(-45deg);transform:translateY(6px) translateX(-9px) rotate(-45deg);bottom:0;margin-right:-18px}.popover--top__arrow{-webkit-transform:translateY(-6px) translateX(-9px) rotate(135deg);transform:translateY(-6px) translateX(-9px) rotate(135deg);top:0;margin-right:-18px}.popover--left__arrow{-webkit-transform:translateX(-6px) translateY(-9px) rotate(45deg);transform:translateX(-6px) translateY(-9px) rotate(45deg);left:0;margin-bottom:-18px}.popover--right__arrow{-webkit-transform:translateX(6px) translateY(-9px) rotate(225deg);transform:translateX(6px) translateY(-9px) rotate(225deg);right:0;margin-bottom:-18px}.popover--material__content{background-color:#fafafa;border-radius:2px;color:#1f1f21;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.popover--material__arrow{display:none}.progress-bar{position:relative;height:2px;display:block;width:100%;background-color:transparent;background-clip:padding-box;margin:0;overflow:hidden;border-radius:4px}.progress-bar__primary,.progress-bar__secondary{position:absolute;background-color:#0076ff;top:0;bottom:0;transition:width .3s linear;z-index:100;border-radius:4px}.progress-bar__secondary{background-color:#65adff;z-index:0}.progress-bar--indeterminate:after,.progress-bar--indeterminate:before{content:'';position:absolute;background-color:#0076ff;top:0;left:0;bottom:0;will-change:left,right;border-radius:4px}.progress-bar--indeterminate:before{-webkit-animation:progress-bar__indeterminate 2.1s cubic-bezier(.65,.815,.735,.395) infinite;animation:progress-bar__indeterminate 2.1s cubic-bezier(.65,.815,.735,.395) infinite}.progress-bar--indeterminate:after{-webkit-animation:progress-bar__indeterminate-short 2.1s cubic-bezier(.165,.84,.44,1) infinite;animation:progress-bar__indeterminate-short 2.1s cubic-bezier(.165,.84,.44,1) infinite;-webkit-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes progress-bar__indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@keyframes progress-bar__indeterminate{0%{left:-35%;right:100%}100%,60%{left:100%;right:-90%}}@-webkit-keyframes progress-bar__indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}@keyframes progress-bar__indeterminate-short{0%{left:-200%;right:100%}100%,60%{left:107%;right:-8%}}.progress-bar--material{height:4px;background-color:transparent;border-radius:0}.progress-bar--material__primary,.progress-bar--material__secondary{background-color:#37474f;border-radius:0}.progress-bar--material__secondary{background-color:#548ba7;z-index:0}.fab--material__icon,.fab__icon{overflow:hidden;z-index:100;position:relative}.progress-bar--material.progress-bar--indeterminate:after,.progress-bar--material.progress-bar--indeterminate:before{background-color:#37474f;border-radius:0}.progress-circular{height:32px;position:relative;width:32px;-webkit-transform:rotate(270deg);transform:rotate(270deg);-webkit-animation:none;animation:none}.progress-circular__background,.progress-circular__primary,.progress-circular__secondary{cx:50%;cy:50%;r:40%;-webkit-animation:none;animation:none;fill:none;stroke-width:5%;stroke-miterlimit:10}.progress-circular__background{stroke:transparent}.progress-circular__primary{stroke-dasharray:1,200;stroke-dashoffset:0;stroke:#0076ff;transition:all 1s cubic-bezier(.4,0,.2,1)}.progress-circular__secondary{stroke:#65adff}.progress-circular--indeterminate{-webkit-animation:progress__rotate 2s linear infinite;animation:progress__rotate 2s linear infinite;-webkit-transform:none;transform:none}.progress-circular--indeterminate__primary{-webkit-animation:progress__dash 1.5s ease-in-out infinite;animation:progress__dash 1.5s ease-in-out infinite}.progress-circular--indeterminate__secondary{display:none}@-webkit-keyframes progress__rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes progress__rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes progress__dash{0%{stroke-dasharray:10%,241.32%;stroke-dashoffset:0}50%{stroke-dasharray:201%,50.322%;stroke-dashoffset:-100%}100%{stroke-dasharray:10%,241.32%;stroke-dashoffset:-251.32%}}@keyframes progress__dash{0%{stroke-dasharray:10%,241.32%;stroke-dashoffset:0}50%{stroke-dasharray:201%,50.322%;stroke-dashoffset:-100%}100%{stroke-dasharray:10%,241.32%;stroke-dashoffset:-251.32%}}.progress-circular--material__background,.progress-circular--material__primary,.progress-circular--material__secondary{stroke-width:9%}.progress-circular--material__background{stroke:transparent}.progress-circular--material__primary{stroke:#37474f}.progress-circular--material__secondary{stroke:#548ba7}.fab{position:relative;display:inline-block;box-sizing:border-box;padding:0;margin:0;font:inherit;background:#0076ff;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:56px;height:56px;text-decoration:none;font-size:25px;line-height:56px;letter-spacing:0;color:#fff;text-align:center;border:0 solid currentColor;border-radius:50%;overflow:hidden;box-shadow:0 3px 6px rgba(0,0,0,.12);transition:all .1s linear}.fab:active{background-color:rgba(0,118,255,.7);transition:all .2s ease;box-shadow:0 0 6 rgba(0,0,0,.12)}.fab:focus{outline:0}.fab__icon{height:100%;width:100%;display:block;border-radius:100%;padding:0;line-height:56px}.fab:disabled,.fab[disabled]{background-color:rgba(0,0,0,.5);box-shadow:none;opacity:.3;cursor:default;pointer-events:none}.fab--material{position:relative;display:inline-block;box-sizing:border-box;padding:0;margin:0;font:inherit;background:#fff;-moz-osx-font-smoothing:grayscale;cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;letter-spacing:0;text-align:center;border:0 solid currentColor;border-radius:50%;overflow:hidden;font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;width:56px;height:56px;text-decoration:none;font-size:25px;line-height:56px;color:#31313a;box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4);transition:all .2s ease-in-out}.fab--material:active{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.4);background-color:rgba(255,255,255,.75);transition:all .2s ease}.fab--material:focus{outline:0}.fab--material__icon{height:100%;width:100%;display:block;border-radius:100%;padding:0;line-height:56px}.fab--mini,.fab--mini__icon{line-height:40px}.fab--material:disabled,.fab--material[disabled]{background-color:rgba(0,0,0,.5);box-shadow:none;opacity:.3;cursor:default;pointer-events:none}.fab--mini{width:40px;height:40px}.modal,.modal__content{overflow:hidden;word-spacing:0;padding:0;font:inherit;border:none}.speed-dial__item{position:absolute;-webkit-transform:scale(0);transform:scale(0)}.fab--top__right{top:20px;bottom:auto;right:20px;left:auto;position:absolute}.fab--bottom__right{top:auto;bottom:20px;right:20px;left:auto;position:absolute}.fab--top__left{top:20px;bottom:auto;right:auto;left:20px;position:absolute}.fab--bottom__left{top:auto;bottom:20px;right:auto;left:20px;position:absolute}.fab--bottom__center,.fab--top__center{margin-left:-28px;left:50%;right:auto;position:absolute}.fab--top__center{top:20px;bottom:auto}.fab--bottom__center{top:auto;bottom:20px}.modal,.modal__content,.select-input{margin:0;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}.modal{white-space:nowrap;color:inherit;background:0 0;line-height:normal;background-clip:padding-box;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;background-color:rgba(0,0,0,.7);position:absolute;left:0;right:0;top:0;bottom:0;width:100%;height:100%;display:table;z-index:2147483647}.modal__content{background:0 0;line-height:normal;background-clip:padding-box;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;display:table-cell;text-align:center;color:#fff;white-space:normal}.select-input{font:inherit;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTBweCIgaGVpZ2h0PSI1cHgiIHZpZXdCb3g9IjAgMCAxMCA1IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0My4yICgzOTA2OSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+c2VsZWN0LWFsbG93PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9InNlbGVjdCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Imlvcy1zZWxlY3QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOTguMDAwMDAwLCAtMTE0LjAwMDAwMCkiIGZpbGw9IiM3NTc1NzUiPgogICAgICAgICAgICA8ZyBpZD0ibWVudS1iYXItKy1vcGVuLW1lbnUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMy4wMDAwMDAsIDEwMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJtZW51LWJhciI+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9InNlbGVjdC1hbGxvdyIgcG9pbnRzPSI3NSAxNCA4MCAxOSA4NSAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=) right center no-repeat;vertical-align:top;font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;font-weight:400;position:relative;font-size:17px;height:32px;line-height:32px;color:#1f1f21;appearance:none;display:inline-block;border-radius:0;border:none;padding:0 20px 0 0;border-bottom:none}.select-input--material,.select-input--material__label{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.select-input::-ms-clear{display:none}.select-input::-webkit-input-placeholder{color:#999}.select-input:-ms-input-placeholder{color:#999}.select-input::-ms-input-placeholder{color:#999}.select-input::placeholder{color:#999}.select-input:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent}.select-input:disabled::-webkit-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled:-ms-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled::-ms-input-placeholder{border:none;background-color:transparent;color:#999}.select-input:disabled::placeholder{border:none;background-color:transparent;color:#999}.select-input:invalid{border:none;background-color:transparent;color:#1f1f21}.select-input[multiple]{height:64px}.select-input--material{color:#1f1f21;font-size:15px;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTBweCIgaGVpZ2h0PSI1cHgiIHZpZXdCb3g9IjAgMCAxMCA1IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0My4yICgzOTA2OSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+c2VsZWN0LWFsbG93PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9InNlbGVjdCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Imlvcy1zZWxlY3QiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xOTguMDAwMDAwLCAtMTE0LjAwMDAwMCkiIGZpbGw9IiM3NTc1NzUiPgogICAgICAgICAgICA8ZyBpZD0ibWVudS1iYXItKy1vcGVuLW1lbnUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMy4wMDAwMDAsIDEwMC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJtZW51LWJhciI+CiAgICAgICAgICAgICAgICAgICAgPHBvbHlnb24gaWQ9InNlbGVjdC1hbGxvdyIgcG9pbnRzPSI3NSAxNCA4MCAxOSA4NSAxNCI+PC9wb2x5Z29uPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=),linear-gradient(to top,rgba(0,0,0,.12) 50%,rgba(0,0,0,.12) 50%);background-size:auto,100% 1px;background-repeat:no-repeat;background-position:right center,left bottom;border:none;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.select-input--material__label{color:rgba(0,0,0,.81);position:absolute;left:0;top:2px;font-size:16px;pointer-events:none}.select-input--material__label--active{color:rgba(0,0,0,.15);-webkit-transform:translate(0,-75%) scale(.75);transform:translate(0,-75%) scale(.75);-webkit-transform-origin:left top;transform-origin:left top;transition:color .1s ease-in,-webkit-transform .1s ease-in;transition:transform .1s ease-in,color .1s ease-in;transition:transform .1s ease-in,color .1s ease-in,-webkit-transform .1s ease-in}.select-input--material::-webkit-input-placeholder{color:rgba(0,0,0,.81);line-height:20px}.select-input--material:-ms-input-placeholder{color:rgba(0,0,0,.81);line-height:20px}.select-input--material::-ms-input-placeholder{color:rgba(0,0,0,.81);line-height:20px}.select-input--material::placeholder{color:rgba(0,0,0,.81);line-height:20px}@-webkit-keyframes material-select-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}@keyframes material-select-input-animate{0%{background-size:0 2px,100% 2px}100%{background-size:100% 2px,100% 2px}}.action-sheet-button,.action-sheet-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;background-size:100% 1px;background-repeat:no-repeat;background-position:bottom;height:56px;line-height:56px}.select-input--underbar{border:none;border-bottom:1px solid #ccc}.select-input--underbar:disabled{opacity:.3;cursor:default;pointer-events:none;border:none;background-color:transparent;border-bottom:1px solid #ccc}.select-input--underbar:disabled::-webkit-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled:-ms-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled::-ms-input-placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:disabled::placeholder{color:#999;border:none;background-color:transparent}.select-input--underbar:invalid{color:#1f1f21;border:none;background-color:transparent;border-bottom:1px solid #ccc}.action-sheet{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;cursor:default;position:absolute;left:10px;right:10px;bottom:10px;z-index:2;max-height:100%;overflow-y:scroll}.action-sheet-button{box-sizing:border-box;font-size:20px;text-align:center;color:#0076ff;background-color:rgba(255,255,255,.9);border-radius:0;border:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;display:block;width:100%;background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 100%)}.action-sheet-button:first-child,.action-sheet-title:first-child{border-top-left-radius:12px;border-top-right-radius:12px}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.action-sheet-button{background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 50%,transparent 50%)}}.action-sheet-button:active{background-color:#e9e9e9;background-image:none}.action-sheet-button:focus{outline:0}.action-sheet-button:nth-last-of-type(2){border-bottom-right-radius:12px;border-bottom-left-radius:12px;background-image:none}.action-sheet-button:last-of-type{border-radius:12px;margin:8px 0 0;background-color:#fff;background-image:none;font-weight:600}.action-sheet-button:last-of-type:active{background-color:#e9e9e9}.action-sheet-button--destructive{color:#fe3824}.action-sheet-title{box-sizing:border-box;font-size:13px;color:#8f8e94;text-align:center;background-color:rgba(255,255,255,.9);background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 100%)}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:192dpi),(min-resolution:2dppx){.action-sheet-title{background-image:linear-gradient(0deg,rgba(0,0,0,.1),rgba(0,0,0,.1) 50%,transparent 50%)}}.action-sheet-button--material,.action-sheet-title--material{font-family:Roboto,Noto,sans-serif;background-image:none;text-align:left;font-size:16px;padding:0 0 0 16px;color:#686868;-webkit-font-smoothing:antialiased}.action-sheet-icon{display:none}.action-sheet-mask{position:absolute;left:0;top:0;right:0;bottom:0;background-color:rgba(0,0,0,.1);z-index:1}.action-sheet-button--material,.action-sheet-button--material:last-of-type,.action-sheet-title--material{border-radius:0;background-color:#fff;font-weight:400}.action-sheet--material{left:0;right:0;bottom:0;box-shadow:0 16px 24px 2px rgba(0,0,0,.14),0 6px 30px 5px rgba(0,0,0,.12),0 8px 10px -5px rgba(0,0,0,.4)}.action-sheet-title--material{height:56px;line-height:56px}.action-sheet-title--material:first-child{border-radius:0}.action-sheet-button--material{height:52px;line-height:52px}.action-sheet-button--material:first-child,.action-sheet-button--material:nth-last-of-type(2){border-radius:0}.action-sheet-button--material:last-of-type{margin:0}.action-sheet-icon--material{display:inline-block;float:left;height:52px;line-height:52px;margin-right:32px;font-size:26px;width:.8em;text-align:center}.card,.card__title{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;display:block;-moz-osx-font-smoothing:grayscale;box-sizing:border-box}.action-sheet-mask--material{background-color:rgba(0,0,0,.2)}.card,.card--material{background-color:#fff}.card{-webkit-font-smoothing:antialiased;font-weight:400;box-shadow:0 1px 2px rgba(0,0,0,.12);border-radius:8px;margin:8px;padding:16px;text-align:left;word-wrap:break-word}.card__content{margin:0;font-size:14px;line-height:1.4;color:#030303}.card__title{-webkit-font-smoothing:antialiased;font-weight:400;font-size:20px;margin:4px 0 8px;padding:0}.card--material,.card--material__title{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.card--material{border-radius:2px;box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2)}.card--material__content{font-size:14px;line-height:1.4;color:rgba(0,0,0,.54)}.card--material__title{font-size:24px;margin:8px 0 12px}.toast{font-family:-apple-system,'Helvetica Neue',Helvetica,Arial,'Lucida Grande',sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;position:absolute;z-index:2;left:8px;right:8px;bottom:0;margin:8px 0;border-radius:8px;background-color:rgba(0,0,0,.8);display:-webkit-box;display:-webkit-flex;display:flex;min-height:48px;line-height:1.5;box-sizing:border-box;padding:16px}.toast--material__button,.toast--material__message{font-family:Roboto,Noto,sans-serif;-webkit-font-smoothing:antialiased;font-weight:400}.toast__message{font-size:14px;color:#fff;-webkit-box-flex:1;-webkit-flex-grow:1;flex-grow:1;text-align:left;margin:0 16px 0 0;white-space:normal}.toast__button{font-size:14px;color:#fff;-webkit-box-flex:0;-webkit-flex-grow:0;flex-grow:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;background-color:transparent;cursor:default;text-transform:uppercase}.toast__button:focus{outline:0}.toast__button:active{opacity:.4}.toast--material{left:0;right:0;bottom:0;margin:0;background-color:rgba(0,0,0,.8);border-radius:0;padding:0 24px}.bottom-bar,.tabbar:not(.tabbar--top){padding-bottom:0}.toast--material__message{margin:0 24px 0 0}.toast--material__button{color:#bbdefb}.toolbar{top:0;box-sizing:border-box;padding-top:0}.bottom-bar{bottom:0;box-sizing:border-box}.toolbar+.page__background{top:44px}.page__content{top:0;padding-top:0;bottom:0}.toolbar+.page__background+.page__content{top:44px;padding-top:0}.page-with-bottom-toolbar>.page__content{bottom:44px}.toolbar.toolbar--material+.page__background{top:56px}.toolbar.toolbar--material+.page__background+.page__content{top:56px;padding-top:0}.toolbar.toolbar--transparent+.page__background{top:0}.toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,.toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:44px}.toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,.toolbar.toolbar--material.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:56px}.tabbar--top{padding-top:0}@media (orientation:portrait){html[onsflag-iphonex-portrait] .fab--top__center,html[onsflag-iphonex-portrait] .fab--top__left,html[onsflag-iphonex-portrait] .fab--top__right{top:64px}html[onsflag-iphonex-portrait] .fab--bottom__center,html[onsflag-iphonex-portrait] .fab--bottom__left,html[onsflag-iphonex-portrait] .fab--bottom__right{bottom:34px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .page__content{padding-left:44px;padding-right:44px}html[onsflag-iphonex-landscape] .dialog .page__content,html[onsflag-iphonex-landscape] .modal .page__content{padding-left:0;padding-right:0}html[onsflag-iphonex-landscape] .toolbar__left{padding-left:44px}html[onsflag-iphonex-landscape] .toolbar__right{padding-right:44px}html[onsflag-iphonex-landscape] .bottom-bar{padding-right:44px;padding-left:44px}html[onsflag-iphonex-landscape] .tabbar{padding-left:44px;padding-right:44px;width:calc(100% - 88px)}html[onsflag-iphonex-landscape] .fab--bottom__center,html[onsflag-iphonex-landscape] .fab--bottom__left,html[onsflag-iphonex-landscape] .fab--bottom__right{bottom:21px}html[onsflag-iphonex-landscape] .fab--bottom__left,html[onsflag-iphonex-landscape] .fab--top__left{left:44px}html[onsflag-iphonex-landscape] .fab--bottom__right,html[onsflag-iphonex-landscape] .fab--top__right{right:44px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .action-sheet{bottom:48px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .action-sheet{left:calc((100vw - 100vh + 20px)/ 2);right:calc((100vw - 100vh + 20px)/ 2);bottom:33px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .toast{bottom:34px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .toast{left:52px;right:52px;bottom:21px}}@media (orientation:portrait){html[onsflag-iphonex-portrait] .toolbar{top:0;box-sizing:content-box;padding-top:44px}html[onsflag-iphonex-portrait] .dialog .toolbar,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar{top:0;box-sizing:border-box;padding-top:0}html[onsflag-iphonex-portrait] .bottom-bar{bottom:0;box-sizing:content-box;padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .bottom-bar,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .bottom-bar,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .bottom-bar{bottom:0;box-sizing:border-box;padding-bottom:0}html[onsflag-iphonex-portrait] .page__content{top:0;padding-top:44px;bottom:0;padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .page__content{top:0;padding-top:0}html[onsflag-iphonex-portrait] .dialog .page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .page__content,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page__content{bottom:0;padding-bottom:0}html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content{top:88px;padding-top:0}html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .dialog .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar:not(.toolbar--cover-content)+.page__background+.page__content{top:44px;padding-top:0}html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content{bottom:78px;padding-bottom:0}html[onsflag-iphonex-portrait] .dialog .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar>.page__content{bottom:44px;padding-bottom:0}html[onsflag-iphonex-portrait] .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content{top:0;padding-top:88px}html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .dialog .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .tabbar--top__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page_content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .toolbar.toolbar--transparent.toolbar--cover-content+.page__background+.page__content .page__content{top:0;padding-top:44px}html[onsflag-iphonex-portrait] .tabbar--top{padding-top:44px}html[onsflag-iphonex-portrait] .dialog .tabbar--top,html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top{padding-top:0}html[onsflag-iphonex-portrait] .tabbar--top__content{top:93px}html[onsflag-iphonex-portrait] .dialog .tabbar--top__content,html[onsflag-iphonex-portrait] .tabbar--top__content .tabbar--top__content,html[onsflag-iphonex-portrait] .toolbar:not(.toolbar--cover-content)+.page__background+.page__content .tabbar--top__content{top:49px}html[onsflag-iphonex-portrait] .tabbar:not(.tabbar--top):not(.tabbar--top){padding-bottom:34px}html[onsflag-iphonex-portrait] .dialog .tabbar:not(.tabbar--top):not(.tabbar--top),html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .tabbar:not(.tabbar--top),html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top){padding-bottom:0}html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content){bottom:83px}html[onsflag-iphonex-portrait] .dialog .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-portrait] .page-with-bottom-toolbar>.page__content .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-portrait] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content){bottom:49px}}@media (orientation:landscape){html[onsflag-iphonex-landscape] .bottom-bar{bottom:0;box-sizing:content-box;padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .bottom-bar,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .bottom-bar,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .bottom-bar{bottom:0;box-sizing:border-box;padding-bottom:0}html[onsflag-iphonex-landscape] .page__content{bottom:0;padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .page__content,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page__content{bottom:0;padding-bottom:0}html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content{bottom:65px;padding-bottom:0}html[onsflag-iphonex-landscape] .dialog .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .page-with-bottom-toolbar>.page__content,html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .page-with-bottom-toolbar>.page__content{bottom:44px;padding-bottom:0}html[onsflag-iphonex-landscape] .tabbar:not(.tabbar--top){padding-bottom:21px}html[onsflag-iphonex-landscape] .dialog .tabbar:not(.tabbar--top),html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .tabbar:not(.tabbar--top),html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar:not(.tabbar--top){padding-bottom:0}html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content){bottom:70px}html[onsflag-iphonex-landscape] .dialog .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-landscape] .page-with-bottom-toolbar>.page__content .tabbar__content:not(.tabbar--top__content),html[onsflag-iphonex-landscape] .tabbar__content:not(.tabbar--top__content) .tabbar__content:not(.tabbar--top__content){bottom:49px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset){margin-left:-44px;margin-right:-44px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-header{padding-left:59px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item{padding-left:58px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:60px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:50px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:56px}html[onsflag-iphonex-landscape] .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:74px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset){margin-left:0;margin-right:0}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-header{padding-left:15px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item{padding-left:14px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:16px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:6px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:12px}html[onsflag-iphonex-landscape] .dialog .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:30px}} diff --git a/old_frontend/lib/css/onsenui-core.min.css b/old_frontend/lib/css/onsenui-core.min.css deleted file mode 100644 index 9aff26fb..00000000 --- a/old_frontend/lib/css/onsenui-core.min.css +++ /dev/null @@ -1 +0,0 @@ -/*! onsenui - v2.10.1 - 2018-05-28 */ons-gesture-detector,ons-navigator,ons-page,ons-tabbar{display:block;touch-action:manipulation}ons-action-sheet,ons-alert-dialog,ons-dialog,ons-navigator,ons-splitter,ons-tabbar,ons-toast{position:absolute;top:0;left:0;bottom:0;right:0;overflow:hidden;touch-action:manipulation}ons-toast{pointer-events:none}ons-toast .toast{pointer-events:auto}ons-tab{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}ons-action-sheet,ons-alert-dialog,ons-dialog,ons-navigator,ons-page,ons-tabbar,ons-toast{z-index:2}ons-fab,ons-speed-dial{z-index:10001}ons-bottom-toolbar,ons-toolbar:not([inline]){position:absolute;left:0;right:0;z-index:10000}ons-toolbar:not([inline]){top:0}ons-bottom-toolbar{bottom:0}.page,.page--material,.page--material__content,.page__content{background:0 0!important}.page__content{overflow:auto;-webkit-overflow-scrolling:touch;z-index:0;-ms-touch-action:pan-y}.page.overflow-visible,.page.overflow-visible .page,.page.overflow-visible .page__content,.page.overflow-visible ons-navigator,.page.overflow-visible ons-splitter{overflow:visible}.page.overflow-visible .page__content.content-swiping,.page.overflow-visible .page__content.content-swiping .page,.page.overflow-visible .page__content.content-swiping .page__content{overflow:auto}.page[status-bar-fill]>.page__content{top:20px}.page[status-bar-fill]>.toolbar{padding-top:20px;box-sizing:content-box}.ons-status-bar-mock,.ons-swiper,.ons-swiper-target>*,ons-col,ons-row{box-sizing:border-box}.page[status-bar-fill]>.toolbar:not(.toolbar--cover-content)+.page__background+.page__content,.page[status-bar-fill]>.toolbar:not(.toolbar--transparent)+.page__background{top:64px}.page[status-bar-fill]>.toolbar--material:not(.toolbar--cover-content)+.page__background+.page__content,.page[status-bar-fill]>.toolbar--material:not(.toolbar-transparent)+.page__background{top:76px}.page[status-bar-fill]>.toolbar.toolbar--transparent+.page__background{top:0}ons-tabbar[status-bar-fill]>.tabbar--top__content{top:71px}ons-tabbar[status-bar-fill]>.tabbar--top{padding-top:22px}.toolbar+.page__background+.page__content ons-tabbar[status-bar-fill]>.tabbar--top,ons-tabbar[position=top] .page[status-bar-fill]>.page__content{top:0}.toolbar+.page__background+.page__content ons-tabbar[status-bar-fill]>.tabbar--top__content{top:49px}.page__content>.list:not(.list--material):first-child{margin-top:-1px}.page--wrapper>.page__background{display:none}ons-action-sheet[disabled],ons-alert-dialog[disabled],ons-dialog[disabled],ons-popover[disabled]{pointer-events:none;opacity:.75}ons-list-item[disabled]{pointer-events:none}ons-range[disabled]{opacity:.3;pointer-events:none}ons-pull-hook{position:relative;display:block;margin:auto;text-align:center;z-index:20002}ons-splitter,ons-splitter-content,ons-splitter-mask,ons-splitter-side{display:block;position:absolute;left:0;right:0;top:0;bottom:0;box-sizing:border-box;z-index:0}ons-splitter-mask{z-index:4;background-color:rgba(0,0,0,.1);display:none;opacity:0}ons-splitter-content{z-index:2}ons-splitter-side{right:auto;z-index:2}ons-splitter-side[side=right]{right:0;left:auto}ons-splitter-side[mode=collapse]{z-index:5;left:auto;right:100%}ons-splitter-side[side=right][mode=collapse]{right:auto;left:100%}ons-splitter-side[mode=split]{z-index:3}ons-toolbar-button>ons-icon[icon*=ion-]{font-size:26px}ons-range,ons-select{display:inline-block}ons-range>input{min-width:50px;width:100%}ons-select>select{width:100%}ons-carousel[disabled]{pointer-events:none;opacity:.75}ons-carousel[fullscreen]{height:100%}.ons-status-bar-mock{position:absolute;width:100%;height:20px;padding:0 16px 0 6px;z-index:30000;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;font-size:12px;line-height:20px;font-family:Arial,Helvetica}.ons-status-bar-mock i{padding:0 2px}.ons-status-bar-mock.android{color:#fff;background-color:#222;font-family:Roboto,Arial,Helvetica}.ons-status-bar-mock.android~*{top:20px;bottom:0;position:inherit;width:100%}.ons-ios-scroll-fix .page:not(.page--wrapper)[shown]>.page__content{overflow-y:hidden}.ons-ios-scroll-fix ons-splitter-side>.page:not(.page--wrapper)[shown]>.page__content{overflow-y:auto}ons-row{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;width:100%}ons-row[align=top],ons-row[vertical-align=top]{-webkit-box-align:start;box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;-moz-align-items:flex-start;align-items:flex-start}ons-row[align=bottom],ons-row[vertical-align=bottom]{-webkit-box-align:end;box-align:end;-ms-flex-align:end;-webkit-align-items:flex-end;-moz-align-items:flex-end;align-items:flex-end}ons-row[align=center],ons-row[vertical-align=center]{-webkit-box-align:center;box-align:center;-ms-flex-align:center;-webkit-align-items:center;-moz-align-items:center;align-items:center;text-align:inherit}ons-row+ons-row{padding-top:0}ons-col{-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-moz-flex:1;-ms-flex:1;flex:1;display:block;width:100%}ons-col[align=top],ons-col[vertical-align=top]{-webkit-align-self:flex-start;-moz-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}ons-col[align=bottom],ons-col[vertical-align=bottom]{-webkit-align-self:flex-end;-moz-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}ons-col[align=center],ons-col[vertical-align=center]{-webkit-align-self:center;-moz-align-self:center;-ms-flex-item-align:center;text-align:inherit}.ons-icon{display:inline-block;line-height:inherit;font-style:normal;font-weight:400;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.segment__button .ons-icon{line-height:initial}:not(ons-toolbar-button):not(ons-action-sheet-button):not(.segment__button)>.ons-icon--ion{line-height:.75em;vertical-align:-25%}.ons-icon[spin]{-webkit-animation:ons-icon-spin 2s infinite linear;-moz-animation:ons-icon-spin 2s infinite linear;animation:ons-icon-spin 2s infinite linear}@-moz-keyframes ons-icon-spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes ons-icon-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@keyframes ons-icon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.ons-icon[rotate="90"]{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);transform:rotate(90deg)}.ons-icon[rotate="180"]{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);transform:rotate(180deg)}.ons-icon[rotate="270"]{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);transform:rotate(270deg)}.ons-icon[fixed-width]{width:1.28571429em;text-align:center}.ons-icon--lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.ons-icon--2x{font-size:2em}.ons-icon--3x{font-size:3em}.ons-icon--4x{font-size:4em}.ons-icon--5x{font-size:5em}ons-checkbox,ons-input,ons-radio,ons-search-input{display:inline-block;position:relative}.ripple,.ripple__wave{position:absolute}ons-input .text-input,ons-search-input .search-input{width:100%;display:inline-block}ons-input .text-input__label:not(.text-input--material__label),ons-input:not([float]) .text-input--material__label--active{display:none}ons-checkbox[disabled],ons-input[disabled],ons-radio[disabled],ons-search-input[disabled],ons-segment[disabled]{opacity:.5;pointer-events:none}ons-input input.text-input--material::-webkit-input-placeholder{color:transparent}ons-input input.text-input--material::-moz-placeholder{color:transparent}ons-input input.text-input--material:-ms-input-placeholder{color:transparent}@media (orientation:landscape){html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content{padding-right:0}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content{padding-left:0}html[onsflag-iphonex-landscape] .page__content>ons-progress-bar>.progress-bar{margin-left:-44px;margin-right:-44px;width:calc(100% + 88px)}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content>.list:not(.list--inset){margin-left:0}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content>.list:not(.list--inset)>.list-header{padding-left:15px}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content>.list:not(.list--inset)>.list-item{padding-left:14px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset){margin-right:0}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:16px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:6px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:12px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:30px}}.ons-swiper-blocker,.ripple,.ripple__background{top:0;bottom:0;left:0;right:0;pointer-events:none}ons-progress-bar{display:block}ons-progress-circular{display:inline-block;width:32px;height:32px}.ons-swiper,.ripple{overflow:hidden;display:block}ons-progress-circular>svg.progress-circular{width:100%;height:100%}.ripple__background{background:rgba(255,255,255,.2);position:absolute;opacity:0}.ripple__wave{background:rgba(255,255,255,.2);width:0;height:0;border-radius:50%;top:0;left:0;z-index:0;pointer-events:none}.button--material--flat .ripple__background,.button--material--flat .ripple__wave,.ripple--light-gray__background,.ripple--light-gray__wave,ons-list-item .ripple__background,ons-list-item .ripple__wave{background:rgba(189,189,189,.3)}.ons-swiper-target{display:-webkit-box;display:-webkit-flex;display:flex;height:100%;z-index:1;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row}.ons-swiper-target--vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column}.ons-swiper-target>*{height:inherit;-webkit-flex-shrink:0;flex-shrink:0;width:100%;position:relative!important}.ons-swiper-target.active:not(.swiping)>.page:not([shown]){visibility:hidden}.ons-swiper-tabbar .tabbar--material__button:after{display:none}.ons-swiper-blocker{display:block;position:absolute} \ No newline at end of file diff --git a/old_frontend/lib/css/onsenui.min.css b/old_frontend/lib/css/onsenui.min.css deleted file mode 100644 index 5cc6bd73..00000000 --- a/old_frontend/lib/css/onsenui.min.css +++ /dev/null @@ -1 +0,0 @@ -/*! onsenui - v2.10.1 - 2018-05-28 */@import url(ionicons/css/ionicons.min.css);@import url(font_awesome/css/font-awesome.min.css);ons-gesture-detector,ons-navigator,ons-page,ons-tabbar{display:block;touch-action:manipulation}ons-action-sheet,ons-alert-dialog,ons-dialog,ons-navigator,ons-splitter,ons-tabbar,ons-toast{position:absolute;top:0;left:0;bottom:0;right:0;overflow:hidden;touch-action:manipulation}ons-toast{pointer-events:none}ons-toast .toast{pointer-events:auto}ons-tab{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}ons-action-sheet,ons-alert-dialog,ons-dialog,ons-navigator,ons-page,ons-tabbar,ons-toast{z-index:2}ons-fab,ons-speed-dial{z-index:10001}ons-bottom-toolbar,ons-toolbar:not([inline]){position:absolute;left:0;right:0;z-index:10000}ons-toolbar:not([inline]){top:0}ons-bottom-toolbar{bottom:0}.page,.page--material,.page--material__content,.page__content{background:0 0!important}.page__content{overflow:auto;-webkit-overflow-scrolling:touch;z-index:0;-ms-touch-action:pan-y}.page.overflow-visible,.page.overflow-visible .page,.page.overflow-visible .page__content,.page.overflow-visible ons-navigator,.page.overflow-visible ons-splitter{overflow:visible}.page.overflow-visible .page__content.content-swiping,.page.overflow-visible .page__content.content-swiping .page,.page.overflow-visible .page__content.content-swiping .page__content{overflow:auto}.page[status-bar-fill]>.page__content{top:20px}.page[status-bar-fill]>.toolbar{padding-top:20px;box-sizing:content-box}.ons-status-bar-mock,.ons-swiper,.ons-swiper-target>*,ons-col,ons-row{box-sizing:border-box}.page[status-bar-fill]>.toolbar:not(.toolbar--cover-content)+.page__background+.page__content,.page[status-bar-fill]>.toolbar:not(.toolbar--transparent)+.page__background{top:64px}.page[status-bar-fill]>.toolbar--material:not(.toolbar--cover-content)+.page__background+.page__content,.page[status-bar-fill]>.toolbar--material:not(.toolbar-transparent)+.page__background{top:76px}.page[status-bar-fill]>.toolbar.toolbar--transparent+.page__background{top:0}ons-tabbar[status-bar-fill]>.tabbar--top__content{top:71px}ons-tabbar[status-bar-fill]>.tabbar--top{padding-top:22px}.toolbar+.page__background+.page__content ons-tabbar[status-bar-fill]>.tabbar--top,ons-tabbar[position=top] .page[status-bar-fill]>.page__content{top:0}.toolbar+.page__background+.page__content ons-tabbar[status-bar-fill]>.tabbar--top__content{top:49px}.page__content>.list:not(.list--material):first-child{margin-top:-1px}.page--wrapper>.page__background{display:none}ons-action-sheet[disabled],ons-alert-dialog[disabled],ons-dialog[disabled],ons-popover[disabled]{pointer-events:none;opacity:.75}ons-list-item[disabled]{pointer-events:none}ons-range[disabled]{opacity:.3;pointer-events:none}ons-pull-hook{position:relative;display:block;margin:auto;text-align:center;z-index:20002}ons-splitter,ons-splitter-content,ons-splitter-mask,ons-splitter-side{display:block;position:absolute;left:0;right:0;top:0;bottom:0;box-sizing:border-box;z-index:0}ons-splitter-mask{z-index:4;background-color:rgba(0,0,0,.1);display:none;opacity:0}ons-splitter-content{z-index:2}ons-splitter-side{right:auto;z-index:2}ons-splitter-side[side=right]{right:0;left:auto}ons-splitter-side[mode=collapse]{z-index:5;left:auto;right:100%}ons-splitter-side[side=right][mode=collapse]{right:auto;left:100%}ons-splitter-side[mode=split]{z-index:3}ons-toolbar-button>ons-icon[icon*=ion-]{font-size:26px}ons-range,ons-select{display:inline-block}ons-range>input{min-width:50px;width:100%}ons-select>select{width:100%}ons-carousel[disabled]{pointer-events:none;opacity:.75}ons-carousel[fullscreen]{height:100%}.ons-status-bar-mock{position:absolute;width:100%;height:20px;padding:0 16px 0 6px;z-index:30000;display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;font-size:12px;line-height:20px;font-family:Arial,Helvetica}.ons-status-bar-mock i{padding:0 2px}.ons-status-bar-mock.android{color:#fff;background-color:#222;font-family:Roboto,Arial,Helvetica}.ons-status-bar-mock.android~*{top:20px;bottom:0;position:inherit;width:100%}.ons-ios-scroll-fix .page:not(.page--wrapper)[shown]>.page__content{overflow-y:hidden}.ons-ios-scroll-fix ons-splitter-side>.page:not(.page--wrapper)[shown]>.page__content{overflow-y:auto}ons-row{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-moz-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;width:100%}ons-row[align=top],ons-row[vertical-align=top]{-webkit-box-align:start;box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;-moz-align-items:flex-start;align-items:flex-start}ons-row[align=bottom],ons-row[vertical-align=bottom]{-webkit-box-align:end;box-align:end;-ms-flex-align:end;-webkit-align-items:flex-end;-moz-align-items:flex-end;align-items:flex-end}ons-row[align=center],ons-row[vertical-align=center]{-webkit-box-align:center;box-align:center;-ms-flex-align:center;-webkit-align-items:center;-moz-align-items:center;align-items:center;text-align:inherit}ons-row+ons-row{padding-top:0}ons-col{-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-moz-flex:1;-ms-flex:1;flex:1;display:block;width:100%}ons-col[align=top],ons-col[vertical-align=top]{-webkit-align-self:flex-start;-moz-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}ons-col[align=bottom],ons-col[vertical-align=bottom]{-webkit-align-self:flex-end;-moz-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}ons-col[align=center],ons-col[vertical-align=center]{-webkit-align-self:center;-moz-align-self:center;-ms-flex-item-align:center;text-align:inherit}.ons-icon{display:inline-block;line-height:inherit;font-style:normal;font-weight:400;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.segment__button .ons-icon{line-height:initial}:not(ons-toolbar-button):not(ons-action-sheet-button):not(.segment__button)>.ons-icon--ion{line-height:.75em;vertical-align:-25%}.ons-icon[spin]{-webkit-animation:ons-icon-spin 2s infinite linear;-moz-animation:ons-icon-spin 2s infinite linear;animation:ons-icon-spin 2s infinite linear}@-moz-keyframes ons-icon-spin{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes ons-icon-spin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(359deg)}}@keyframes ons-icon-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.ons-icon[rotate="90"]{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);transform:rotate(90deg)}.ons-icon[rotate="180"]{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);transform:rotate(180deg)}.ons-icon[rotate="270"]{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);transform:rotate(270deg)}.ons-icon[fixed-width]{width:1.28571429em;text-align:center}.ons-icon--lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.ons-icon--2x{font-size:2em}.ons-icon--3x{font-size:3em}.ons-icon--4x{font-size:4em}.ons-icon--5x{font-size:5em}ons-checkbox,ons-input,ons-radio,ons-search-input{display:inline-block;position:relative}.ripple,.ripple__wave{position:absolute}ons-input .text-input,ons-search-input .search-input{width:100%;display:inline-block}ons-input .text-input__label:not(.text-input--material__label),ons-input:not([float]) .text-input--material__label--active{display:none}ons-checkbox[disabled],ons-input[disabled],ons-radio[disabled],ons-search-input[disabled],ons-segment[disabled]{opacity:.5;pointer-events:none}ons-input input.text-input--material::-webkit-input-placeholder{color:transparent}ons-input input.text-input--material::-moz-placeholder{color:transparent}ons-input input.text-input--material:-ms-input-placeholder{color:transparent}@media (orientation:landscape){html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content{padding-right:0}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content{padding-left:0}html[onsflag-iphonex-landscape] .page__content>ons-progress-bar>.progress-bar{margin-left:-44px;margin-right:-44px;width:calc(100% + 88px)}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content>.list:not(.list--inset){margin-left:0}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content>.list:not(.list--inset)>.list-header{padding-left:15px}html[onsflag-iphonex-landscape] ons-splitter-side[side=right] .page__content>.list:not(.list--inset)>.list-item{padding-left:14px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset){margin-right:0}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item--chevron:before{right:16px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item>.list-item__center:last-child{padding-right:6px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item>.list-item__right{padding-right:12px}html[onsflag-iphonex-landscape] ons-splitter-side[side=left] .page__content>.list:not(.list--inset)>.list-item>.list-item--chevron__right{padding-right:30px}}.ons-swiper-blocker,.ripple,.ripple__background{top:0;bottom:0;left:0;right:0;pointer-events:none}ons-progress-bar{display:block}ons-progress-circular{display:inline-block;width:32px;height:32px}.ons-swiper,.ripple{overflow:hidden;display:block}ons-progress-circular>svg.progress-circular{width:100%;height:100%}.ripple__background{background:rgba(255,255,255,.2);position:absolute;opacity:0}.ripple__wave{background:rgba(255,255,255,.2);width:0;height:0;border-radius:50%;top:0;left:0;z-index:0;pointer-events:none}.button--material--flat .ripple__background,.button--material--flat .ripple__wave,.ripple--light-gray__background,.ripple--light-gray__wave,ons-list-item .ripple__background,ons-list-item .ripple__wave{background:rgba(189,189,189,.3)}.ons-swiper-target{display:-webkit-box;display:-webkit-flex;display:flex;height:100%;z-index:1;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;flex-direction:row}.ons-swiper-target--vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;flex-direction:column}.ons-swiper-target>*{height:inherit;-webkit-flex-shrink:0;flex-shrink:0;width:100%;position:relative!important}.ons-swiper-target.active:not(.swiping)>.page:not([shown]){visibility:hidden}.ons-swiper-tabbar .tabbar--material__button:after{display:none}.ons-swiper-blocker{display:block;position:absolute} \ No newline at end of file diff --git a/old_frontend/lib/css/valetudo-map.css b/old_frontend/lib/css/valetudo-map.css deleted file mode 100644 index 83ddacd3..00000000 --- a/old_frontend/lib/css/valetudo-map.css +++ /dev/null @@ -1,40 +0,0 @@ -/*Light theme for valetudo map. See dark-valetudo-map.css for corresponding dark theme*/ -:root { - --map-background-1: #efeff4; - --map-background-2: #afafaf; - --map-free: #0076ff; - --map-occupied: #333333; - --path: #ffffff; -} - -.map-page-container { - height: 100%; - width: 100%; - display: grid; - grid-template-columns: 1fr; - grid-template-rows: auto 1fr; - justify-items: stretch; - align-items: stretch; -} - -canvas#map-canvas { - height: 100%; - width: 100%; - touch-action: none; - background-image: linear-gradient(var(--map-background-1), var(--map-background-2)); -} - -.map-page-buttons { - position: absolute; - right: 1.5em; - bottom: 1.5em; - display: grid; - grid-template-columns: auto; - grid-template-rows: auto; - grid-gap: 0.5em; -} - -.map-page-buttons > ons-fab { - background-color: #ffffff; - color: #31313a; -} diff --git a/old_frontend/lib/donate.html b/old_frontend/lib/donate.html deleted file mode 100644 index 44e31b45..00000000 --- a/old_frontend/lib/donate.html +++ /dev/null @@ -1,23 +0,0 @@ - diff --git a/old_frontend/lib/forbidden-markers-configuration-map.html b/old_frontend/lib/forbidden-markers-configuration-map.html deleted file mode 100644 index 9e17f361..00000000 --- a/old_frontend/lib/forbidden-markers-configuration-map.html +++ /dev/null @@ -1,73 +0,0 @@ - -
-
- Forbidden Markers - -
- - - -
- -
- - - - - - - - - - -
- - - -
diff --git a/old_frontend/lib/forbidden-markers-configuration-map.js b/old_frontend/lib/forbidden-markers-configuration-map.js deleted file mode 100644 index 013f9a99..00000000 --- a/old_frontend/lib/forbidden-markers-configuration-map.js +++ /dev/null @@ -1,80 +0,0 @@ -/*global ons, fn*/ -import {VacuumMap} from "./js/js-modules/vacuum-map.js"; -import {ApiService} from "./services/api.service.js"; - -function markerConfigInit() { - const map = new VacuumMap(document.getElementById("forbidden-markers-configuration-map")); - const loadingBarSaveMarkers = document.getElementById("loading-bar-save-markers"); - const saveButton = document.getElementById("forbidden-markers-configuration-save"); - - - const topPage = fn.getTopPage(); - map.initCanvas(topPage.data.map, {metaData: false, noGotoPoints: true}); - window.fn.map = map; - const supportedVirtualRestrictions = topPage.data.supportedVirtualRestrictions; - - if (supportedVirtualRestrictions.supportedRestrictedZoneTypes.indexOf("mop") !== -1) { - document.getElementById("forbidden-markers-configuration-add-mop-zone").style.display = ""; - } - - const no_go_areas = topPage.data.map.entities.filter(e => e.type === "no_go_area"); - const no_mop_areas = topPage.data.map.entities.filter(e => e.type === "no_mop_area"); - const virtual_walls = topPage.data.map.entities.filter(e => e.type === "virtual_wall"); - - if (no_go_areas) { - no_go_areas.forEach(area => { - map.addForbiddenZone(area.points, true, true); - }); - } - if (no_mop_areas) { - no_mop_areas.forEach(area => { - map.addForbiddenMopZone(area.points, true, true); - }); - } - - if (virtual_walls) { - virtual_walls.forEach(wall => { - map.addVirtualWall(wall.points, true, true); - }); - } - - document.getElementById("forbidden-markers-configuration-map-page-h1").innerText = "Editing markers"; - - document.getElementById("forbidden-markers-configuration-add-wall").onclick = () => { - map.addVirtualWall(null, false, true); - }; - - document.getElementById("forbidden-markers-configuration-add-zone").onclick = () => { - map.addForbiddenZone(null, false, true); - }; - - document.getElementById("forbidden-markers-configuration-add-mop-zone").onclick = () => { - map.addForbiddenMopZone(null, false, true); - }; - - saveButton.onclick = async () => { - loadingBarSaveMarkers.setAttribute("indeterminate", "indeterminate"); - saveButton.setAttribute("disabled", "disabled"); - - try { - await ApiService.setPersistentData( - map.getLocations().virtualWalls, - map.getLocations().forbiddenZones, - map.getLocations().forbiddenMopZones - ); - await ons.notification.toast( - "Successfully saved forbidden markers!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout} - ); - - fn.popPage(); - } catch (err) { - ons.notification.toast(err.message, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSaveMarkers.removeAttribute("indeterminate"); - saveButton.removeAttribute("disabled"); - } - }; -} - -window.markerConfigInit = markerConfigInit; diff --git a/old_frontend/lib/global.d.ts b/old_frontend/lib/global.d.ts deleted file mode 100644 index c36872c7..00000000 --- a/old_frontend/lib/global.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare var ons: any; -declare var fn: any; diff --git a/old_frontend/lib/icon.png b/old_frontend/lib/icon.png deleted file mode 100644 index 262146b9..00000000 Binary files a/old_frontend/lib/icon.png and /dev/null differ diff --git a/old_frontend/lib/img/charger.png b/old_frontend/lib/img/charger.png deleted file mode 100644 index ad83a10b..00000000 Binary files a/old_frontend/lib/img/charger.png and /dev/null differ diff --git a/old_frontend/lib/img/robot.png b/old_frontend/lib/img/robot.png deleted file mode 100644 index 7107cd67..00000000 Binary files a/old_frontend/lib/img/robot.png and /dev/null differ diff --git a/old_frontend/lib/index.html b/old_frontend/lib/index.html deleted file mode 100644 index 4b0ddf1d..00000000 --- a/old_frontend/lib/index.html +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - - - - - - - - - - Valetudo - - - - - - - - - - - - - - - - - diff --git a/old_frontend/lib/index.js b/old_frontend/lib/index.js deleted file mode 100644 index d0b82e42..00000000 --- a/old_frontend/lib/index.js +++ /dev/null @@ -1,98 +0,0 @@ -/*global ons */ -window.fn = {}; - -window.fn.toggleMenu = function() { - document.getElementById("appSplitter").left.toggle(); - var themeSwitch = document.getElementById("theme-switch"); - themeSwitch.checked = window.fn.theme === "dark"; - themeSwitch.addEventListener("change", (event) => { - if (event.switch.checked) { - window.fn.theme = "dark"; - } else { - window.fn.theme = "light"; - } - if (event.isInteractive) { - window.localStorage.setItem("theme", window.fn.theme); - } - window.fn.applyTheme(); - }); -}; - -window.fn.loadView = function(index) { - document.getElementById("appTabbar").setActiveTab(index); - document.getElementById("sidemenu").close(); -}; - -window.fn.loadLink = function(url) { - window.open(url, "_blank"); -}; - -window.fn.pushPage = function(page, anim) { - if (anim) { - document.getElementById("appNavigator") - .pushPage(page.id, {data: {title: page.title, ...page.data}, animation: anim}); - } else { - document.getElementById("appNavigator").pushPage(page.id, { - data: {title: page.title, ...page.data} - }); - } - history.pushState({}, page.title); -}; - -window.fn.popPage = - function() { - document.getElementById("appNavigator").popPage(); - }; - -window.fn.getTopPage = - function() { - return document.getElementById("appNavigator").topPage; - }; - -window.fn.applyTheme = - function() { - let themeEl = document.getElementById("theme"); - let mapThemeEl = document.getElementById("map-theme"); - if (window.fn.theme === "dark") { - if (themeEl) { - themeEl.setAttribute("href", "css/dark-onsen-css-components.min.css"); - } - if (mapThemeEl) { - mapThemeEl.setAttribute("href", "css/dark-valetudo-map.css"); - } - } else { - if (themeEl) { - themeEl.setAttribute("href", "css/onsen-css-components.min.css"); - } - if (mapThemeEl) { - mapThemeEl.setAttribute("href", "css/valetudo-map.css"); - } - } - window.fn.updateMapPage && window.fn.updateMapPage(); - }; - -window.fn.toastErrorTimeout = 5e3; -window.fn.toastOKTimeout = 15e2; - -// TODO: Fix this routing mess -ons.ready(function() { - window.addEventListener("popstate", function(e) { - e.preventDefault(); - document.getElementById("appNavigator").popPage({}); - history.pushState(null, null, window.location.pathname); // What - // this is just broken - }, false); - window.fn.theme = window.localStorage.getItem("theme"); - if (window.fn.theme === null) { - if (matchMedia("(prefers-color-scheme: dark)").matches) { - window.fn.theme = "dark"; - } else { - window.fn.theme = "light"; - } - } - window.fn.applyTheme(); -}); - -if (ons.platform.isIPhoneX()) { - document.documentElement.setAttribute("onsflag-iphonex-portrait", ""); -} diff --git a/old_frontend/lib/js/MapFunctions.js b/old_frontend/lib/js/MapFunctions.js deleted file mode 100644 index a6cff9fa..00000000 --- a/old_frontend/lib/js/MapFunctions.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * General functions for Valetudo map operations. - * - * The functions here are used both on the server and the client. - * The source file resides in the client/js folder to facilitate deployment. - */ - -const MapFunctions = function() { - -}; - -/** - * Converts an index in the map array to coordinates. - * - * @param index index to convert - * @param width map width - * @param height map height - * @param size map entry size - * @returns {number[]} coordinates as an array [x,y] - */ - - -MapFunctions.mapIndexToMapCoord = function(index, width, height, size) { - let ridx = index / size; - let x = ridx % width; - return [x, (ridx - x) / width ]; -}; - -/** - * Converts coordinates to an index in the map array. - * This is the inverse of mapIndexToMapCoord. - * - * @param {number[]} coord coordinates as an array [x,y] - * @param {number} width map width - * @param {number} height map height - * @param {number} size map entry size - * @returns {number} the map array index for the coordinates - */ -MapFunctions.mapCoordToMapIndex = function(coord, width, height, size) { - return size * (coord[0] + coord[1] * width); -}; - -/** - * Generic function to apply a transformation function to coordinates. - * - * @param {Function} transform the transform function to invoke - * @param {number[]} coord coordinates as an array [x,y] - * @param {number} width map width - * @param {number} height map height - * @returns {any} the result of the transform function, coordinates as an array [x,y] - */ -MapFunctions.applyCoordTransform = function(transform, coord, width, height) { - return transform(coord, width, height); -}; - -/** - * Coordinate transformation function that flips the y coordinate. - * - * @param {number[]} coord coordinates as an array [x,y] - * @param {number} width map width - * @param {number} height map height - * @returns {number[]} coordinates coordinates as an array [x,y], where y is flipped. - */ -MapFunctions.TRANSFORM_COORD_FLIP_Y = function(coord, width, height) { - return [coord[0], height - coord[1] - 1]; -}; - -MapFunctions.logCoordToCanvasCoord = function(coord, flipY) { - let f = flipY ? -1 : 1; - let x = Math.round(2048 + coord[0] * 80); - let y = Math.round(2048 + coord[1] * f * 80); - return [x,y]; -}; - -MapFunctions.canvasCoordToLogCoord = function(coord, flipY) { - let f = flipY ? -1 : 1; - let x = (coord[0] - 2048) / 80; - let y = (coord[1] - 2048) / (f * 80); - return [x,y]; -}; - -MapFunctions.zoneCoordToLogCoord = function(coord) { - let zx = coord[0], zy = coord[1]; - // There seems to be an offset of 150 mm in both directions, - // i.e. goto (-1000, -1000) (zone coords) results in - // (0.850, 0.850) in log coords. - let lx = (-zx - 150) / 1000; - let ly = (-zy - 150) / 1000; - return [lx, ly]; -}; - -MapFunctions.logCoordToZoneCoord = function(coord) { - let lx = coord[0], ly = coord[1]; - let zx = -(Math.round(lx * 1000) + 150); - let zy = -(Math.round(ly * 1000) + 150); - return [zx, zy]; -}; - -MapFunctions.zoneCoordToCanvasCoord = function(coord, flipY) { - let lcoord = MapFunctions.zoneCoordToLogCoord(coord); - return MapFunctions.logCoordToCanvasCoord(lcoord, flipY); -}; - -MapFunctions.canvasCoordToZoneCoord = function(coord, flipY) { - let lcoord = MapFunctions.canvasCoordToLogCoord(coord, flipY); - return MapFunctions.logCoordToZoneCoord(lcoord); -}; - - -try { - // server-side only - module.exports = MapFunctions; -} catch (err) { - /* exception can be ignored on client */ -} diff --git a/old_frontend/lib/js/geometry-polyfill.js b/old_frontend/lib/js/geometry-polyfill.js deleted file mode 100644 index 74dc7f78..00000000 --- a/old_frontend/lib/js/geometry-polyfill.js +++ /dev/null @@ -1,715 +0,0 @@ -// MIT License - -// Copyright (c) 2018 Jarek Foksa - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// https://github.com/jarek-foksa/geometry-polyfill - -// @info -// DOMPoint polyfill -// @src -// https://drafts.fxtf.org/geometry/#DOMPoint -// https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/geometry/dom_point_read_only.cc -{ - class DOMPoint { - constructor(x = 0, y = 0, z = 0, w = 1) { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - static fromPoint(otherPoint) { - return new DOMPoint( - otherPoint.x, - otherPoint.y, - otherPoint.z !== undefined ? otherPoint.z : 0, - otherPoint.w !== undefined ? otherPoint.w : 1 - ); - } - - matrixTransform(matrix) { - if ( - (matrix.is2D || matrix instanceof SVGMatrix) && - this.z === 0 && - this.w === 1 - ) { - return new DOMPoint( - this.x * matrix.a + this.y * matrix.c + matrix.e, - this.x * matrix.b + this.y * matrix.d + matrix.f, - 0, 1 - ); - } - else { - return new DOMPoint( - this.x * matrix.m11 + this.y * matrix.m21 + this.z * matrix.m31 + this.w * matrix.m41, - this.x * matrix.m12 + this.y * matrix.m22 + this.z * matrix.m32 + this.w * matrix.m42, - this.x * matrix.m13 + this.y * matrix.m23 + this.z * matrix.m33 + this.w * matrix.m43, - this.x * matrix.m14 + this.y * matrix.m24 + this.z * matrix.m34 + this.w * matrix.m44 - ); - } - } - } - - window.DOMPoint = DOMPoint; - } - - // @info - // DOMRect polyfill - // @src - // https://drafts.fxtf.org/geometry/#DOMRect - // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/geometry/dom_rect_read_only.cc - { - class DOMRect { - constructor(x = 0, y = 0, width = 0, height = 0) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - static fromRect(otherRect) { - return new DOMRect(otherRect.x, otherRect.y, otherRect.width, otherRect.height); - } - - get top() { - return this.y; - } - - get left() { - return this.x; - } - - get right() { - return this.x + this.width; - } - - get bottom() { - return this.y + this.height; - } - } - - window.DOMRect = DOMRect; - } - - // @info - // DOMMatrix polyfill (SVG 2) - // @src - // https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/geometry/dom_matrix_read_only.cc - // https://github.com/tocharomera/generativecanvas/blob/master/node-canvas/lib/DOMMatrix.js - { - const M11 = 0, M12 = 1, M13 = 2, M14 = 3; - const M21 = 4, M22 = 5, M23 = 6, M24 = 7; - const M31 = 8, M32 = 9, M33 = 10, M34 = 11; - const M41 = 12, M42 = 13, M43 = 14, M44 = 15; - - const A = M11, B = M12; - const C = M21, D = M22; - const E = M41, F = M42; - - const DEGREE_PER_RAD = 180 / Math.PI; - const RAD_PER_DEGREE = Math.PI / 180; - - const $values = Symbol(); - const $is2D = Symbol(); - - let parseMatrix = (init) => { - let parsed = init.replace(/matrix\(/, ""); - parsed = parsed.split(/,/, 7); - - if (parsed.length !== 6) { - throw new Error(`Failed to parse ${init}`); - } - - parsed = parsed.map(parseFloat); - - return [ - parsed[0], parsed[1], 0, 0, - parsed[2], parsed[3], 0, 0, - 0, 0, 1, 0, - parsed[4], parsed[5], 0, 1 - ]; - }; - - let parseMatrix3d = (init) => { - let parsed = init.replace(/matrix3d\(/, ""); - parsed = parsed.split(/,/, 17); - - if (parsed.length !== 16) { - throw new Error(`Failed to parse ${init}`); - } - - return parsed.map(parseFloat); - }; - - let parseTransform = (tform) => { - let type = tform.split(/\(/, 1)[0]; - - if (type === "matrix") { - return parseMatrix(tform); - } - else if (type === "matrix3d") { - return parseMatrix3d(tform); - } - else { - throw new Error(`${type} parsing not implemented`) - } - }; - - let setNumber2D = (receiver, index, value) => { - if (typeof value !== "number") { - throw new TypeError("Expected number"); - } - - receiver[$values][index] = value; - }; - - let setNumber3D = (receiver, index, value) => { - if (typeof value !== "number") { - throw new TypeError("Expected number"); - } - - if (index === M33 || index === M44) { - if (value !== 1) { - receiver[$is2D] = false; - } - } - else if (value !== 0) { - receiver[$is2D] = false; - } - - receiver[$values][index] = value; - }; - - let newInstance = (values) => { - let instance = Object.create(DOMMatrix.prototype); - instance.constructor = DOMMatrix; - instance[$is2D] = true; - instance[$values] = values; - - return instance; - }; - - let multiply = (first, second) => { - let dest = new Float64Array(16); - - for (let i = 0; i < 4; i++) { - for (let j = 0; j < 4; j++) { - let sum = 0; - - for (let k = 0; k < 4; k++) { - sum += first[i * 4 + k] * second[k * 4 + j]; - } - - dest[i * 4 + j] = sum; - } - } - - return dest; - }; - - class DOMMatrix { - get m11() { return this[$values][M11]; } set m11(value) { setNumber2D(this, M11, value); } - get m12() { return this[$values][M12]; } set m12(value) { setNumber2D(this, M12, value); } - get m13() { return this[$values][M13]; } set m13(value) { setNumber3D(this, M13, value); } - get m14() { return this[$values][M14]; } set m14(value) { setNumber3D(this, M14, value); } - get m21() { return this[$values][M21]; } set m21(value) { setNumber2D(this, M21, value); } - get m22() { return this[$values][M22]; } set m22(value) { setNumber2D(this, M22, value); } - get m23() { return this[$values][M23]; } set m23(value) { setNumber3D(this, M23, value); } - get m24() { return this[$values][M24]; } set m24(value) { setNumber3D(this, M24, value); } - get m31() { return this[$values][M31]; } set m31(value) { setNumber3D(this, M31, value); } - get m32() { return this[$values][M32]; } set m32(value) { setNumber3D(this, M32, value); } - get m33() { return this[$values][M33]; } set m33(value) { setNumber3D(this, M33, value); } - get m34() { return this[$values][M34]; } set m34(value) { setNumber3D(this, M34, value); } - get m41() { return this[$values][M41]; } set m41(value) { setNumber2D(this, M41, value); } - get m42() { return this[$values][M42]; } set m42(value) { setNumber2D(this, M42, value); } - get m43() { return this[$values][M43]; } set m43(value) { setNumber3D(this, M43, value); } - get m44() { return this[$values][M44]; } set m44(value) { setNumber3D(this, M44, value); } - - get a() { return this[$values][A]; } set a(value) { setNumber2D(this, A, value); } - get b() { return this[$values][B]; } set b(value) { setNumber2D(this, B, value); } - get c() { return this[$values][C]; } set c(value) { setNumber2D(this, C, value); } - get d() { return this[$values][D]; } set d(value) { setNumber2D(this, D, value); } - get e() { return this[$values][E]; } set e(value) { setNumber2D(this, E, value); } - get f() { return this[$values][F]; } set f(value) { setNumber2D(this, F, value); } - - get is2D() { - return this[$is2D]; - } - - get isIdentity() { - let values = this[$values]; - - return values[M11] === 1 && values[M12] === 0 && values[M13] === 0 && values[M14] === 0 && - values[M21] === 0 && values[M22] === 1 && values[M23] === 0 && values[M24] === 0 && - values[M31] === 0 && values[M32] === 0 && values[M33] === 1 && values[M34] === 0 && - values[M41] === 0 && values[M42] === 0 && values[M43] === 0 && values[M44] === 1; - } - - static fromMatrix(init) { - if (init instanceof DOMMatrix) { - return new DOMMatrix(init[$values]); - } - else if (init instanceof SVGMatrix) { - return new DOMMatrix([init.a, init.b, init.c, init.d, init.e, init.f]); - } - else { - throw new TypeError("Expected DOMMatrix"); - } - } - - static fromFloat32Array(init) { - if (!(init instanceof Float32Array)) throw new TypeError("Expected Float32Array"); - return new DOMMatrix(init); - } - - static fromFloat64Array(init) { - if (!(init instanceof Float64Array)) throw new TypeError("Expected Float64Array"); - return new DOMMatrix(init); - } - - // @type - // (Float64Array) => void - constructor(init) { - this[$is2D] = true; - - this[$values] = new Float64Array([ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ]); - - // Parse CSS transformList - if (typeof init === "string") { - if (init === "") { - return; - } - else { - let tforms = init.split(/\)\s+/, 20).map(parseTransform); - - if (tforms.length === 0) { - return; - } - - init = tforms[0]; - - for (let i = 1; i < tforms.length; i++) { - init = multiply(tforms[i], init); - } - } - } - - let i = 0; - - if (init && init.length === 6) { - setNumber2D(this, A, init[i++]); - setNumber2D(this, B, init[i++]); - setNumber2D(this, C, init[i++]); - setNumber2D(this, D, init[i++]); - setNumber2D(this, E, init[i++]); - setNumber2D(this, F, init[i++]); - } - else if (init && init.length === 16) { - setNumber2D(this, M11, init[i++]); - setNumber2D(this, M12, init[i++]); - setNumber3D(this, M13, init[i++]); - setNumber3D(this, M14, init[i++]); - setNumber2D(this, M21, init[i++]); - setNumber2D(this, M22, init[i++]); - setNumber3D(this, M23, init[i++]); - setNumber3D(this, M24, init[i++]); - setNumber3D(this, M31, init[i++]); - setNumber3D(this, M32, init[i++]); - setNumber3D(this, M33, init[i++]); - setNumber3D(this, M34, init[i++]); - setNumber2D(this, M41, init[i++]); - setNumber2D(this, M42, init[i++]); - setNumber3D(this, M43, init[i++]); - setNumber3D(this, M44, init[i]); - } - else if (init !== undefined) { - throw new TypeError("Expected string or array."); - } - } - - inspect(depth, options) { - if (depth < 0) { - return "[DOMMatrix]"; - } - - return `DOMMatrix [ - a: ${this.a} - b: ${this.b} - c: ${this.c} - d: ${this.d} - e: ${this.e} - f: ${this.f} - m11: ${this.m11} - m12: ${this.m12} - m13: ${this.m13} - m14: ${this.m14} - m21: ${this.m21} - m22: ${this.m22} - m23: ${this.m23} - m23: ${this.m23} - m31: ${this.m31} - m32: ${this.m32} - m33: ${this.m33} - m34: ${this.m34} - m41: ${this.m41} - m42: ${this.m42} - m43: ${this.m43} - m44: ${this.m44} - is2D: ${this.is2D} - isIdentity: ${this.isIdentity} ]`; - } - - multiply(other) { - return newInstance(this[$values]).multiplySelf(other); - } - - multiplySelf(other) { - this[$values] = multiply(other[$values], this[$values]); - - if (!other.is2D) { - this[$is2D] = false; - } - - return this; - } - - preMultiplySelf(other) { - this[$values] = multiply(this[$values], other[$values]); - - if (!other.is2D) { - this[$is2D] = false; - } - - return this; - } - - translate(tx, ty, tz) { - return newInstance(this[$values]).translateSelf(tx, ty, tz); - } - - translateSelf(tx = 0, ty = 0, tz = 0) { - this[$values] = multiply([ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - tx, ty, tz, 1 - ], this[$values]); - - if (tz !== 0) { - this[$is2D] = false; - } - - return this; - } - - scale(scaleX, scaleY, scaleZ, originX, originY, originZ) { - return newInstance(this[$values]).scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ); - } - - scale3d(scale, originX, originY, originZ) { - return newInstance(this[$values]).scale3dSelf(scale, originX, originY, originZ); - } - - scale3dSelf(scale, originX, originY, originZ) { - return this.scaleSelf(scale, scale, scale, originX, originY, originZ); - } - - scaleSelf(scaleX, scaleY, scaleZ, originX, originY, originZ) { - // Not redundant with translate's checks because we need to negate the values later. - if (typeof originX !== "number") originX = 0; - if (typeof originY !== "number") originY = 0; - if (typeof originZ !== "number") originZ = 0; - - this.translateSelf(originX, originY, originZ); - - if (typeof scaleX !== "number") scaleX = 1; - if (typeof scaleY !== "number") scaleY = scaleX; - if (typeof scaleZ !== "number") scaleZ = 1; - - this[$values] = multiply([ - scaleX, 0, 0, 0, - 0, scaleY, 0, 0, - 0, 0, scaleZ, 0, - 0, 0, 0, 1 - ], this[$values]); - - this.translateSelf(-originX, -originY, -originZ); - - if (scaleZ !== 1 || originZ !== 0) { - this[$is2D] = false; - } - - return this; - } - - rotateFromVector(x, y) { - return newInstance(this[$values]).rotateFromVectorSelf(x, y); - } - - rotateFromVectorSelf(x = 0, y = 0) { - let theta = (x === 0 && y === 0) ? 0 : Math.atan2(y, x) * DEGREE_PER_RAD; - return this.rotateSelf(theta); - } - - rotate(rotX, rotY, rotZ) { - return newInstance(this[$values]).rotateSelf(rotX, rotY, rotZ); - } - - rotateSelf(rotX, rotY, rotZ) { - if (rotY === undefined && rotZ === undefined) { - rotZ = rotX; - rotX = rotY = 0; - } - - if (typeof rotY !== "number") rotY = 0; - if (typeof rotZ !== "number") rotZ = 0; - - if (rotX !== 0 || rotY !== 0) { - this[$is2D] = false; - } - - rotX *= RAD_PER_DEGREE; - rotY *= RAD_PER_DEGREE; - rotZ *= RAD_PER_DEGREE; - - let c = Math.cos(rotZ); - let s = Math.sin(rotZ); - - this[$values] = multiply([ - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ], this[$values]); - - c = Math.cos(rotY); - s = Math.sin(rotY); - - this[$values] = multiply([ - c, 0, -s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1 - ], this[$values]); - - c = Math.cos(rotX); - s = Math.sin(rotX); - - this[$values] = multiply([ - 1, 0, 0, 0, - 0, c, s, 0, - 0, -s, c, 0, - 0, 0, 0, 1 - ], this[$values]); - - return this; - } - - rotateAxisAngle(x, y, z, angle) { - return newInstance(this[$values]).rotateAxisAngleSelf(x, y, z, angle); - } - - rotateAxisAngleSelf(x = 0, y = 0, z = 0, angle = 0) { - let length = Math.sqrt(x * x + y * y + z * z); - - if (length === 0) { - return this; - } - - if (length !== 1) { - x /= length; - y /= length; - z /= length; - } - - angle *= RAD_PER_DEGREE; - - let c = Math.cos(angle); - let s = Math.sin(angle); - let t = 1 - c; - let tx = t * x; - let ty = t * y; - - this[$values] = multiply([ - tx * x + c, tx * y + s * z, tx * z - s * y, 0, - tx * y - s * z, ty * y + c, ty * z + s * x, 0, - tx * z + s * y, ty * z - s * x, t * z * z + c, 0, - 0, 0, 0, 1 - ], this[$values]); - - if (x !== 0 || y !== 0) { - this[$is2D] = false; - } - - return this; - } - - skewX(sx) { - return newInstance(this[$values]).skewXSelf(sx); - } - - skewXSelf(sx) { - if (typeof sx !== "number") { - return this; - } - - let t = Math.tan(sx * RAD_PER_DEGREE); - - this[$values] = multiply([ - 1, 0, 0, 0, - t, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ], this[$values]); - - return this; - } - - skewY(sy) { - return newInstance(this[$values]).skewYSelf(sy); - } - - skewYSelf(sy) { - if (typeof sy !== "number") { - return this; - } - - let t = Math.tan(sy * RAD_PER_DEGREE); - - this[$values] = multiply([ - 1, t, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ], this[$values]); - - return this; - } - - flipX() { - return newInstance(multiply([ - -1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ], this[$values])); - } - - flipY() { - return newInstance(multiply([ - 1, 0, 0, 0, - 0, -1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ], this[$values])); - } - - inverse () { - return newInstance(this[$values]).invertSelf(); - } - - invertSelf() { - if (this[$is2D]) { - let det = this[$values][A] * this[$values][D] - this[$values][B] * this[$values][C]; - - // Invertable - if (det !== 0) { - let result = new DOMMatrix(); - - result.a = this[$values][D] / det; - result.b = -this[$values][B] / det; - result.c = -this[$values][C] / det; - result.d = this[$values][A] / det; - result.e = (this[$values][C] * this[$values][F] - this[$values][D] * this[$values][E]) / det; - result.f = (this[$values][B] * this[$values][E] - this[$values][A] * this[$values][F]) / det; - - return result; - } - - // Not invertable - else { - this[$is2D] = false; - - this[$values] = [ - NaN, NaN, NaN, NaN, - NaN, NaN, NaN, NaN, - NaN, NaN, NaN, NaN, - NaN, NaN, NaN, NaN - ]; - } - } - else { - throw new Error("3D matrix inversion is not implemented."); - } - } - - setMatrixValue(transformList) { - let temp = new DOMMatrix(transformList); - - this[$values] = temp[$values]; - this[$is2D] = temp[$is2D]; - - return this; - } - - transformPoint(point) { - point = new DOMPoint(point); - - let x = point.x; - let y = point.y; - let z = point.z; - let w = point.w; - - let values = this[$values]; - - let nx = values[M11] * x + values[M21] * y + values[M31] * z + values[M41] * w; - let ny = values[M12] * x + values[M22] * y + values[M32] * z + values[M42] * w; - let nz = values[M13] * x + values[M23] * y + values[M33] * z + values[M43] * w; - let nw = values[M14] * x + values[M24] * y + values[M34] * z + values[M44] * w; - - return new DOMPoint(nx, ny, nz, nw); - } - - toFloat32Array() { - return Float32Array.from(this[$values]); - } - - toFloat64Array() { - return this[$values].slice(0); - } - - toString() { - if (this.is2D) { - return `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.e}, ${this.f})`; - } - else { - return `matrix3d(${this[$values].join(", ")})`; - } - } - } - - window.DOMMatrix = DOMMatrix; - } \ No newline at end of file diff --git a/old_frontend/lib/js/js-modules/locations.js b/old_frontend/lib/js/js-modules/locations.js deleted file mode 100644 index 5340bfcc..00000000 --- a/old_frontend/lib/js/js-modules/locations.js +++ /dev/null @@ -1,1131 +0,0 @@ -/** - * The idea behind "locations" (for lack of a better term) - * is that we can manage multiple goto points / zones or in the future nogo areas etc. - * - * They include the drawing logic (draw function) which is called by the vacuum-map, - * and can define hooks for user-interaction such as tapping or panning. - */ - -const robot = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_robot = new Image(); -img_robot.src = robot; - -const charger = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_charger = new Image(); -img_charger.src = charger; - -const delete_button = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_delete_button = new Image(); -img_delete_button.src = delete_button; - -const scale_button = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGNpcmNsZSBjeD0iMTYuMDA2IiBjeT0iMTYuMDA2IiByPSIxNC45NDYiIGZpbGw9IiM3ZjdmN2YiIHN0cm9rZT0iIzMzMyIgc3Ryb2tlLXdpZHRoPSIyLjEwODciLz4KIDxnIHRyYW5zZm9ybT0ibWF0cml4KC00LjMyODQgLTQuMzI4NCA0LjMyODQgLTQuMzI4NCAtMzYuMTM0IC0xNS40NzEpIiBmaWxsPSIjMzMzIj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtLjAxMDgxNCAtLjAwMzA5MzEpIj4KICAgPHBhdGggZD0ibS03LjUwMTIgMi4zODk5LTAuNzY2OTYgMC40NDI4di0wLjg4NTZsMC4zODM0OCAwLjIyMTR6Ii8+CiAgIDxwYXRoIHRyYW5zZm9ybT0ic2NhbGUoLTEsMSkiIGQ9Im0xMS43OTggMi4zODk5LTAuNzY2OTYgMC40NDI4di0wLjg4NTZsMC4zODM0OCAwLjIyMTR6Ii8+CiAgPC9nPgogIDxyZWN0IHg9Ii0xMS40MDYiIHk9IjIuMTUzOCIgd2lkdGg9IjMuNDkwNyIgaGVpZ2h0PSIuNDY2MiIvPgogPC9nPgo8L3N2Zz4K"; -const img_scale_button = new Image(); -img_scale_button.src = scale_button; - -const move_button = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_move_button = new Image(); -img_move_button.src = move_button; - -const marker = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" \n"); -const img_marker = new Image(); -img_marker.src = marker; - -const marker_active = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_marker_active = new Image(); -img_marker_active.src = marker_active; - -const segment = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_segment = new Image(); -img_segment.src = segment; - -const segment_active = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(" "); -const img_segment_active = new Image(); -img_segment_active.src = segment_active; - - -export class Robot { - constructor(x ,y, angle) { - this.x = x; - this.y = y; - this.angle = angle; - } - - draw(ctx, transformFromMapSpace, scaleFactor) { - const p1 = new DOMPoint(this.x, this.y).matrixTransform(transformFromMapSpace); - - function rotateRobot(img, scaledSize, angle) { - var canvasimg = document.createElement("canvas"); - canvasimg.width = scaledSize.width; - canvasimg.height = scaledSize.height; - var ctximg = canvasimg.getContext("2d"); - ctximg.clearRect(0, 0, scaledSize.width, scaledSize.height); - ctximg.translate(scaledSize.width / 2, scaledSize.width / 2); - ctximg.rotate(angle * Math.PI / 180); - ctximg.translate(-scaledSize.width / 2, -scaledSize.width / 2); - ctximg.drawImage(img, 0, 0, scaledSize.width, scaledSize.height); - return canvasimg; - } - - const scaledSize = { - width: Math.max(img_robot.width / (4.5 / scaleFactor), img_robot.width), - height: Math.max(img_robot.height / (4.5 / scaleFactor), img_robot.height) - }; - - ctx.drawImage( - rotateRobot(img_robot, scaledSize, this.angle), - p1.x - scaledSize.width / 2, - p1.y - scaledSize.height / 2, - scaledSize.width, - scaledSize.height - ); - } -} - -export class Charger { - constructor(x ,y) { - this.x = x; - this.y = y; - } - - draw(ctx, transformFromMapSpace, scaleFactor) { - const p1 = new DOMPoint(this.x, this.y).matrixTransform(transformFromMapSpace); - - const scaledSize = { - width: Math.max(img_charger.width / (4.5 / scaleFactor), img_charger.width), - height: Math.max(img_charger.height / (4.5 / scaleFactor), img_charger.height) - }; - - ctx.drawImage( - img_charger, - p1.x - scaledSize.width / 2, - p1.y - scaledSize.height / 2, - scaledSize.width, - scaledSize.height - ); - } -} - -/** - * Represents a point the robot can be sent to. - */ -export class GotoPoint { - - constructor(x ,y) { - this.x = x; - this.y = y; - } - - draw(ctx, transformFromMapSpace) { - const p1 = new DOMPoint(this.x, this.y).matrixTransform(transformFromMapSpace); - - ctx.drawImage( - img_marker, - p1.x - img_marker.width / 2, - p1.y - img_marker.height - ); - } - - toZone(x2, y2) { - return new Zone(this.x, this.y, x2, y2); - } -} - -/** - * Represents a zone for zoned_cleanup. - */ -export class Zone { - - constructor(x1 ,y1, x2, y2) { - this.buttonSize = 30; - - this.active = true; - this.isResizing = false; - - this.x1 = Math.min(x1, x2); - this.x2 = Math.max(x1, x2); - - this.y1 = Math.min(y1, y2); - this.y2 = Math.max(y1, y2); - } - - draw(ctx, transformMapToScreenSpace, scaleFactor) { - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const dimensions = { //TODO: why do I have to divide these by 2? - x: (Math.round(this.x2) - Math.round(this.x1)) / 20, - y: (Math.round(this.y2) - Math.round(this.y1)) / 20 - }; - const label = dimensions.x.toFixed(1) + " x " + dimensions.y.toFixed(1) + "m"; - - - - ctx.save(); - if (!this.active) { - ctx.strokeStyle = "rgb(255, 255, 255)"; - ctx.fillStyle = "rgba(255, 255, 255, 0.4)"; - } else { - ctx.setLineDash([15, 5]); - ctx.strokeStyle = "rgb(255, 255, 255)"; - ctx.fillStyle = "rgba(255, 255, 255, 0)"; - } - - ctx.lineWidth = 2; - ctx.fillRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y); - ctx.strokeRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y); - ctx.restore(); - - ctx.save(); - ctx.textAlign = "start"; - ctx.fillStyle = "rgba(255, 255, 255, 1)"; - ctx.font = Math.round(6 * scaleFactor).toString(10) + "px sans-serif"; - ctx.fillText(label, p1.x, p1.y - 4); - ctx.strokeText(label, p1.x, p1.y - 4); - - ctx.restore(); - - if (this.active) { - ctx.drawImage( - img_delete_button, - p2.x - img_delete_button.width / 2, - p1.y - img_delete_button.height / 2 - ); - - ctx.drawImage( - img_scale_button, - p2.x - img_scale_button.width / 2, - p2.y - img_scale_button.height / 2 - ); - } - } - - /** - * This is handler is called on each endTranslate. - * It allows us to do post-processing such as snapping - */ - postProcess() { - this.x1 = Math.round(this.x1); - this.y1 = Math.round(this.y1); - - this.x2 = Math.round(this.x2); - this.y2 = Math.round(this.y2); - - this.x3 = Math.round(this.x3); - this.y3 = Math.round(this.y3); - - this.x4 = Math.round(this.x4); - this.y4 = Math.round(this.y4); - } - - /** - * Handler for intercepting tap events on the canvas - * Used for activating / deleting the zone - * - * @param {{x: number, y: number}} tappedPoint - The tapped point in screen coordinates - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - tap(tappedPoint, transformMapToScreenSpace) { - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p2.x, 2) + Math.pow(tappedPoint.y - p1.y, 2) - ); - - if (this.active && distanceFromDelete <= this.buttonSize / 2) { - return { - updatedLocation: null, - stopPropagation: true - }; - } else if ( - tappedPoint.x >= p1.x && - tappedPoint.x <= p2.x && - tappedPoint.y >= p1.y && - tappedPoint.y <= p2.y - ) { - this.active = true; - - return { - updatedLocation: this, - stopPropagation: false - }; - } else { - this.active = false; - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } - - /** - * Handler for intercepting pan events on the canvas - * Used for resizing / moving the zone - * - * @param {{x: number, y: number}} start - The coordinates where the panning started - * @param {{x: number, y: number}} last - The coordinates from the last call - * @param {{x: number, y: number}} current - The current coordinates of the pointer - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - translate(start, last, current, transformMapToScreenSpace) { - if (this.active) { - const transformCanvasToMapSpace = transformMapToScreenSpace.inverse(); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - - const distanceFromResize = Math.sqrt( - Math.pow(last.x - p2.x, 2) + Math.pow(last.y - p2.y, 2) - ); - if (!this.isResizing && distanceFromResize <= this.buttonSize / 2) { - this.isResizing = true; - } - - const lastInMapSpace = new DOMPoint(last.x, last.y).matrixTransform(transformCanvasToMapSpace); - const currentInMapSpace = new DOMPoint(current.x, current.y).matrixTransform(transformCanvasToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; - - if (this.isResizing) { - if (currentInMapSpace.x > this.x1 + 5 && this.x2 + dx > this.x1 + 5) { - this.x2 += dx; - } - if (currentInMapSpace.y > this.y1 + 5 && this.y2 + dy > this.y1 + 5) { - this.y2 += dy; - } - - return { - updatedLocation: this, - stopPropagation: true - }; - } else if ( - last.x >= p1.x && - last.x <= p2.x && - last.y >= p1.y && - last.y <= p2.y - ) { - this.x1 += dx; - this.y1 += dy; - this.x2 += dx; - this.y2 += dy; - - return { - updatedLocation: this, - stopPropagation: true - }; - } else { - this.active = false; - } - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } -} - -/** - * Current goto target point - */ -export class GotoTarget { - - constructor(x ,y) { - this.x = x; - this.y = y; - } - - draw(ctx, transformFromMapSpace) { - const p1 = new DOMPoint(this.x, this.y).matrixTransform(transformFromMapSpace); - - - ctx.drawImage( - img_marker_active, - p1.x - img_marker_active.width / 2, - p1.y - img_marker_active.height / 2 - ); - } -} - -/** - * Represents the currently cleaned zone - */ -export class CurrentCleaningZone { - - /** - * @param {DOMPoint} p1 - * @param {DOMPoint} p2 - */ - constructor(p1, p2) { - this.p1 = p1; - this.p2 = p2; - } - - draw(ctx, transformFromMapSpace) { - const p1Screen = this.p1.matrixTransform(transformFromMapSpace); - const p2Screen = this.p2.matrixTransform(transformFromMapSpace); - - ctx.save(); - ctx.strokeStyle = "rgb(53, 145, 26)"; - ctx.fillStyle = "rgba(107, 244, 66, 0.3)"; - - ctx.lineWidth = 2; - ctx.fillRect(p1Screen.x, p1Screen.y, p2Screen.x - p1Screen.x, p2Screen.y - p1Screen.y); - ctx.strokeRect(p1Screen.x, p1Screen.y, p2Screen.x - p1Screen.x, p2Screen.y - p1Screen.y); - - ctx.restore(); - } -} - -/** - * Represents a virtual wall the robot does not pass - */ -export class VirtualWall { - - constructor(x1 ,y1, x2, y2, editable) { - this.editable = editable || false; - - if (editable) { - this.active = true; - this.buttonSize = 30; - } else { - this.active = false; - } - - this.x1 = x1; - this.x2 = x2; - - this.y1 = y1; - this.y2 = y2; - } - - draw(ctx, transformFromMapSpace) { - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformFromMapSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformFromMapSpace); - - ctx.save(); - ctx.beginPath(); - ctx.lineWidth = 5; - ctx.lineCap = "round"; - ctx.strokeStyle = "red"; - if (this.editable && this.active) { - ctx.setLineDash([8, 6]); - } - ctx.moveTo(p1.x, p1.y); - ctx.lineTo(p2.x, p2.y); - ctx.strokeStyle = "red"; - ctx.stroke(); - - ctx.restore(); - - if (this.active) { - ctx.drawImage( - img_delete_button, - p1.x - img_delete_button.width / 2, - p1.y - img_delete_button.height / 2 - ); - - ctx.drawImage( - img_move_button, - p2.x - img_move_button.width / 2, - p2.y - img_move_button.height / 2 - ); - } - if (this.editable) { - this.matrix = new DOMMatrix().rotateFromVectorSelf(p2.y - p1.y,p2.x - p1.x); - this.sp1 = p1.matrixTransform(new DOMMatrix().translate(-10).rotateFromVectorSelf(p2.y - p1.y,p2.x - p1.x)); - this.sp2 = p2.matrixTransform(new DOMMatrix().translate(+10).rotateFromVectorSelf(p2.y - p1.y,p2.x - p1.x)); - } - } - - /** - * This is handler is called on each endTranslate. - * It allows us to do post-processing such as snapping - */ - postProcess() { - this.x1 = Math.round(this.x1); - this.y1 = Math.round(this.y1); - - const deltaY = Math.abs(this.y1 - this.y2); - const deltaX = Math.abs(this.x1 - this.x2); - const distance = Math.round(Math.hypot(deltaX, deltaY)); - - const angle = Math.atan2(deltaY, deltaX) * 180/Math.PI; - const newAngle = (Math.round(angle/5)*5); - - let xOffset = distance * Math.cos(newAngle * Math.PI/180); - let yOffset = distance * Math.sin(newAngle * Math.PI/180); - - - if (this.x1 > this.x2) { - xOffset = xOffset * -1; - } - - if (this.y1 > this.y2) { - yOffset = yOffset * -1; - } - - this.x2 = this.x1 + xOffset; - this.y2 = this.y1 + yOffset; - } - - /** - * Handler for intercepting tap events on the canvas - * Used for activating / deleting the wall - * - * @param {{x: number, y: number}} tappedPoint - The tapped point in screen coordinates - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - tap(tappedPoint, transformMapToScreenSpace) { - if (!this.editable) { - return { - updatedLocation: this, - stopPropagation: false - }; - } - - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p1.x, 2) + Math.pow(tappedPoint.y - p1.y, 2) - ); - - const sTappedPoint = new DOMPoint(tappedPoint.x,tappedPoint.y).matrixTransform(this.matrix); - - if (this.active && distanceFromDelete <= this.buttonSize / 2) { - return { - updatedLocation: null, - stopPropagation: true - }; - } else if ( - sTappedPoint.x >= this.sp1.x && - sTappedPoint.x <= this.sp2.x && - sTappedPoint.y >= this.sp1.y && - sTappedPoint.y <= this.sp2.y - ) { - this.active = true; - - return { - updatedLocation: this, - stopPropagation: false - }; - } else { - this.active = false; - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } - - /** - * Handler for intercepting pan events on the canvas - * Used for resizing / moving the zone - * - * @param {{x: number, y: number}} start - The coordinates where the panning started - * @param {{x: number, y: number}} last - The coordinates from the last call - * @param {{x: number, y: number}} current - The current coordinates of the pointer - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - translate(start, last, current, transformMapToScreenSpace) { - if (this.active) { - const transformCanvasToMapSpace = transformMapToScreenSpace.inverse(); - // eslint-disable-next-line no-unused-vars - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - - const distanceFromResize = Math.sqrt( - Math.pow(last.x - p2.x, 2) + Math.pow(last.y - p2.y, 2) - ); - - const lastInMapSpace = new DOMPoint(last.x, last.y).matrixTransform(transformCanvasToMapSpace); - const currentInMapSpace = new DOMPoint(current.x, current.y).matrixTransform(transformCanvasToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; - - const sLast = new DOMPoint(last.x,last.y).matrixTransform(this.matrix); - - if (distanceFromResize <= this.buttonSize / 2) { - this.x2 += dx; - this.y2 += dy; - - return { - updatedLocation: this, - stopPropagation: true - }; - } else if ( - sLast.x >= this.sp1.x && - sLast.x <= this.sp2.x && - sLast.y >= this.sp1.y && - sLast.y <= this.sp2.y - ) { - this.x1 += dx; - this.y1 += dy; - this.x2 += dx; - this.y2 += dy; - - return { - updatedLocation: this, - stopPropagation: true - }; - } - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } -} - -/** - * Represents a nogo zone the robot does not enter - */ -export class ForbiddenZone { - - constructor(x1, y1, x2, y2, x3, y3, x4, y4, editable) { - this.editable = editable || false; - - if (editable) { - this.active = true; - this.isResizing = false; - this.buttonSize = 30; - } else { - this.active = false; - } - - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - this.x4 = x4; - - this.y1 = y1; - this.y2 = y2; - this.y3 = y3; - this.y4 = y4; - } - - draw(ctx, transformMapToScreenSpace) { - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformMapToScreenSpace); - const p4 = new DOMPoint(this.x4, this.y4).matrixTransform(transformMapToScreenSpace); - - ctx.save(); - if (!this.active) { - ctx.strokeStyle = "rgb(255, 0, 0)"; - ctx.fillStyle = "rgba(255, 0, 0, 0.4)"; - } else { - ctx.setLineDash([8, 6]); - ctx.strokeStyle = "rgb(255, 0, 0)"; - ctx.fillStyle = "rgba(255, 0, 0, 0)"; - } - - ctx.lineWidth = 2; - ctx.beginPath(); - ctx.moveTo(p1.x, p1.y); - ctx.lineTo(p2.x, p2.y); - ctx.lineTo(p3.x, p3.y); - ctx.lineTo(p4.x, p4.y); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - if (this.active) { - ctx.drawImage( - img_delete_button, - p2.x - img_delete_button.width / 2, - p2.y - img_delete_button.height / 2 - ); - - ctx.drawImage( - img_scale_button, - p3.x - img_scale_button.width / 2, - p3.y - img_scale_button.height / 2 - ); - } - } - - /** - * This is handler is called on each endTranslate. - * It allows us to do post-processing such as snapping - */ - postProcess() { - this.x1 = Math.round(this.x1); - this.y1 = Math.round(this.y1); - - this.x2 = Math.round(this.x2); - this.y2 = Math.round(this.y2); - - this.x3 = Math.round(this.x3); - this.y3 = Math.round(this.y3); - - this.x4 = Math.round(this.x4); - this.y4 = Math.round(this.y4); - } - - /** - * Handler for intercepting tap events on the canvas - * Used for activating / deleting the zone - * - * @param {{x: number, y: number}} tappedPoint - The tapped point in screen coordinates - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - tap(tappedPoint, transformMapToScreenSpace) { - if (!this.editable) { - return { - updatedLocation: this, - stopPropagation: false - }; - } - - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p4 = new DOMPoint(this.x4, this.y4).matrixTransform(transformMapToScreenSpace); - - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p2.x, 2) + Math.pow(tappedPoint.y - p2.y, 2) - ); - - if (this.active && distanceFromDelete <= this.buttonSize / 2) { - return { - updatedLocation: null, - stopPropagation: true - }; - } else if ( - tappedPoint.x >= p1.x && - tappedPoint.x <= p3.x && - tappedPoint.y >= p1.y && - tappedPoint.y <= p3.y - ) { - this.active = true; - - return { - updatedLocation: this, - stopPropagation: false - }; - } else { - this.active = false; - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } - - /** - * Handler for intercepting pan events on the canvas - * Used for resizing / moving the zone - * - * @param {{x: number, y: number}} start - The coordinates where the panning started - * @param {{x: number, y: number}} last - The coordinates from the last call - * @param {{x: number, y: number}} current - The current coordinates of the pointer - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - translate(start, last, current, transformMapToScreenSpace) { - if (this.active) { - const transformCanvasToMapSpace = transformMapToScreenSpace.inverse(); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p4 = new DOMPoint(this.x4, this.y4).matrixTransform(transformMapToScreenSpace); - - const distanceFromResize = Math.sqrt( - Math.pow(last.x - p3.x, 2) + Math.pow(last.y - p3.y, 2) - ); - if (!this.isResizing && distanceFromResize <= this.buttonSize / 2) { - this.isResizing = true; - } - - const lastInMapSpace = new DOMPoint(last.x, last.y).matrixTransform(transformCanvasToMapSpace); - const currentInMapSpace = new DOMPoint(current.x, current.y).matrixTransform(transformCanvasToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; - - if (this.isResizing) { - if (currentInMapSpace.x > this.x1 + 5 && this.x2 + dx > this.x1 + 5) { - this.x2 += dx; - this.x3 += dx; - } - if (currentInMapSpace.y > this.y1 + 5 && this.y3 + dy > this.y1 + 5) { - this.y3 += dy; - this.y4 += dy; - } - - return { - updatedLocation: this, - stopPropagation: true - }; - } else if ( - last.x >= p1.x && - last.x <= p3.x && - last.y >= p1.y && - last.y <= p3.y - ) { - this.x1 += dx; - this.y1 += dy; - this.x2 += dx; - this.y2 += dy; - this.x3 += dx; - this.y3 += dy; - this.x4 += dx; - this.y4 += dy; - - return { - updatedLocation: this, - stopPropagation: true - }; - } - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } - -} - -/** - * Represents a no-mopping zone the robot does not enter when the mop is attached - */ -export class ForbiddenMopZone { - - constructor(x1, y1, x2, y2, x3, y3, x4, y4, editable) { - this.editable = editable || false; - - if (editable) { - this.active = true; - this.isResizing = false; - this.buttonSize = 30; - } else { - this.active = false; - } - - this.x1 = x1; - this.x2 = x2; - this.x3 = x3; - this.x4 = x4; - - this.y1 = y1; - this.y2 = y2; - this.y3 = y3; - this.y4 = y4; - } - - draw(ctx, transformMapToScreenSpace) { - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformMapToScreenSpace); - const p4 = new DOMPoint(this.x4, this.y4).matrixTransform(transformMapToScreenSpace); - - ctx.save(); - if (!this.active) { - ctx.strokeStyle = "rgb(200, 0, 255)"; - ctx.fillStyle = "rgba(200, 0, 255, 0.4)"; - } else { - ctx.setLineDash([8, 6]); - ctx.strokeStyle = "rgb(200, 0, 255)"; - ctx.fillStyle = "rgba(200, 0, 255, 0)"; - } - - ctx.lineWidth = 2; - ctx.beginPath(); - ctx.moveTo(p1.x, p1.y); - ctx.lineTo(p2.x, p2.y); - ctx.lineTo(p3.x, p3.y); - ctx.lineTo(p4.x, p4.y); - ctx.closePath(); - ctx.fill(); - ctx.stroke(); - ctx.restore(); - - if (this.active) { - ctx.drawImage( - img_delete_button, - p2.x - img_delete_button.width / 2, - p2.y - img_delete_button.height / 2 - ); - - ctx.drawImage( - img_scale_button, - p3.x - img_scale_button.width / 2, - p3.y - img_scale_button.height / 2 - ); - } - } - - /** - * This is handler is called on each endTranslate. - * It allows us to do post-processing such as snapping - */ - postProcess() { - this.x1 = Math.round(this.x1); - this.y1 = Math.round(this.y1); - - this.x2 = Math.round(this.x2); - this.y2 = Math.round(this.y2); - - this.x3 = Math.round(this.x3); - this.y3 = Math.round(this.y3); - - this.x4 = Math.round(this.x4); - this.y4 = Math.round(this.y4); - } - - /** - * Handler for intercepting tap events on the canvas - * Used for activating / deleting the zone - * - * @param {{x: number, y: number}} tappedPoint - The tapped point in screen coordinates - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - tap(tappedPoint, transformMapToScreenSpace) { - if (!this.editable) { - return { - updatedLocation: this, - stopPropagation: false - }; - } - - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p4 = new DOMPoint(this.x4, this.y4).matrixTransform(transformMapToScreenSpace); - - const distanceFromDelete = Math.sqrt( - Math.pow(tappedPoint.x - p2.x, 2) + Math.pow(tappedPoint.y - p2.y, 2) - ); - - if (this.active && distanceFromDelete <= this.buttonSize / 2) { - return { - updatedLocation: null, - stopPropagation: true - }; - } else if ( - tappedPoint.x >= p1.x && - tappedPoint.x <= p3.x && - tappedPoint.y >= p1.y && - tappedPoint.y <= p3.y - ) { - this.active = true; - - return { - updatedLocation: this, - stopPropagation: false - }; - } else { - this.active = false; - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } - - /** - * Handler for intercepting pan events on the canvas - * Used for resizing / moving the zone - * - * @param {{x: number, y: number}} start - The coordinates where the panning started - * @param {{x: number, y: number}} last - The coordinates from the last call - * @param {{x: number, y: number}} current - The current coordinates of the pointer - * @param {DOMMatrix} transformMapToScreenSpace - The transformation for transforming map-space coordinates into screen-space. - * This is the transform applied by the vacuum-map canvas. - */ - translate(start, last, current, transformMapToScreenSpace) { - if (this.active) { - const transformCanvasToMapSpace = transformMapToScreenSpace.inverse(); - const p1 = new DOMPoint(this.x1, this.y1).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p2 = new DOMPoint(this.x2, this.y2).matrixTransform(transformMapToScreenSpace); - const p3 = new DOMPoint(this.x3, this.y3).matrixTransform(transformMapToScreenSpace); - // eslint-disable-next-line no-unused-vars - const p4 = new DOMPoint(this.x4, this.y4).matrixTransform(transformMapToScreenSpace); - - const distanceFromResize = Math.sqrt( - Math.pow(last.x - p3.x, 2) + Math.pow(last.y - p3.y, 2) - ); - if (!this.isResizing && distanceFromResize <= this.buttonSize / 2) { - this.isResizing = true; - } - - const lastInMapSpace = new DOMPoint(last.x, last.y).matrixTransform(transformCanvasToMapSpace); - const currentInMapSpace = new DOMPoint(current.x, current.y).matrixTransform(transformCanvasToMapSpace); - - const dx = currentInMapSpace.x - lastInMapSpace.x; - const dy = currentInMapSpace.y - lastInMapSpace.y; - - if (this.isResizing) { - if (currentInMapSpace.x > this.x1 + 5 && this.x2 + dx > this.x1 + 5) { - this.x2 += dx; - this.x3 += dx; - } - if (currentInMapSpace.y > this.y1 + 5 && this.y3 + dy > this.y1 + 5) { - this.y3 += dy; - this.y4 += dy; - } - - return { - updatedLocation: this, - stopPropagation: true - }; - } else if ( - last.x >= p1.x && - last.x <= p3.x && - last.y >= p1.y && - last.y <= p3.y - ) { - this.x1 += dx; - this.y1 += dy; - this.x2 += dx; - this.y2 += dy; - this.x3 += dx; - this.y3 += dy; - this.x4 += dx; - this.y4 += dy; - - return { - updatedLocation: this, - stopPropagation: true - }; - } - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } - -} - -/** - * Label of a segment - */ -export class SegmentLabel { - - constructor(x ,y, id, selected, active, area, name) { - this.x = x; - this.y = y; - this.id = id; - - this.selected = selected === true; - this.active = active === true; - this.name = name; - - this.scaledIconSize = { - width: 0, - height: 0 - }; - - this.area = area; - } - - draw(ctx, transformFromMapSpace, scaleFactor) { - const p1 = new DOMPoint(this.x, this.y).matrixTransform(transformFromMapSpace); - - if (this.selected === true) { - this.image = img_segment_active; - } else { - this.image = img_segment; - } - - this.scaledIconSize = { - width: Math.max( - this.image.width * (scaleFactor / 4), - this.image.width * 0.8 - ), - height: Math.max( - this.image.height * (scaleFactor / 4), - this.image.height * 0.8 - ) - }; - - ctx.save(); - - if (this.active) { - ctx.translate(p1.x, p1.y); - ctx.rotate(Math.PI); - ctx.translate(-p1.x, -p1.y); - } - - ctx.drawImage( - this.image, - p1.x - this.scaledIconSize.width / 2, - p1.y - (this.scaledIconSize.height / 3)*2, - this.scaledIconSize.width, - this.scaledIconSize.height - ); - - ctx.restore(); - - if (scaleFactor >= 11) { - ctx.save(); - ctx.textAlign = "center"; - ctx.font = "45px sans-serif"; - ctx.fillStyle = "rgba(255, 255, 255, 1)"; - let text = this.name ? this.name : this.id; - ctx.fillText(text, p1.x , p1.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0)); - ctx.strokeText(text, p1.x , p1.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0)); - - - if (this.area) { - let areaString = (this.area / 10000).toPrecision(2) + " m²"; - if (this.name) { - areaString += `\n(id=${this.id})`; - } - - ctx.font = "35px sans-serif"; - ctx.fillStyle = "rgba(255, 255, 255, 1)"; - ctx.fillText(areaString, p1.x , p1.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0) + 45); - ctx.strokeText(areaString, p1.x , p1.y + ((this.scaledIconSize.height/3)*2) + 20 + (this.active ? 25 : 0) + 45); - } - - ctx.restore(); - } - } - - tap(tappedPoint, transformMapToScreenSpace) { - const p1 = new DOMPoint(this.x, this.y).matrixTransform(transformMapToScreenSpace); - - if ( - tappedPoint.x >= p1.x - this.scaledIconSize.width / 2 && - tappedPoint.x <= p1.x + this.scaledIconSize.width / 2 && - tappedPoint.y >= p1.y - this.scaledIconSize.height / 2 && - tappedPoint.y <= p1.y + this.scaledIconSize.height / 2 - ) { - this.selected = !this.selected; - - return { - updatedLocation: this, - stopPropagation: true - }; - } - - return { - updatedLocation: this, - stopPropagation: false - }; - } -} diff --git a/old_frontend/lib/js/js-modules/map-color-finder.js b/old_frontend/lib/js/js-modules/map-color-finder.js deleted file mode 100644 index 0f72cc6a..00000000 --- a/old_frontend/lib/js/js-modules/map-color-finder.js +++ /dev/null @@ -1,234 +0,0 @@ -export class FourColorTheoremSolver { - - /** - * This class determines how to color the different map segments contained in the given layers object. - * The resulting color mapping will ensure that no two adjacent segments share the same color. - * The map is evaluated row-by-row and column-by-column in order to find every pair of segments that are in "line of sight" of each other. - * Each pair of segments is then represented as an edge in a graph where the vertices represent the segments themselves. - * We then use a simple greedy algorithm to color all vertices so that none of its edges connect it to a vertex with the same color. - * - * @param {Array} layers - the data containing the map image (array of pixel offsets) - * @param {number} resolution - Minimal resolution of the map scanner in pixels. Any number higher than one will lead to this many pixels being skipped when finding segment boundaries. - * For example: If the robot measures 30cm in length/width, this should be set to 6, as no room can be smaller than 6 pixels. This of course implies that a pixel represents 5cm in the real world. - */ - constructor(layers, resolution) { - const prec = Math.floor(resolution); - this.stepFunction = function (c) { - return c + prec; - }; - var preparedLayers = this.preprocessLayers(layers); - if (preparedLayers !== undefined) { - var mapData = this.createPixelToSegmentMapping(preparedLayers); - this.areaGraph = this.buildGraph(mapData); - this.areaGraph.colorAllVertices(); - } - } - - /** - * @param {number} segmentId - ID of the segment you want to get the color for. - * The segment ID is extracted from the layer meta data in the first contructor parameter of this class. - * @returns {number} The segment color, represented as an integer. Starts at 0 and goes up the minimal number of colors required to color the map without collisions. - */ - getColor(segmentId) { - if (this.areaGraph === undefined) { - // Layer preprocessing seems to have failed. Just return a default value for any input. - return 0; - } - - var segmentFromGraph = this.areaGraph.getById(segmentId); - if (segmentFromGraph) { - return segmentFromGraph.color; - } else { - return 0; - } - } - - preprocessLayers(layers) { - var internalSegments = []; - var boundaries = { - minX: Infinity, - maxX: -Infinity, - minY: Infinity, - maxY: -Infinity - }; - const filteredLayers = layers.filter(layer => layer.type === "segment"); - if (filteredLayers.length <= 0) { - return undefined; - } - filteredLayers.forEach(layer => { - var allPixels = []; - for (let index = 0; index < layer.pixels.length - 1; index += 2) { - var p = { - x: layer.pixels[index], - y: layer.pixels[index + 1] - }; - this.setBoundaries(boundaries, p); - allPixels.push(p); - } - internalSegments.push({ - segmentId: layer.metaData.segmentId, - name: layer.metaData.name, - pixels: allPixels - }); - }); - return { - boundaries: boundaries, - segments: internalSegments - }; - } - - setBoundaries(res, pixel) { - if (pixel.x < res.minX) { - res.minX = pixel.x; - } - if (pixel.y < res.minY) { - res.minY = pixel.y; - } - if (pixel.x > res.maxX) { - res.maxX = pixel.x; - } - if (pixel.y > res.maxY) { - res.maxY = pixel.y; - } - } - - createPixelToSegmentMapping(preparedLayers) { - var pixelData = this.create2DArray( - preparedLayers.boundaries.maxX + 1, - preparedLayers.boundaries.maxY + 1 - ); - var segmentIds = []; - preparedLayers.segments.forEach(seg => { - segmentIds.push(seg.segmentId); - seg.pixels.forEach(p => { - pixelData[p.x][p.y] = seg.segmentId; - }); - }); - return { - map: pixelData, - segmentIds: segmentIds, - boundaries: preparedLayers.boundaries - }; - } - - buildGraph(mapData) { - var vertices = mapData.segmentIds.map(i => new MapAreaVertex(i)); - var graph = new MapAreaGraph(vertices); - this.traverseMap(mapData.boundaries, mapData.map, (x, y, currentSegmentId, pixelData) => { - var newSegmentId = pixelData[x][y]; - graph.connectVertices(currentSegmentId, newSegmentId); - return newSegmentId !== undefined ? newSegmentId : currentSegmentId; - }); - return graph; - } - - traverseMap(boundaries, pixelData, func) { - // row-first traversal - for (let y = boundaries.minY; y <= boundaries.maxY; y = this.stepFunction(y)) { - var rowFirstSegmentId = undefined; - for (let x = boundaries.minX; x <= boundaries.maxX; x = this.stepFunction(x)) { - rowFirstSegmentId = func(x, y, rowFirstSegmentId, pixelData); - } - } - // column-first traversal - for (let x = boundaries.minX; x <= boundaries.maxX; x = this.stepFunction(x)) { - var colFirstSegmentId = undefined; - for (let y = boundaries.minY; y <= boundaries.maxY; y = this.stepFunction(y)) { - colFirstSegmentId = func(x, y, colFirstSegmentId, pixelData); - } - } - } - - /** - * Credit for this function goes to the authors of this StackOverflow answer: https://stackoverflow.com/a/966938 - * - * @param {number} length - */ - create2DArray(length) { - var arr = new Array(length || 0), - i = length; - if (arguments.length > 1) { - var args = Array.prototype.slice.call(arguments, 1); - while (i--) { - arr[length - 1 - i] = this.create2DArray.apply(this, args); - } - } - return arr; - } -} - -class MapAreaVertex { - constructor(id) { - this.id = id; - this.adjacentVertexIds = new Set(); - this.color = undefined; - } - - appendVertex(vertexId) { - if (vertexId !== undefined) { - this.adjacentVertexIds.add(vertexId); - } - } -} - -class MapAreaGraph { - constructor(vertices) { - this.vertices = vertices; - this.vertexLookup = new Map(); - this.vertices.forEach(v => { - this.vertexLookup.set(v.id, v); - }); - } - - connectVertices(id1, id2) { - if (id1 !== undefined && id2 !== undefined && id1 !== id2) { - if (this.vertexLookup.has(id1)) { - this.vertexLookup.get(id1).appendVertex(id2); - } - if (this.vertexLookup.has(id2)) { - this.vertexLookup.get(id2).appendVertex(id1); - } - } - } - - /** - * Color the graphs vertices using a greedy algorithm. Any vertices that have already been assigned a color will not be changed. - * Color assignment will start with the vertex that is connected with the highest number of edges. In most cases, this will - * naturally lead to a distribution where only four colors are required for the whole graph. This is relevant for maps with a high - * number of segments, as the naive, greedy algorithm tends to require a fifth color when starting coloring in a segment far from the map's center. - * - */ - colorAllVertices() { - this.vertices.sort((l, r) => r.adjacentVertexIds.size - l.adjacentVertexIds.size) - .forEach(v => { - if (v.adjacentVertexIds.size <= 0) { - v.color = 0; - } else { - var adjs = this.getAdjacentVertices(v); - var existingColors = adjs - .filter(vert => vert.color !== undefined) - .map(vert => vert.color); - v.color = this.lowestColor(existingColors); - } - }); - } - - getAdjacentVertices(vertex) { - return Array.from(vertex.adjacentVertexIds).map(id => this.getById(id)); - } - - getById(id) { - return this.vertices.find(v => v.id === id); - } - - lowestColor(colors) { - if (colors.length <= 0) { - return 0; - } - for (let index = 0; index < colors.length + 1; index++) { - if (!colors.includes(index)) { - return index; - } - } - } -} diff --git a/old_frontend/lib/js/js-modules/map-drawer.js b/old_frontend/lib/js/js-modules/map-drawer.js deleted file mode 100644 index ebf6d7dc..00000000 --- a/old_frontend/lib/js/js-modules/map-drawer.js +++ /dev/null @@ -1,92 +0,0 @@ -import { FourColorTheoremSolver } from "./map-color-finder.js"; - -/** - * Object for drawing the map itself onto a 1024 * 1024 canvas. - * It's not displayed directly but used to easily paint the map image onto another canvas. - */ -export function MapDrawer() { - const mapCanvas = document.createElement("canvas"); - const mapCtx = mapCanvas.getContext("2d"); - - //Default. Will be overwritten - mapCanvas.width = 1024; - mapCanvas.height = 1024; - - function hexToRgb(hex) { - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim()); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } : null; - } - - /** - * - * @param {Array} layers - the data containing the map image (array of pixel offsets) - */ - function draw(layers) { - const freeColor = hexToRgb(getComputedStyle(document.documentElement).getPropertyValue("--map-free") || "#0076ff"); - const occupiedColor = hexToRgb(getComputedStyle(document.documentElement).getPropertyValue("--map-occupied") || "#333333"); - const segmentColors = [ - "#19A1A1", - "#7AC037", - "#DF5618", - "#F7C841", - "#9966CC" // "fallback" color - ].map(function (e) { - return hexToRgb(e); - }); - - mapCtx.clearRect(0, 0, mapCanvas.width, mapCanvas.height); - const imgData = mapCtx.createImageData(mapCanvas.width, mapCanvas.height); - - const colorFinder = new FourColorTheoremSolver(layers, 6); - - if (layers.length > 0) { - layers.forEach(layer => { - var color; - var alpha = 255; - - switch (layer.type) { - case "floor": - color = freeColor; - alpha = 192; - break; - case "wall": - color = occupiedColor; - break; - case "segment": - color = segmentColors[colorFinder.getColor((layer.metaData.segmentId))]; - alpha = 192; - break; - } - - if (!color) { - console.error(`Missing color for ${layer.type} with segment id '${layer.metaData.segmentId}'.`); - color = {r: 0, g: 0, b: 0}; - } - - for (let i = 0; i < layer.pixels.length; i = i + 2) { - drawPixel(imgData, mapCanvas, layer.pixels[i], layer.pixels[i+1], color.r, color.g, color.b, alpha); - } - }); - } - - mapCtx.putImageData(imgData, 0, 0); - } - - function drawPixel(imgData, mapCanvas, x, y, r, g, b, a) { - const imgDataOffset = (x + y * mapCanvas.width) * 4; - - imgData.data[imgDataOffset] = r; - imgData.data[imgDataOffset + 1] = g; - imgData.data[imgDataOffset + 2] = b; - imgData.data[imgDataOffset + 3] = a; - } - - return { - draw: draw, - canvas: mapCanvas - }; -} diff --git a/old_frontend/lib/js/js-modules/touch-handling.js b/old_frontend/lib/js/js-modules/touch-handling.js deleted file mode 100644 index ac7ed91c..00000000 --- a/old_frontend/lib/js/js-modules/touch-handling.js +++ /dev/null @@ -1,234 +0,0 @@ -function distance([x1, y1], [x2, y2]) { - return Math.sqrt( - Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) - ); -} - -class NoGesture { - constructor() {} - updatePointerPosition(evts) {} - removePointer(evt) { - return this; - } -} - -class PossibleTap { - constructor(pointerDownEvent, dispatchEvent) { - this.tapTolerance = 5; - this.pointerId = pointerDownEvent.pointerId; - this.pointerDownPosition = [pointerDownEvent.clientX, pointerDownEvent.clientY]; - this.lastPosition = [pointerDownEvent.clientX, pointerDownEvent.clientY]; - - this.dispatchEvent = dispatchEvent; - } - - toleranceExeeded() { - return distance(this.lastPosition, this.pointerDownPosition) > this.tapTolerance; - } - - updatePointerPosition(evts) { - this.lastPosition = [evts[0].clientX, evts[0].clientY]; - } - - removePointer(evt) { - if (evt.pointerId === this.pointerId) { - const tapEvent = new Event("tap"); - tapEvent.tappedCoordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - this.dispatchEvent(tapEvent); - - return new NoGesture(); - } else { - return this; - } - } -} - -class OngoingPan { - constructor(pointerId, [pointerDownX, pointerDownY], [currentX, currentY], dispatchEvent) { - this.pointerId = pointerId; - this.pointerDownPosition = [pointerDownX, pointerDownY]; - this.lastPosition = [currentX, currentY]; - - this.dispatchEvent = dispatchEvent; - - const panStartEvent = new Event("panstart"); - panStartEvent.coordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - this.dispatchEvent(panStartEvent); - } - - updatePointerPosition(evts) { - this.lastPosition = [evts[0].clientX, evts[0].clientY]; - - const panMoveEvent = new Event("panmove"); - panMoveEvent.startCoordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - panMoveEvent.currentCoordinates = {x: evts[0].clientX, y: evts[0].clientY}; - this.dispatchEvent(panMoveEvent); - } - - removePointer(evt) { - if (evt.pointerId === this.pointerId) { - const panEndEvent = new Event("panend"); - panEndEvent.startCoordinates = {x: this.pointerDownPosition[0], y: this.pointerDownPosition[1]}; - panEndEvent.currentCoordinates = {x: evt.clientX, y: evt.clientY}; - this.dispatchEvent(panEndEvent); - - return new NoGesture(); - } else { - return this; - } - } -} - -class OngoingPinch { - constructor(pointerId, [pointerDownX, pointerDownY], secondPointerDownEvent, dispatchEvent) { - this.tapTolerance = 5; - this.pointerId = pointerId; - this.pointerDownPosition = [pointerDownX, pointerDownY]; - this.lastPosition = [pointerDownX, pointerDownY]; - this.pointer2Id = secondPointerDownEvent.pointerId; - this.pointer2DownPosition = [secondPointerDownEvent.clientX, secondPointerDownEvent.clientY]; - this.lastPosition2 = [secondPointerDownEvent.clientX, secondPointerDownEvent.clientY]; - - this.dispatchEvent = dispatchEvent; - - const pinchStartEvent = new Event("pinchstart"); - pinchStartEvent.distance = distance(this.pointerDownPosition, this.pointer2DownPosition); - pinchStartEvent.scale = 1; - pinchStartEvent.center = { - x: (this.pointerDownPosition[0] + this.pointer2DownPosition[0]) / 2, - y: (this.pointerDownPosition[1] + this.pointer2DownPosition[1]) / 2 - }; - this.dispatchEvent(pinchStartEvent); - } - - updatePointerPosition(evts) { - for (let evt of evts) { - if (evt.pointerId === this.pointerId) { - this.lastPosition = [evt.clientX, evt.clientY]; - } else if (evt.pointerId === this.pointer2Id) { - this.lastPosition2 = [evt.clientX, evt.clientY]; - } - } - - const pinchMoveEvent = new Event("pinchmove"); - pinchMoveEvent.distance = distance(this.lastPosition, this.lastPosition2); - pinchMoveEvent.scale = pinchMoveEvent.distance / distance(this.pointerDownPosition, this.pointer2DownPosition); - pinchMoveEvent.center = { - x: (this.lastPosition[0] + this.lastPosition2[0]) / 2, - y: (this.lastPosition[1] + this.lastPosition2[1]) / 2 - }; - - this.dispatchEvent(pinchMoveEvent); - } - - removePointer(evt) { - if (evt.pointerId === this.pointerId) { - this.dispatchEvent(new Event("pinchend")); - return new OngoingPan( - this.pointer2Id, - this.lastPosition2, - this.lastPosition2, - this.dispatchEvent - ); - } else if (evt.pointerId === this.pointer2Id) { - this.dispatchEvent(new Event("pinchend")); - return new OngoingPan( - this.pointerId, - this.lastPosition, - this.lastPosition, - this.dispatchEvent - ); - } else { - return this; - } - } -} - -export class TouchHandler { - /** - * @param {HTMLElement} trackedElement - */ - constructor(trackedElement) { - this.trackedElement = trackedElement; - this.trackedElement.addEventListener("mousedown", e => this.pointerDown(e, this.touchChangesFromMouseEvent(e))); - this.trackedElement.addEventListener("mousemove", e => this.pointerMove(e, this.touchChangesFromMouseEvent(e))); - this.trackedElement.addEventListener("mouseup", e => this.pointerUp(e, this.touchChangesFromMouseEvent(e))); - this.trackedElement.addEventListener("mouseleave", e => this.pointerUp(e, this.touchChangesFromMouseEvent(e))); - this.trackedElement.addEventListener("mouseout", e => this.pointerUp(e, this.touchChangesFromMouseEvent(e))); - - this.trackedElement.addEventListener("touchstart", e => this.pointerDown(e, this.touchChangesFromTouchEvent(e))); - this.trackedElement.addEventListener("touchmove", e => this.pointerMove(e, this.touchChangesFromTouchEvent(e))); - this.trackedElement.addEventListener("touchcancel", e => this.pointerUp(e, this.touchChangesFromTouchEvent(e))); - this.trackedElement.addEventListener("touchend", e => this.pointerUp(e, this.touchChangesFromTouchEvent(e))); - - this.ongoingGesture = new NoGesture(); - } - - - touchChangesFromMouseEvent(evt) { - return [{ - clientX: evt.clientX, - clientY: evt.clientY, - pointerId: 0 - }]; - } - - touchChangesFromTouchEvent(evt) { - const changedTouches = []; - - for (let touch of evt.changedTouches) { - changedTouches.push({ - clientX: touch.clientX, - clientY: touch.clientY, - pointerId: touch.identifier - }); - } - - return changedTouches; - } - - pointerDown(evt, changedTouches) { - evt.stopPropagation(); - evt.preventDefault(); - - if (this.ongoingGesture instanceof NoGesture) { - this.ongoingGesture = new PossibleTap(changedTouches[0], this.trackedElement.dispatchEvent.bind(this.trackedElement)); - - } else if (this.ongoingGesture instanceof PossibleTap || this.ongoingGesture instanceof OngoingPan) { - this.ongoingGesture = new OngoingPinch( - this.ongoingGesture.pointerId, - // start the pinch with the first pointer at the current position - // (when the second pointer was added) - this.ongoingGesture.lastPosition, - changedTouches[0], - this.trackedElement.dispatchEvent.bind(this.trackedElement) - ); - } - } - - pointerMove(evt, changedTouches) { - evt.stopPropagation(); - evt.preventDefault(); - - this.ongoingGesture.updatePointerPosition(changedTouches); - - // Upgrade Tap to a Pan if the movement tolerance is exeeded - if (this.ongoingGesture instanceof PossibleTap && this.ongoingGesture.toleranceExeeded()) { - this.ongoingGesture = new OngoingPan( - this.ongoingGesture.pointerId, - this.ongoingGesture.pointerDownPosition, - this.ongoingGesture.lastPosition, - this.trackedElement.dispatchEvent.bind(this.trackedElement) - ); - } - } - - pointerUp(evt, changedTouches) { - evt.stopPropagation(); - evt.preventDefault(); - - changedTouches.forEach(e => { - this.ongoingGesture = this.ongoingGesture.removePointer(e); - }); - } -} diff --git a/old_frontend/lib/js/js-modules/tracked-canvas.js b/old_frontend/lib/js/js-modules/tracked-canvas.js deleted file mode 100644 index ca2519f6..00000000 --- a/old_frontend/lib/js/js-modules/tracked-canvas.js +++ /dev/null @@ -1,80 +0,0 @@ - -/** - * This allows to save and retrieve the currently applied transfroms from the RenderingContext. - * There is a native browser feature not really supported today: - * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/currentTransform - * - * - * Large amounts of this code are from here: https://codepen.io/techslides/pen/zowLd - * - * @param {CanvasRenderingContext2D} ctx - */ -export function trackTransforms(ctx) { - let xform = new DOMMatrix(); - ctx.getTransform = function () { - return xform.translate(0, 0); - }; - - const savedTransforms = []; - const save = ctx.save; - ctx.save = function () { - savedTransforms.push(xform.translate(0, 0)); - return save.call(ctx); - }; - - const restore = ctx.restore; - ctx.restore = function () { - xform = savedTransforms.pop(); - return restore.call(ctx); - }; - - const scale = ctx.scale; - ctx.scale = function (sx, sy) { - xform = xform.scale(sx, sy); - return scale.call(ctx, sx, sy); - }; - - const rotate = ctx.rotate; - ctx.rotate = function (radians) { - xform = xform.rotate(radians * 180 / Math.PI); - return rotate.call(ctx, radians); - }; - - const translate = ctx.translate; - ctx.translate = function (dx, dy) { - xform = xform.translate(dx, dy); - return translate.call(ctx, dx, dy); - }; - - const transform = ctx.transform; - ctx.transform = function (a, b, c, d, e, f) { - const m2 = new DOMMatrix(); - m2.a = a; m2.b = b; m2.c = c; m2.d = d; m2.e = e; m2.f = f; - xform = xform.multiply(m2); - return transform.call(ctx, a, b, c, d, e, f); - }; - - const setTransform = ctx.setTransform; - ctx.setTransform = function (a, b, c, d, e, f) { - xform.a = a; - xform.b = b; - xform.c = c; - xform.d = d; - xform.e = e; - xform.f = f; - return setTransform.call(ctx, a, b, c, d, e, f); - }; - - const pt = new DOMPoint(); - ctx.transformedPoint = function (x, y) { - pt.x = x; pt.y = y; - return pt.matrixTransform(xform.inverse()); - }; - - ctx.getScaleFactor2d = function () { - const sx = Math.sqrt(xform.a * xform.a + xform.b + xform.b); - const sy = Math.sqrt(xform.c * xform.c + xform.d * xform.d); - - return [sx, sy]; - }; -} diff --git a/old_frontend/lib/js/js-modules/vacuum-map.js b/old_frontend/lib/js/js-modules/vacuum-map.js deleted file mode 100644 index 626cff06..00000000 --- a/old_frontend/lib/js/js-modules/vacuum-map.js +++ /dev/null @@ -1,952 +0,0 @@ -import {MapDrawer} from "./map-drawer.js"; -import {trackTransforms} from "./tracked-canvas.js"; -import { - CurrentCleaningZone, - ForbiddenZone, - ForbiddenMopZone, - GotoPoint, - GotoTarget, - SegmentLabel, - VirtualWall, - Zone, - Robot, - Charger -} from "./locations.js"; -import {TouchHandler} from "./touch-handling.js"; - -/** - * Represents the map and handles all the userinteractions - * as panning / zooming into the map. - * - * @param {HTMLCanvasElement} canvasElement - the canvas used to display the map on - */ -export function VacuumMap(canvasElement) { - const canvas = canvasElement; - - const mapDrawer = new MapDrawer(); - let evtSource; - - let options = {}; - - canvas.width = canvas.clientWidth; - canvas.height = canvas.clientHeight; - - let locations = []; - let size = { - x: 1024, - y: 1024, - pixelSize: 5 - }; - - let pathSvg = new Image(); - let predictedPathSvg = new Image(); - - let actualScaleFactor = 1; - - let redrawCanvas = null; - - function initSSE() { - console.info("SSE Connecting"); - evtSource = new EventSource("../api/v2/robot/state/map/sse", {withCredentials: true}); - - - evtSource.addEventListener("MapUpdated", (event) => { - try { - updateMap(JSON.parse(event.data)); - } catch (e) { - console.error("Unable to parse Map Update", e); - } - - }, false); - - evtSource.onopen = function() { - console.info("Connected to SSE"); - }; - - evtSource.onerror = function(e) { - setTimeout(() => { - console.info("Reconnecting to SSE"); - initSSE(); - }, 5000); - }; - } - - function closeSSEConnection() { - if (evtSource) { - evtSource.close(); - - evtSource = undefined; - } - } - - function drawPath(path, isPredicted) { - const pathColor = (getComputedStyle(document.documentElement).getPropertyValue("--path") || "#ffffff").trim(); - - if (path && path.points.length > 0) { - let svgPath = " { - predictedPathSvg = newImg; - }; - newImg.src = svgPathDataUrl; - } - } else { - if (svgPathDataUrl !== pathSvg.src) { - let newImg = new Image(); - - newImg.onload = () => { - pathSvg = newImg; - }; - newImg.src = svgPathDataUrl; - } - } - } else { - const emptySvgDataUrl = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(""); - - if (isPredicted) { - let newImg = new Image(); - - newImg.onload = () => { - predictedPathSvg = newImg; - }; - - newImg.src = emptySvgDataUrl; - } else { - let newImg = new Image(); - - newImg.onload = () => { - pathSvg = newImg; - }; - - newImg.src = emptySvgDataUrl; - } - } - } - - function updateForbiddenZones(forbiddenZoneData) { - locations = locations - .filter(l => !(l instanceof ForbiddenZone)) - .concat(forbiddenZoneData.map(zone => { - const p1 = convertFromRealCoords({x: zone.points[0], y: zone.points[1]}); - const p2 = convertFromRealCoords({x: zone.points[2], y: zone.points[3]}); - const p3 = convertFromRealCoords({x: zone.points[4], y: zone.points[5]}); - const p4 = convertFromRealCoords({x: zone.points[6], y: zone.points[7]}); - return new ForbiddenZone( - p1.x, p1.y, - p2.x, p2.y, - p3.x, p3.y, - p4.x, p4.y - ); - })); - } - - function updateForbiddenMopZones(forbiddenMopZoneData) { - locations = locations - .filter(l => !(l instanceof ForbiddenMopZone)) - .concat(forbiddenMopZoneData.map(zone => { - const p1 = convertFromRealCoords({x: zone.points[0], y: zone.points[1]}); - const p2 = convertFromRealCoords({x: zone.points[2], y: zone.points[3]}); - const p3 = convertFromRealCoords({x: zone.points[4], y: zone.points[5]}); - const p4 = convertFromRealCoords({x: zone.points[6], y: zone.points[7]}); - return new ForbiddenMopZone( - p1.x, p1.y, - p2.x, p2.y, - p3.x, p3.y, - p4.x, p4.y - ); - })); - } - - function updateRobotPosition(robot) { - - locations = locations - .filter(l => !(l instanceof Robot)); - - if (robot) { - const p1 = convertFromRealCoords({x: robot.points[0], y: robot.points[1]}); - locations.push(new Robot(p1.x, p1.y, robot.metaData.angle)); - } - } - - function updateChargerLocation(charger) { - - locations = locations - .filter(l => !(l instanceof Charger)); - - if (charger) { - const p1 = convertFromRealCoords({x: charger.points[0], y: charger.points[1]}); - locations.push(new Charger(p1.x, p1.y)); - } - } - - function updateGotoTarget(gotoTarget) { - - locations = locations - .filter(l => !(l instanceof GotoTarget)); - - if (gotoTarget) { - const p1 = convertFromRealCoords({x: gotoTarget.points[0], y: gotoTarget.points[1]}); - locations.push(new GotoTarget(p1.x, p1.y)); - } - } - - function updateCurrentZones(currentZoneData) { - locations = locations - .filter(l => !(l instanceof CurrentCleaningZone)) - .concat(currentZoneData.map(zone => { - const p1 = convertFromRealCoords({x: zone.points[0], y: zone.points[1]}); - const p2 = convertFromRealCoords({x: zone.points[4], y: zone.points[5]}); - return new CurrentCleaningZone(new DOMPoint(p1.x, p1.y), new DOMPoint(p2.x, p2.y)); - })); - } - - function updateVirtualWalls(virtualWallData) { - locations = locations - .filter(l => !(l instanceof VirtualWall)) - .concat(virtualWallData.map(wall => { - const p1 = convertFromRealCoords({x: wall.points[0], y: wall.points[1]}); - const p2 = convertFromRealCoords({x: wall.points[2], y: wall.points[3]}); - return new VirtualWall(p1.x, p1.y, p2.x, p2.y); - })); - } - - // eslint-disable-next-line no-unused-vars - function updateSegmentMetadata(segments) { - const selectedSegments = locations.filter(l => l instanceof SegmentLabel && l.selected === true).map(s => s.id); - - locations = locations.filter(l => !(l instanceof SegmentLabel)); - - segments.forEach(segment => { - locations.push(new SegmentLabel( - segment.dimensions.x.mid, - segment.dimensions.y.mid, - segment.metaData.segmentId, - selectedSegments.indexOf(segment.metaData.segmentId) !== -1, - segment.metaData.active, - segment.metaData.area, - segment.metaData.name - )); - }); - - } - - function updateMapMetadata(mapData) { - const go_to_target = mapData.entities.find(e => e.type === "go_to_target"); - const active_zones = mapData.entities.filter(e => e.type === "active_zone"); - const no_go_areas = mapData.entities.filter(e => e.type === "no_go_area"); - const no_mop_areas = mapData.entities.filter(e => e.type === "no_mop_area"); - const virtual_walls = mapData.entities.filter(e => e.type === "virtual_wall"); - const segments = mapData.layers.filter(e => e.type === "segment"); - const robotPosition = mapData.entities.find(e => e.type === "robot_position"); - const chargerLocation = mapData.entities.find(e => e.type === "charger_location"); - - //the order is important here - updateCurrentZones(active_zones); - updateForbiddenZones(no_go_areas); - updateForbiddenMopZones(no_mop_areas); - updateVirtualWalls(virtual_walls); - - updateChargerLocation(chargerLocation); - updateRobotPosition(robotPosition); - - updateSegmentMetadata(segments); - updateGotoTarget(go_to_target); - } - - /** - * Public function to update the displayed mapdata periodically. - * Data is distributed into the subcomponents for rendering the map / path. - * - * @param {object} mapData - the json data returned by the "/api/map/latest" route - */ - function updateMap(mapData) { - size.x = mapData.size.x; - size.y = mapData.size.y; - size.pixelSize = mapData.pixelSize; - - let pixelX = Math.round(size.x / size.pixelSize); - let pixelY = Math.round(size.y / size.pixelSize); - - if (pixelX !== mapDrawer.canvas.width) { - mapDrawer.canvas.width = pixelX; - } - - if (pixelY !== mapDrawer.canvas.height) { - mapDrawer.canvas.height = pixelY; - } - - if( mapData.metaData.version === 2 && Array.isArray(mapData.layers)) { - mapData.layers.forEach(layer => { - if(layer.pixels.length === 0 && layer.compressedPixels.length !== 0) { - for (let i = 0; i < layer.compressedPixels.length; i = i + 3) { - const xStart = layer.compressedPixels[i]; - const y = layer.compressedPixels[i+1] - const count = layer.compressedPixels[i+2] - - for(let j = 0; j < count; j++) { - layer.pixels.push( - xStart + j, - y - ); - } - } - } - }) - } - - mapDrawer.draw(mapData.layers); - - drawPath(mapData.entities.find(e => e.type === "path"), false); - drawPath(mapData.entities.find(e => e.type === "predicted_path"), true); - - updateMapMetadata(mapData); - - if (redrawCanvas) { - redrawCanvas(); - } - } - - /** - * Transforms coordinates in mapspace into the centimeter format - * - * @param {{x: number, y: number}} coordinatesInMapSpace - */ - function convertToRealCoords(coordinatesInMapSpace) { - return {x: Math.floor(coordinatesInMapSpace.x * size.pixelSize), y: Math.floor(coordinatesInMapSpace.y * size.pixelSize)}; - } - - /** - * Transforms coordinates in the centimeter format into the mapspace - * - * @param {{x: number, y: number}} coordinatesInCentimeter - */ - function convertFromRealCoords(coordinatesInCentimeter) { - return {x: Math.floor(coordinatesInCentimeter.x / size.pixelSize), y: Math.floor(coordinatesInCentimeter.y / size.pixelSize)}; - } - - /** - * Sets up the canvas for tracking taps / pans / zooms and redrawing the map accordingly - * - * @param {object} data - the json data returned by the "/api/map/latest" route - * @param {object} opts - */ - function initCanvas(data, opts) { - if (opts) { - options = opts; - } - let ctx = canvas.getContext("2d"); - ctx.imageSmoothingEnabled = false; - trackTransforms(ctx); - - size.x = data.size.x; - size.y = data.size.y; - size.pixelSize = data.pixelSize; - - let pixelX = Math.round(size.x / size.pixelSize); - let pixelY = Math.round(size.y / size.pixelSize); - - if (pixelX !== mapDrawer.canvas.width) { - mapDrawer.canvas.width = pixelX; - } - - if (pixelY !== mapDrawer.canvas.height) { - mapDrawer.canvas.height = pixelY; - } - - window.addEventListener("resize", () => { - // Save the current transformation and recreate it - // as the transformation state is lost when changing canvas size - // https://stackoverflow.com/questions/48044951/canvas-state-lost-after-changing-size - const {a, b, c, d, e, f} = ctx.getTransform(); - - canvas.height = canvas.clientHeight; - canvas.width = canvas.clientWidth; - - ctx.setTransform(a, b, c, d, e, f); - ctx.imageSmoothingEnabled = false; - - redraw(); - }); - - if( data.metaData.version === 2 && Array.isArray(data.layers)) { - - data.layers.forEach(layer => { - if(layer.pixels.length === 0 && layer.compressedPixels.length !== 0) { - for (let i = 0; i < layer.compressedPixels.length; i = i + 3) { - const xStart = layer.compressedPixels[i]; - const y = layer.compressedPixels[i+1] - const count = layer.compressedPixels[i+2] - - for(let j = 0; j < count; j++) { - layer.pixels.push( - xStart + j, - y - ); - } - } - } - }) - } - - mapDrawer.draw(data.layers); - - if (!options.noPath) { - drawPath(data.entities.find(e => e.type === "path"), false); - drawPath(data.entities.find(e => e.type === "predicted_path"), true); - } - - switch (options.metaData) { - case false: - case "none": - break; - case "forbidden": - updateForbiddenZones(data.entities.filter(e => e.type === "no_go_area")); - updateForbiddenMopZones(data.entities.filter(e => e.type === "no_mop_area")); - updateVirtualWalls(data.entities.filter(e => e.type === "virtual_wall")); - break; - case "segments": - updateSegmentMetadata(data.layers.filter(e => e.type === "segment")); - break; - default: - updateMapMetadata(data); - } - - const boundingBox = { - minX: 0, - minY: 0, - maxX: data.size.x / data.pixelSize, - maxY: data.size.y / data.pixelSize - }; - const initialScalingFactor = Math.min( - canvas.width / (boundingBox.maxX - boundingBox.minX), - canvas.height / (boundingBox.maxY - boundingBox.minY) - ); - let initialxOffset = (canvas.width - (boundingBox.maxX - boundingBox.minX)*initialScalingFactor) / 2; - let initialyOffset = (canvas.height - (boundingBox.maxY - boundingBox.minY)*initialScalingFactor) / 2; - ctx.translate(initialxOffset, initialyOffset); - - - actualScaleFactor = initialScalingFactor; - - ctx.scale(initialScalingFactor, initialScalingFactor); - ctx.translate(-boundingBox.minX, -boundingBox.minY); - - function clearContext(ctx) { - ctx.save(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - } - - /** - * Carries out a drawing routine on the canvas with resetting the scaling / translation of the canvas - * and restoring it afterwards. - * This allows for drawing equally thick lines no matter what the zoomlevel of the canvas currently is. - * - * @param {CanvasRenderingContext2D} ctx - the rendering context to draw on (needs to have "trackTransforms" applied) - * @param {Function} f - the drawing routine to carry out on the rendering context - */ - function usingOwnTransform(ctx, f) { - const transform = ctx.getTransform(); - ctx.save(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - f(ctx, transform); - ctx.restore(); - } - - /** - * The function for rendering everything - * - Applies the map image from a seperate canvas inside the mapDrawer - * - Draws the locations - */ - function redraw() { - clearContext(ctx); - ctx.drawImage(mapDrawer.canvas, 0, 0); - - ctx.drawImage(pathSvg, 0, 0); - ctx.drawImage(predictedPathSvg, 0, 0); - - usingOwnTransform(ctx, (ctx, transform) => { - locations.forEach(location => { - location.draw(ctx, transform, actualScaleFactor); - }); - }); - } - - redraw(); - redrawCanvas = redraw; - - let lastX = canvas.width / 2, lastY = canvas.height / 2; - - let dragStart; - - function startTranslate(evt) { - const {x, y} = relativeCoordinates(evt.coordinates, canvas); - lastX = x; - lastY = y; - dragStart = ctx.transformedPoint(lastX, lastY); - } - - function moveTranslate(evt) { - const {x, y} = relativeCoordinates(evt.currentCoordinates, canvas); - const oldX = lastX; - const oldY = lastY; - lastX = x; - lastY = y; - - if (dragStart) { - // Let each location handle the panning event - // the location can return a stopPropagation bool which - // stops the event handling by other locations / the main canvas - for (let i = 0; i < locations.length; ++i) { - const location = locations[i]; - if (typeof location.translate === "function") { - const result = location.translate( - dragStart.matrixTransform(ctx.getTransform().inverse()), - {x: oldX, y: oldY}, - {x, y}, - ctx.getTransform() - ); - if (result.updatedLocation) { - locations[i] = result.updatedLocation; - } else { - locations.splice(i, 1); - i--; - } - if (result.stopPropagation === true) { - redraw(); - return; - } - } - } - // locations could be removed - // not quite nice to handle with the for loop - locations = locations.filter(location => location !== null); - - // If no location stopped event handling -> pan the whole map - const pt = ctx.transformedPoint(lastX, lastY); - ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y); - redraw(); - } - } - - function endTranslate(evt) { - dragStart = null; - - locations.forEach(location => { - if (location.isResizing) { - location.isResizing = false; - } - - if (typeof location.postProcess === "function") { - location.postProcess(); - } - }); - - redraw(); - } - - function tap(evt) { - const {x, y} = relativeCoordinates(evt.tappedCoordinates, canvas); - const tappedX = x; - const tappedY = y; - const tappedPoint = ctx.transformedPoint(tappedX, tappedY); - - // Let each location handle the tapping event - // the location can return a stopPropagation bool which - // stops the event handling by other locations / the main canvas - for (let i = 0; i < locations.length; ++i) { - const location = locations[i]; - - if (typeof location.tap === "function") { - const result = location.tap({x: tappedX, y: tappedY}, ctx.getTransform()); - - if (result.updatedLocation) { - locations[i] = result.updatedLocation; - } else { - locations.splice(i, 1); - i--; - } - - if (result.stopPropagation === true) { - redraw(); - return; - } - } - } - - // remove previous goto point if there is any - locations = locations.filter(l => !(l instanceof GotoPoint)); - const zones = locations.filter(l => l instanceof Zone); - if (zones.length === 0 && !options.noGotoPoints) { - locations.push(new GotoPoint(tappedPoint.x, tappedPoint.y)); - } - - redraw(); - } - - // eslint-disable-next-line no-unused-vars - const touchHandler = new TouchHandler(canvas); - - canvas.addEventListener("tap", tap); - canvas.addEventListener("panstart", startTranslate); - canvas.addEventListener("panmove", moveTranslate); - canvas.addEventListener("panend", endTranslate); - canvas.addEventListener("pinchstart", startPinch); - canvas.addEventListener("pinchmove", scalePinch); - canvas.addEventListener("pinchend", endPinch); - - - let lastScaleFactor = 1; - - function startPinch(evt) { - lastScaleFactor = 1; - - // translate - const {x, y} = relativeCoordinates(evt.center, canvas); - lastX = x; - lastY = y; - dragStart = ctx.transformedPoint(lastX, lastY); - } - - function endPinch(evt) { - // eslint-disable-next-line no-unused-vars - const [scaleX, scaleY] = ctx.getScaleFactor2d(); - actualScaleFactor = scaleX; - endTranslate(evt); - } - - function scalePinch(evt) { - const currentScaleFactor = ctx.getScaleFactor2d()[0]; - const factor = evt.scale / lastScaleFactor; - - if (factor * currentScaleFactor < 0.4 && factor < 1) { - return; - } else if (factor * currentScaleFactor > 150 && factor > 1) { - return; - } - - lastScaleFactor = evt.scale; - - const pt = ctx.transformedPoint(evt.center.x, evt.center.y); - ctx.translate(pt.x, pt.y); - ctx.scale(factor, factor); - ctx.translate(-pt.x, -pt.y); - - // translate - const {x, y} = relativeCoordinates(evt.center, canvas); - lastX = x; - lastY = y; - const p = ctx.transformedPoint(lastX, lastY); - ctx.translate(p.x - dragStart.x, p.y - dragStart.y); - - redraw(); - } - - const scaleFactor = 1.1; - /** - * Handles zooming by using the mousewheel. - * - * @param {WheelEvent} evt - */ - const handleScroll = function (evt) { - const delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0; - - if (delta) { - const currentScaleFactor = ctx.getScaleFactor2d()[0]; - const factor = parseFloat(Math.pow(scaleFactor, delta).toPrecision(2)); - - if (factor * currentScaleFactor < 0.4 && factor < 1) { - return; - } else if (factor * currentScaleFactor > 150 && factor > 1) { - return; - } - - const pt = ctx.transformedPoint(evt.offsetX, evt.offsetY); - ctx.translate(pt.x, pt.y); - ctx.scale(factor, factor); - ctx.translate(-pt.x, -pt.y); - - // eslint-disable-next-line no-unused-vars - const [scaleX, scaleY] = ctx.getScaleFactor2d(); - actualScaleFactor = scaleX; - - redraw(); - } - - return evt.preventDefault() && false; - }; - - canvas.addEventListener("DOMMouseScroll", handleScroll, false); - canvas.addEventListener("mousewheel", handleScroll, false); - } - - const prepareGotoCoordinatesForApi = (gotoPoint) => { - const point = convertToRealCoords(gotoPoint); - return { - x: point.x, - y: point.y - }; - }; - - const prepareZoneCoordinatesForApi = (zone) => { - const p1Real = convertToRealCoords({x: zone.x1, y: zone.y1}); - const p2Real = convertToRealCoords({x: zone.x2, y: zone.y2}); - - return [ - Math.min(p1Real.x, p2Real.x), - Math.min(p1Real.y, p2Real.y), - Math.max(p1Real.x, p2Real.x), - Math.max(p1Real.y, p2Real.y) - ]; - }; - - const prepareWallCoordinatesForApi = (virtualWall) => { - const p1Real = convertToRealCoords({x: virtualWall.x1, y: virtualWall.y1}); - const p2Real = convertToRealCoords({x: virtualWall.x2, y: virtualWall.y2}); - return [ - p1Real.x, - p1Real.y, - p2Real.x, - p2Real.y - ]; - }; - - const prepareFobriddenZoneCoordinatesForApi = (Zone) => { - const p1Real = convertToRealCoords({x: Zone.x1, y: Zone.y1}); - // eslint-disable-next-line no-unused-vars - const p2Real = convertToRealCoords({x: Zone.x2, y: Zone.y2}); - const p3Real = convertToRealCoords({x: Zone.x3, y: Zone.y3}); - // eslint-disable-next-line no-unused-vars - const p4Real = convertToRealCoords({x: Zone.x4, y: Zone.y4}); - // right now will make this a mandatory rectangle - custom quadrilaterals would do later, if ever - return [ - Math.min(p1Real.x, p3Real.x), - Math.min(p1Real.y, p3Real.y), - Math.max(p1Real.x, p3Real.x), - Math.min(p1Real.y, p3Real.y), - Math.max(p1Real.x, p3Real.x), - Math.max(p1Real.y, p3Real.y), - Math.min(p1Real.x, p3Real.x), - Math.max(p1Real.y, p3Real.y) - ]; - }; - - function getLocations() { - const zones = locations - .filter(location => location instanceof Zone) - .map(prepareZoneCoordinatesForApi); - - const gotoPoints = locations - .filter(location => location instanceof GotoPoint) - .map(prepareGotoCoordinatesForApi); - - const virtualWalls = locations - .filter(location => location instanceof VirtualWall) - .map(prepareWallCoordinatesForApi); - - const forbiddenZones = locations - .filter(location => location instanceof ForbiddenZone) - .map(prepareFobriddenZoneCoordinatesForApi); - - const forbiddenMopZones = locations - .filter(location => location instanceof ForbiddenMopZone) - .map(prepareFobriddenZoneCoordinatesForApi); - - const selectedSegments = locations.filter(l => l instanceof SegmentLabel && l.selected === true); - - return { - zones, - gotoPoints, - virtualWalls, - forbiddenZones, - forbiddenMopZones, - selectedSegments: selectedSegments - }; - } - - function addZone(zoneCoordinates, addZoneInactive) { - let newZone; - if (zoneCoordinates) { - const p1 = convertFromRealCoords({x: zoneCoordinates[0], y: zoneCoordinates[1]}); - const p2 = convertFromRealCoords({x: zoneCoordinates[2], y: zoneCoordinates[3]}); - newZone = new Zone(p1.x, p1.y, p2.x, p2.y); - } else { - let halfX = size.x/2; - let halfY = size.y/2; - - const p1 = convertFromRealCoords({x: halfX-64, y: halfY-64}); - const p2 = convertFromRealCoords({x: halfX+64, y: halfY+64}); - - newZone = new Zone(p1.x, p1.y, p2.x, p2.y); - } - - if (addZoneInactive) { - newZone.active = false; - } - - locations.forEach(location => location.active = false); - locations.push(newZone); - if (redrawCanvas) { - redrawCanvas(); - } - } - - function addSpot(spotCoordinates) { - const p = convertFromRealCoords({x: spotCoordinates[0], y: spotCoordinates[1]}); - const newSpot = new GotoPoint(p.x, p.y); - - locations.forEach(location => location.active = false); - locations.push(newSpot); - if (redrawCanvas) { - redrawCanvas(); - } - } - - function addVirtualWall(wallCoordinates, addWallInactive, wallEditable) { - let newVirtualWall; - - if (wallCoordinates) { - const p1 = convertFromRealCoords({x: wallCoordinates[0], y: wallCoordinates[1]}); - const p2 = convertFromRealCoords({x: wallCoordinates[2], y: wallCoordinates[3]}); - newVirtualWall = new VirtualWall(p1.x, p1.y, p2.x, p2.y, wallEditable); - } else { - let halfX = size.x/2; - let halfY = size.y/2; - - const p1 = convertFromRealCoords({x: halfX-64, y: halfY-64}); - const p2 = convertFromRealCoords({x: halfX+64, y: halfY+64}); - - console.log(size); - - newVirtualWall = new VirtualWall(p1.x, p1.y, p2.x, p2.y, wallEditable); - } - - if (addWallInactive) { - newVirtualWall.active = false; - } - - locations.forEach(location => location.active = false); - locations.push(newVirtualWall); - if (redrawCanvas) { - redrawCanvas(); - } - } - - function addForbiddenZone(zoneCoordinates, addZoneInactive, zoneEditable) { - let newZone; - - if (zoneCoordinates) { - const p1 = convertFromRealCoords({x: zoneCoordinates[0], y: zoneCoordinates[1]}); - const p2 = convertFromRealCoords({x: zoneCoordinates[2], y: zoneCoordinates[3]}); - const p3 = convertFromRealCoords({x: zoneCoordinates[4], y: zoneCoordinates[5]}); - const p4 = convertFromRealCoords({x: zoneCoordinates[6], y: zoneCoordinates[7]}); - newZone = new ForbiddenZone(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, zoneEditable); - } else { - let halfX = size.x/2; - let halfY = size.y/2; - - const p1 = convertFromRealCoords({x: halfX-64, y: halfY-64}); - const p2 = convertFromRealCoords({x: halfX+64, y: halfY-64}); - const p3 = convertFromRealCoords({x: halfX+64, y: halfY+64}); - const p4 = convertFromRealCoords({x: halfX-64, y: halfY+64}); - - newZone = new ForbiddenZone(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, zoneEditable); - } - - if (addZoneInactive) { - newZone.active = false; - } - - locations.forEach(location => location.active = false); - locations.push(newZone); - if (redrawCanvas) { - redrawCanvas(); - } - } - - function addForbiddenMopZone(zoneCoordinates, addZoneInactive, zoneEditable) { - let newZone; - - if (zoneCoordinates) { - const p1 = convertFromRealCoords({x: zoneCoordinates[0], y: zoneCoordinates[1]}); - const p2 = convertFromRealCoords({x: zoneCoordinates[2], y: zoneCoordinates[3]}); - const p3 = convertFromRealCoords({x: zoneCoordinates[4], y: zoneCoordinates[5]}); - const p4 = convertFromRealCoords({x: zoneCoordinates[6], y: zoneCoordinates[7]}); - newZone = new ForbiddenMopZone(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, zoneEditable); - } else { - let halfX = size.x/2; - let halfY = size.y/2; - - const p1 = convertFromRealCoords({x: halfX-64, y: halfY-64}); - const p2 = convertFromRealCoords({x: halfX+64, y: halfY-64}); - const p3 = convertFromRealCoords({x: halfX+64, y: halfY+64}); - const p4 = convertFromRealCoords({x: halfX-64, y: halfY+64}); - - newZone = new ForbiddenMopZone(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, zoneEditable); - } - - if (addZoneInactive) { - newZone.active = false; - } - - locations.forEach(location => location.active = false); - locations.push(newZone); - if (redrawCanvas) { - redrawCanvas(); - } - } - - return { - initCanvas: initCanvas, - initSSE: initSSE, - closeSSEConnection: closeSSEConnection, - updateMap: updateMap, - getLocations: getLocations, - addZone: addZone, - addSpot: addSpot, - addVirtualWall: addVirtualWall, - addForbiddenZone: addForbiddenZone, - addForbiddenMopZone: addForbiddenMopZone - }; -} - -/** - * Helper function for calculating coordinates relative to an HTML Element - * - * @param {{x: number, y: number}} "{x, y}" - the absolute screen coordinates (clicked) - * @param {*} referenceElement - the element (e.g. a canvas) to which - * relative coordinates should be calculated - * @returns {{x: number, y: number}} coordinates relative to the referenceElement - */ -function relativeCoordinates({x, y}, referenceElement) { - var rect = referenceElement.getBoundingClientRect(); - return { - x: x - rect.left, - y: y - rect.top - }; -} diff --git a/old_frontend/lib/js/onsenui.min.js b/old_frontend/lib/js/onsenui.min.js deleted file mode 100644 index 75fdcea7..00000000 --- a/old_frontend/lib/js/onsenui.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/* onsenui v2.10.1 - 2018-05-28 */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.ons=e()}(this,function(){"use strict";function t(t){kt.set(t,!0)}function e(t){var e=wt.get(t,[])||[];wt.delete(t),e.forEach(function(t){return t()})}function n(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){};if(void 0===kt&&(kt=new WeakMap,wt=new WeakMap),function(t,e){wt.has(t)||wt.set(t,[]),wt.get(t).push(e)}(n,i),function(e){return e.childNodes.length>0&&t(e),kt.has(e)}(n))e(n);else{new MutationObserver(function(i){t(n),e(n)}).observe(n,{childList:!0,characterData:!0}),setImmediate(function(){t(n),e(n)})}}function i(t){t._destroy instanceof Function?t._destroy():t.remove()}function o(t,e){return e={exports:{}},t(e,e.exports),e.exports}function r(t){var e=gi.has(t),n=/^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(t);return!e&&n}function a(t){var e=t.isConnected;if(void 0!==e)return e;for(var n=t;n&&!(n.__CE_isImportDocument||n instanceof Document);)n=n.parentNode||(window.ShadowRoot&&n instanceof ShadowRoot?n.host:void 0);return!(!n||!(n.__CE_isImportDocument||n instanceof Document))}function s(t,e){for(var n=e;n&&n!==t&&!n.nextSibling;)n=n.parentNode;return n&&n!==t?n.nextSibling:null}function l(t,e){for(var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new Set,i=t;i;){if(i.nodeType===Node.ELEMENT_NODE){var o=i;e(o);var r=o.localName;if("link"===r&&"import"===o.getAttribute("rel")){var a=o.import;if(a instanceof Node&&!n.has(a)){n.add(a);for(var u=a.firstChild;u;u=u.nextSibling)l(u,e,n)}i=s(t,o);continue}if("template"===r){i=s(t,o);continue}var c=o.__CE_shadowRoot;if(c)for(var h=c.firstChild;h;h=h.nextSibling)l(h,e,n)}i=function(t,e){return e.firstChild?e.firstChild:s(t,e)}(t,i)}}function u(t,e,n){t[e]=n}var c={},h=function(){var t=window.getComputedStyle(document.documentElement,""),e=(Array.prototype.slice.call(t).join("").match(/-(moz|webkit|ms)-/)||""===t.OLink&&["","o"])[1];return function(t){return"-"+e+"-"+Q.hyphenate(t)}}(),d=function(t,e){return Object.keys(e).forEach(function(n){n in t.style?t.style[n]=e[n]:h(n)in t.style?t.style[h(n)]=e[n]:Q.warn("No such style property: "+n)}),t};d.clear=function(t){for(var e=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:"").split(/\s+/).reduce(function(t,e){return t.concat([Q.hyphenate(e),h(e)])},[]),n=[],i=t.style.length-1;i>=0;i--)!function(i){var o=t.style[i];(0===e.length||e.some(function(t){return 0===o.indexOf(t)}))&&n.push(o)}(i);n.forEach(function(e){return t.style[e]=""}),""===t.getAttribute("style")&&t.removeAttribute("style")};var f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},g=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,i)&&(n[i]=t[i]);return n},k=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},w=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e=7;if(/iPhone|iPad|iPod/i.test(navigator.userAgent)){var t=(navigator.userAgent.match(/\b[0-9]+_[0-9]+(?:_[0-9]+)?\b/)||[""])[0].replace(/_/g,".");return parseInt(t.split(".")[0])>=7}return!1}},{key:"isIOSSafari",value:function(){var t=window.navigator,e=t.userAgent;return!(!this.isIOS()||-1===e.indexOf("Safari")||-1===e.indexOf("Version")||t.standalone)}},{key:"isWKWebView",value:function(){var t=/constructor/i.test(E);return!(!(this.isIOS()&&window.webkit&&window.webkit.messageHandlers&&window.indexedDB)||t)}},{key:"isUIWebView",value:function(){return!(!this.isIOS()||this.isIOSSafari()||this.isWKWebView())}},{key:"isAndroidPhone",value:function(){return/Android/i.test(navigator.userAgent)&&/Mobile/i.test(navigator.userAgent)}},{key:"isAndroidTablet",value:function(){return/Android/i.test(navigator.userAgent)&&!/Mobile/i.test(navigator.userAgent)}},{key:"isAndroid",value:function(){return this._getSelectedPlatform()?"android"===this._getSelectedPlatform():/Android/i.test("object"!==("undefined"==typeof device?"undefined":f(device))||/browser/i.test(device.platform)?navigator.userAgent:device.platform)}},{key:"isWP",value:function(){return this._getSelectedPlatform()?"wp"===this._getSelectedPlatform():"object"!==("undefined"==typeof device?"undefined":f(device))||/browser/i.test(device.platform)?/Windows Phone|IEMobile|WPDesktop/i.test(navigator.userAgent):/Win32NT|WinCE/i.test(device.platform)}},{key:"isBlackBerry",value:function(){return this._getSelectedPlatform()?"blackberry"===this._getSelectedPlatform():"object"!==("undefined"==typeof device?"undefined":f(device))||/browser/i.test(device.platform)?/BlackBerry|RIM Tablet OS|BB10/i.test(navigator.userAgent):/BlackBerry/i.test(device.platform)}},{key:"isOpera",value:function(){return this._getSelectedPlatform()?"opera"===this._getSelectedPlatform():!!window.opera||navigator.userAgent.indexOf(" OPR/")>=0}},{key:"isFirefox",value:function(){return this._getSelectedPlatform()?"firefox"===this._getSelectedPlatform():"undefined"!=typeof InstallTrigger}},{key:"isSafari",value:function(){return this._getSelectedPlatform()?"safari"===this._getSelectedPlatform():Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0||"[object SafariRemoteNotification]"===(!window["safari"]||safari.pushNotification).toString()}},{key:"isChrome",value:function(){return this._getSelectedPlatform()?"chrome"===this._getSelectedPlatform():!(!window.chrome||window.opera||navigator.userAgent.indexOf(" OPR/")>=0||navigator.userAgent.indexOf(" Edge/")>=0)}},{key:"isIE",value:function(){return this._getSelectedPlatform()?"ie"===this._getSelectedPlatform():!!document.documentMode}},{key:"isEdge",value:function(){return this._getSelectedPlatform()?"edge"===this._getSelectedPlatform():navigator.userAgent.indexOf(" Edge/")>=0}},{key:"getMobileOS",value:function(){return this.isAndroid()?"android":this.isIOS()?"ios":this.isWP()?"wp":"other"}},{key:"getIOSDevice",value:function(){return this.isIPhone()?"iphone":this.isIPad()?"ipad":this.isIPod()?"ipod":"na"}}]),t}()),A=function(t){return Q.throw("In PageAttributeExpression: "+t)},S={_variables:{},defineVariable:function(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];"string"!=typeof t?A("Variable name must be a string"):"string"!=typeof e&&"function"!=typeof e?A("Variable value must be a string or a function"):this._variables.hasOwnProperty(t)&&!n&&A('"'+t+'" is already defined'),this._variables[t]=e},getVariable:function(t){return this._variables.hasOwnProperty(t)?this._variables[t]:null},removeVariable:function(t){delete this._variables[t]},getAllVariables:function(){return this._variables},_parsePart:function(t){var e=void 0,n=!1,i=0,o=[];0===t.length&&A("Unable to parse empty string");for(var r=0;r0&&o.push(t.substring(i,r)),i=r,n=!0}else if("}"===e){n||A("} must be preceeded by ${");t.substring(i,r+1).length>0&&o.push(t.substring(i,r+1)),i=r+1,n=!1}return n&&A("Unterminated interpolation"),o.push(t.substring(i,t.length)),o},_replaceToken:function(t){var e=t.match(/^\${(.*?)}$/);if(!e)return t;var n=e[1].trim(),i=this.getVariable(n);if(null!==i){if("string"==typeof i)return i;var o=i();return"string"!=typeof o&&A("Must return a string"),o}A('Variable "'+n+'" does not exist')},_replaceTokens:function(t){return t.map(this._replaceToken.bind(this))},_parseExpression:function(t){return t.split(",").map(function(t){return t.trim()}).map(this._parsePart.bind(this)).map(this._replaceTokens.bind(this)).map(function(t){return t.join("")})},evaluate:function(t){return t?this._parseExpression(t):[]}};S.defineVariable("mobileOS",C.getMobileOS()),S.defineVariable("iOSDevice",C.getIOSDevice()),S.defineVariable("runtime",function(){return C.isWebView()?"cordova":"browser"});var P={};P.config={autoStatusBarFill:!0,animationsDisabled:!1,warningsDisabled:!1},P.nullElement=window.document.createElement("div"),P.isEnabledAutoStatusBarFill=function(){return!!P.config.autoStatusBarFill},P.normalizePageHTML=function(t){return(""+t).trim()},P.waitDOMContentLoaded=function(t){if("loading"===window.document.readyState||"uninitialized"==window.document.readyState){window.document.addEventListener("DOMContentLoaded",function e(){t(),window.document.removeEventListener("DOMContentLoaded",e)})}else setImmediate(t)},P.autoStatusBarFill=function(t){var e=function e(){P.shouldFillStatusBar()&&t(),document.removeEventListener("deviceready",e)};"object"===("undefined"==typeof device?"undefined":f(device))?document.addEventListener("deviceready",e):-1===["complete","interactive"].indexOf(document.readyState)?P.waitDOMContentLoaded(e):e()},P.shouldFillStatusBar=function(){return P.isEnabledAutoStatusBarFill()&&(C.isWebView()&&C.isIOS7above()&&!C.isIPhoneX()||document.body.querySelector(".ons-status-bar-mock.ios"))},P.templateStore={_storage:{},get:function(t){return P.templateStore._storage[t]||null},set:function(t,e){P.templateStore._storage[t]=e}},window.document.addEventListener("_templateloaded",function(t){"ons-template"===t.target.nodeName.toLowerCase()&&P.templateStore.set(t.templateId,t.template)},!1),P.waitDOMContentLoaded(function(){function t(t){for(var e=window.document.querySelectorAll(t),n=0;n=400&&s.status<600)n(i);else{var o=Q.createFragment(i);Q.arrayFrom(o.querySelectorAll("script")).forEach(function(t){var e=document.createElement("script");e.type=t.type||"text/javascript",e.appendChild(document.createTextNode(t.text||t.textContent||t.innerHTML)),t.parentNode.replaceChild(e,t)}),P.templateStore.set(t,o),e(o)}},s.onerror=function(){Q.throw("Page template not found: "+t)},s.send(null)})})},P.getPageHTMLAsync=function(t){var e=S.evaluate(t);return function t(n){return"string"!=typeof n?Promise.reject("Must specify a page."):P.getTemplateHTMLAsync(n).catch(function(n){return 0===e.length?Promise.reject(n):t(e.shift())})}(e.shift())};var O=function(){function t(e){p(this,t),this._animators=e.animators,this._baseClass=e.baseClass,this._baseClassName=e.baseClassName||e.baseClass.name,this._animation=e.defaultAnimation||"default",this._animationOptions=e.defaultAnimationOptions||{},this._animators[this._animation]||Q.throw("No such animation: "+this._animation)}return g(t,[{key:"setAnimationOptions",value:function(t){this._animationOptions=t}},{key:"newAnimator",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments[1],n=null;if(t.animation instanceof this._baseClass)return t.animation;var i=null;if("string"==typeof t.animation&&(i=this._animators[t.animation]),!i&&e)n=e;else{i=i||this._animators[this._animation];var o=Q.extend({},this._animationOptions,t.animationOptions||{},P.config.animationsDisabled?{duration:0,delay:0}:{});"function"==typeof(n=new i(o))&&(n=new n(o))}return n instanceof this._baseClass||Q.throw('"animator" is not an instance of '+this._baseClassName),n}}],[{key:"parseAnimationOptionsString",value:function(t){try{if("string"==typeof t){var e=Q.animationOptionsParse(t);if("object"===(void 0===e?"undefined":f(e))&&null!==e)return e;console.error('"animation-options" attribute must be a JSON object string: '+t)}return{}}catch(e){return console.error('"animation-options" attribute must be a JSON object string: '+t),{}}}}]),t}(),x=!0,T={quiet:"material--flat",light:"material--flat",outline:"material--flat",cta:"","large--quiet":"material--flat large","large--cta":"large",noborder:"",tappable:""},L={};L.android=function(t){var e=t.tagName.toLowerCase();if(!Q.hasModifier(t,"material")){var n=(t.getAttribute("modifier")||"").trim().split(/\s+/).map(function(t){return T.hasOwnProperty(t)?T[t]:t});n.unshift("material"),t.setAttribute("modifier",n.join(" ").trim())}-1===["ons-alert-dialog-button","ons-toolbar-button","ons-back-button","ons-button","ons-list-item","ons-fab","ons-speed-dial","ons-speed-dial-item","ons-tab"].indexOf(e)||t.hasAttribute("ripple")||t.querySelector("ons-ripple")||("ons-list-item"===e?t.hasAttribute("tappable")&&(t.setAttribute("ripple",""),t.removeAttribute("tappable")):t.setAttribute("ripple",""))},L.ios=function(t){Q.removeModifier(t,"material")&&(Q.removeModifier(t,"material--flat")&&Q.addModifier(t,Q.removeModifier(t,"large")?"large--quiet":"quiet"),t.getAttribute("modifier")||t.removeAttribute("modifier")),t.hasAttribute("ripple")&&("ons-list-item"===t.tagName.toLowerCase()&&t.setAttribute("tappable",""),t.removeAttribute("ripple"))};var M={android:!0},D=function(t,e){if(x&&!t.hasAttribute("disable-auto-styling")){var n=C.getMobileOS();if(L.hasOwnProperty(n)&&(M.hasOwnProperty(n)||e))return n}return null},I=function(t,e,n){return D(e,n)?t.split(/\s+/).map(function(t){return T.hasOwnProperty(t)?T[t]:t}).join(" "):t},N={isEnabled:function(){return x},enable:function(){return x=!0},disable:function(){return x=!1},prepare:function(t,e){var n=D(t,e);n&&L[n](t)},mapModifier:I,getPlatform:D,restoreModifier:function(t){if("android"===D(t)){var e=t.getAttribute("modifier")||"",n=I(e,t);if(/(^|\s+)material($|\s+)/i.test(e)||(n="material "+n),n!==e)return t.setAttribute("modifier",n.trim()),!0}return!1}},B=function(){function t(){p(this,t)}return g(t,null,[{key:"diff",value:function(e,n){function i(e){var n={};return t.split(e).forEach(function(t){return n[t]=t}),n}e=i((""+e).trim()),n=i((""+n).trim());var o=Object.keys(e).reduce(function(t,e){return n[e]||t.push(e),t},[]);return{added:Object.keys(n).reduce(function(t,n){return e[n]||t.push(n),t},[]),removed:o}}},{key:"applyDiffToClassList",value:function(t,e,n){t.added.map(function(t){return n.replace(/\*/g,t)}).forEach(function(t){return t.split(/\s+/).forEach(function(t){return e.add(t)})}),t.removed.map(function(t){return n.replace(/\*/g,t)}).forEach(function(t){return t.split(/\s+/).forEach(function(t){return e.remove(t)})})}},{key:"applyDiffToElement",value:function(e,n,i){Object.keys(i).forEach(function(o){for(var r=!o||Q.match(n,o)?[n]:Array.prototype.filter.call(n.querySelectorAll(o),function(t){return!Q.findParent(t,n.tagName,function(t){return t===n})}),a=0;ai?t:e;throw new Error("Capturing backbutton-handler is failure.")},null)}return e(t)}}]),t}());P.AnimatorFactory=O,P.ModifierUtil=B,P.dbbDispatcher=R;var F=function(t,e){return t.substr(0,e.length)===e},q=function(t,e){return t.substr(t.length-e.length,e.length)===e},z=function(t){return t.slice(1,-1)},V=function(t){return F(t,"{")&&q(t,"}")},W=function(t){return F(t,"[")&&q(t,"]")},U=function(t){return F(t,"'")&&q(t,"'")||F(t,'"')&&q(t,'"')},X=function(t,e,n){throw new Error("Unexpected token '"+t+"' at position "+(n.length-e.length-1)+" in string: '"+n+"'")},Y=function(t,e,n){return"true"===t||"false"===t?"true"===t:U(t)?z(t):isNaN(t)?V(t)?$(z(t)):W(t)?K(z(t)):void X(t,e,n):+t},G=function(t){var e=(t=t.trim()).length;if(":"===t[0]||","===t[0])e=1;else if("{"===t[0]||"["===t[0]){for(var n=t.charCodeAt(0),i=1,o=1;o0;)if(r=a,a=G(t),t=t.slice(a.length,t.length).trim(),":"===a&&(!i||!r||","===r)||","===a&&i||":"!==a&&","!==a&&r&&","!==r&&":"!==r)X(a,t,e);else if(":"===a&&i&&r){if(r=U(r)?z(r):r,!function(t){return/^[A-Z_$][A-Z0-9_$]*$/i.test(t)}(r))throw new Error("Invalid key token '"+r+"' at position 0 in string: '"+e+"'");o=r,i=!1}else","===a&&!i&&r&&(n[o]=Y(r,t,e),i=!0);return a&&(n[o]=Y(a,t,e)),n},K=function(t){for(var e=t=t.trim(),n=[],i=void 0,o=void 0;t.length>0;)i=o,o=G(t),t=t.slice(o.length,t.length).trim(),","!==o||i&&","!==i?","===o&&n.push(Y(i,t,e)):X(o,t,e);return o&&(","!==o?n.push(Y(o,t,e)):X(o,t,e)),n},Q={},J="[Onsen UI]";Q.globals={fabOffset:0,errorPrefix:J,supportsPassive:!1},C._runOnActualPlatform(function(){Q.globals.actualMobileOS=C.getMobileOS(),Q.globals.isUIWebView=C.isUIWebView(),Q.globals.isWKWebView=C.isWKWebView()});try{var Z=Object.defineProperty({},"passive",{get:function(){Q.globals.supportsPassive=!0}});window.addEventListener("testPassive",null,Z),window.removeEventListener("testPassive",null,Z)}catch(t){}Q.addEventListener=function(t,e,n,i,o){t.addEventListener(e,n,Q.globals.supportsPassive?i:(i||{}).capture)},Q.removeEventListener=function(t,e,n,i,o){t.removeEventListener(e,n,Q.globals.supportsPassive?i:(i||{}).capture)},Q.prepareQuery=function(t){return t instanceof Function?t:function(e){return Q.match(e,t)}},Q.match=function(t,e){return(t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.msMatchesSelector).call(t,e)},Q.findChild=function(t,e){for(var n=Q.prepareQuery(e),i=0;i0&&void 0!==arguments[0]?arguments[0]:"",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.split("."),i=document.createElement(n.shift()||"div");return n.length&&(i.className=n.join(" ")),d(i,e),i},Q.createElement=function(t){var e=document.createElement("div");t instanceof DocumentFragment?e.appendChild(document.importNode(t,!0)):e.innerHTML=t.trim(),e.children.length>1&&Q.throw("HTML template must contain a single root element");var n=e.children[0];return e.children[0].remove(),n},Q.createFragment=function(t){var e=document.createElement("template");return e.innerHTML=t,document.importNode(e.content,!0)},Q.extend=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),i=1;i1&&void 0!==arguments[1]?arguments[1]:{};try{var n=JSON.parse(""+t);if("object"===(void 0===n?"undefined":f(n))&&null!==n)return n}catch(t){return e}return e},Q.findFromPath=function(t){t=t.split(".");for(var e,n=window;e=t.shift();)n=n[e];return n},Q.getTopPage=function(t){return t&&("ons-page"===t.tagName.toLowerCase()?t:t.topPage)||null},Q.findToolbarPage=function(t){var e=Q.getTopPage(t);if(e){if(e._canAnimateToolbar())return e;for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:{},i=new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:n});return Object.keys(n).forEach(function(t){i[t]=n[t]}),t.dispatchEvent(i),i},Q.hasModifier=function(t,e){return!!t.hasAttribute("modifier")&&RegExp("(^|\\s+)"+e+"($|\\s+)","i").test(t.getAttribute("modifier"))},Q.addModifier=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return n.autoStyle&&(e=N.mapModifier(e,t,n.forceAutoStyle)),!Q.hasModifier(t,e)&&(t.setAttribute("modifier",((t.getAttribute("modifier")||"")+" "+e).trim()),!0)},Q.removeModifier=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(n.autoStyle&&(e=N.mapModifier(e,t,n.forceAutoStyle)),!t.getAttribute("modifier")||!Q.hasModifier(t,e))return!1;var i=t.getAttribute("modifier").split(/\s+/).filter(function(t){return t&&t!==e});return i.length?t.setAttribute("modifier",i.join(" ")):t.removeAttribute("modifier"),!0},Q.toggleModifier=function(){var t=arguments.length>2?arguments.length<=2?void 0:arguments[2]:{},e="boolean"==typeof t?t:t.force;("boolean"==typeof e?e:!Q.hasModifier.apply(Q,arguments))?Q.addModifier.apply(Q,arguments):Q.removeModifier.apply(Q,arguments)},Q.restoreClass=function(t,e,n){e.split(/\s+/).forEach(function(e){return""!==e&&!t.classList.contains(e)&&t.classList.add(e)}),t.hasAttribute("modifier")&&B.refresh(t,n)},Q.updateParentPosition=function(t){!t._parentUpdated&&t.parentElement&&("static"===window.getComputedStyle(t.parentElement).getPropertyValue("position")&&(t.parentElement.style.position="relative"),t._parentUpdated=!0)},Q.toggleAttribute=function(t,e,n){n?t.setAttribute(e,"boolean"==typeof n?"":n):t.removeAttribute(e)},Q.bindListeners=function(t,e){e.forEach(function(e){var n=e.replace(/^_[a-z]/,"_bound"+e[1].toUpperCase());t[n]=t[n]||t[e].bind(t)})},Q.each=function(t,e){return Object.keys(t).forEach(function(n){return e(n,t[n])})},Q.updateRipple=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};void 0===e&&(e=t.hasAttribute("ripple"));var i=Q.findChild(t,"ons-ripple");if(e){if(!i){var o=document.createElement("ons-ripple");Object.keys(n).forEach(function(t){return o.setAttribute(t,n[t])}),t.insertBefore(o,t.firstChild)}}else i&&i.remove()},Q.animationOptionsParse=function(t){if(t=t.trim(),V(t))return $(z(t));if(W(t))return K(z(t));throw new Error("Provided string must be object or array like: "+t)},Q.isInteger=function(t){return"number"==typeof t&&isFinite(t)&&Math.floor(t)===t},Q.defer=function(){var t={};return t.promise=new Promise(function(e,n){t.resolve=e,t.reject=n}),t},Q.warn=function(){for(var t=arguments.length,e=Array(t),n=0;n=r.charCodeAt(0)&&"cssText"!==r&&"parentText"!==r&&(e[r]=!0)}return e}(),et.hasCssProperty=function(t){return t in et._cssPropertyDict},et.vendorPrefix=function(){var t=window.getComputedStyle(document.documentElement,"");return(Array.prototype.slice.call(t).join("").match(/-(moz|webkit|ms)-/)||""===t.OLink&&["","o"])[1]}(),et.forceLayoutAtOnce=function(t,e){this.batchImmediate(function(){t.forEach(function(t){t.offsetHeight}),e()})},et.batchImmediate=function(){var t=[];return function(e){0===t.length&&setImmediate(function(){var e=t.slice(0);t=[],e.forEach(function(t){t()})}),t.push(e)}}(),et.batchAnimationFrame=function(){var t=[],e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){setTimeout(t,1e3/60)};return function(n){0===t.length&&e(function(){var e=t.slice(0);t=[],e.forEach(function(t){t()})}),t.push(n)}}(),et.transitionPropertyName=function(){if(et.hasCssProperty("transitionDuration"))return"transition";if(et.hasCssProperty(et.vendorPrefix+"TransitionDuration"))return et.vendorPrefix+"Transition";throw new Error("Invalid state")}();var nt=function t(e,n){if(!(this instanceof t))return new t(e,n);if(e instanceof HTMLElement)this.elements=[e];else{if("[object Array]"!==Object.prototype.toString.call(e))throw new Error("First argument must be an array or an instance of HTMLElement.");this.elements=e}this.defaults=n,this.transitionQueue=[],this.lastStyleAttributeDict=[]};nt.prototype={transitionQueue:void 0,elements:void 0,defaults:void 0,play:function(t){return"function"==typeof t&&this.transitionQueue.push(function(e){t(),e()}),this.startAnimation(),this},default:function(t,e,n){function i(t,e,n){return void 0!==t.duration&&(e=t.duration),void 0!==t.timing&&(n=t.timing),{css:t.css||t,duration:e,timing:n}}return this.saveStyle().queue(i(t,0,this.defaults.timing)).wait(void 0===n?this.defaults.delay:n).queue(i(e,this.defaults.duration,this.defaults.timing)).restoreStyle()},queue:function(t,e){var n=this.transitionQueue;if(t&&e&&(e.css=t,t=new nt.Transition(e)),t instanceof Function||t instanceof nt.Transition||(t=new nt.Transition(t.css?t:{css:t})),t instanceof Function)n.push(t);else{if(!(t instanceof nt.Transition))throw new Error("Invalid arguments");n.push(t.build())}return this},wait:function(t){return t>0&&this.transitionQueue.push(function(e){setTimeout(e,1e3*t)}),this},saveStyle:function(){return this.transitionQueue.push(function(t){this.elements.forEach(function(t,e){for(var n=this.lastStyleAttributeDict[e]={},i=0;i0){var i=t.transition||"all "+t.duration+"s "+(t.timing||"linear");this.transitionQueue.push(function(o){var r,a=this.elements,s=function(){a.forEach(function(t){t.style[n]=""})},l=et.onceOnTransitionEnd(a[0],function(){clearTimeout(r),s(),o()});r=setTimeout(function(){l(),s(),o()},1e3*t.duration*1.4),a.forEach(function(t,o){var r=e.lastStyleAttributeDict[o];if(!r)throw new Error("restoreStyle(): The style is not saved. Invoke saveStyle() before.");e.lastStyleAttributeDict[o]=void 0;for(var a,s=0,l=t.style.length;s0){var e=et.buildTransitionValue(this.options),n=this;return function(i){var o,r=this.elements,a=1e3*n.options.duration*1.4,s=et.onceOnTransitionEnd(r[0],function(){clearTimeout(o),i()});o=setTimeout(function(){s(),i()},a),r.forEach(function(n){n.style[et.transitionPropertyName]=e,Object.keys(t).forEach(function(e){n.style[e]=t[e]})})}}if(this.options.duration<=0)return function(e){var n=this.elements;n.forEach(function(e){e.style[et.transitionPropertyName]="",Object.keys(t).forEach(function(n){e.style[n]=t[n]})}),n.length>0?et.forceLayoutAtOnce(n,function(){et.batchAnimationFrame(e)}):et.batchAnimationFrame(e)}}};var it,ot,rt,at,st=function t(e,n){return new t.Instance(e,n||{})};st.defaults={behavior:{touchAction:"pan-y",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},st.DOCUMENT=document,st.HAS_POINTEREVENTS=navigator.pointerEnabled||navigator.msPointerEnabled,st.HAS_TOUCHEVENTS="ontouchstart"in window,st.IS_MOBILE=/mobile|tablet|ip(ad|hone|od)|android|silk/i.test(navigator.userAgent),st.NO_MOUSEEVENTS=st.HAS_TOUCHEVENTS&&st.IS_MOBILE||st.HAS_POINTEREVENTS,st.CALCULATE_INTERVAL=25;var lt={},ut=st.DIRECTION_DOWN="down",ct=st.DIRECTION_LEFT="left",ht=st.DIRECTION_UP="up",dt=st.DIRECTION_RIGHT="right",ft=st.POINTER_MOUSE="mouse",pt=st.POINTER_TOUCH="touch",gt=st.POINTER_PEN="pen",mt=st.EVENT_START="start",_t=st.EVENT_MOVE="move",vt=st.EVENT_END="end",bt=st.EVENT_RELEASE="release",yt=st.EVENT_TOUCH="touch";st.READY=!1,st.plugins=st.plugins||{},st.gestures=st.gestures||{},ot=st.utils={extend:function(t,e,n){for(var i in e)!e.hasOwnProperty(i)||void 0!==t[i]&&n||(t[i]=e[i]);return t},on:function(t,e,n,i){Q.addEventListener(t,e,n,i,!0)},off:function(t,e,n,i){Q.removeEventListener(t,e,n,i,!0)},each:function(t,e,n){var i,o;if("forEach"in t)t.forEach(e,n);else if(void 0!==t.length){for(i=0,o=t.length;i-1},inArray:function(t,e,n){if(n){for(var i=0,o=t.length;i=Math.abs(t.clientY-e.clientY)?t.clientX-e.clientX>0?ct:dt:t.clientY-e.clientY>0?ht:ut},getDistance:function(t,e){var n=e.clientX-t.clientX,i=e.clientY-t.clientY;return Math.sqrt(n*n+i*i)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(t){return t==ht||t==ut},setPrefixedCss:function(t,e,n,i){var o=["","Webkit","Moz","O","ms"];e=ot.toCamelCase(e);for(var r=0;r0&&this.started&&(a=_t),this.started=!0;var u=this.collectEventData(n,a,o,t);return e!=vt&&i.call(rt,u),s&&(u.changedLength=l,u.eventType=s,i.call(rt,u),u.eventType=a,delete u.changedLength),a==vt&&(i.call(rt,u),this.started=!1),a},determineEventTypes:function(){var t;return t=st.HAS_POINTEREVENTS?window.PointerEvent?["pointerdown","pointermove","pointerup pointercancel lostpointercapture"]:["MSPointerDown","MSPointerMove","MSPointerUp MSPointerCancel MSLostPointerCapture"]:st.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],lt[mt]=t[0],lt[_t]=t[1],lt[vt]=t[2],lt},getTouchList:function(t,e){if(st.HAS_POINTEREVENTS)return at.getTouchList();if(t.touches){if(e==_t)return t.touches;var n=[],i=[].concat(ot.toArray(t.touches),ot.toArray(t.changedTouches)),o=[];return ot.each(i,function(t){-1===ot.inArray(n,t.identifier)&&o.push(t),n.push(t.identifier)}),o}return t.identifier=1,[t]},collectEventData:function(t,e,n,i){var o=pt;return ot.inStr(i.type,"mouse")||at.matchType(ft,i)?o=ft:at.matchType(gt,i)&&(o=gt),{center:ot.getCenter(n),timeStamp:Date.now(),target:i.target,touches:n,eventType:e,pointerType:o,srcEvent:i,preventDefault:function(){var t=this.srcEvent;t.preventManipulation&&t.preventManipulation(),t.preventDefault&&t.preventDefault()},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return rt.stopDetect()}}}},at=st.PointerEvent={pointers:{},getTouchList:function(){var t=[];return ot.each(this.pointers,function(e){t.push(e)}),t},updatePointer:function(t,e){t==vt||t!=vt&&1!==e.buttons?delete this.pointers[e.pointerId]:(e.identifier=e.pointerId,this.pointers[e.pointerId]=e)},matchType:function(t,e){if(!e.pointerType)return!1;var n=e.pointerType,i={};return i[ft]=n===(e.MSPOINTER_TYPE_MOUSE||ft),i[pt]=n===(e.MSPOINTER_TYPE_TOUCH||pt),i[gt]=n===(e.MSPOINTER_TYPE_PEN||gt),i[t]},reset:function(){this.pointers={}}},rt=st.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(t,e){this.current||(this.stopped=!1,this.current={inst:t,startEvent:ot.extend({},e),lastEvent:!1,lastCalcEvent:!1,futureCalcEvent:!1,lastCalcData:{},name:""},this.detect(e))},detect:function(t){if(this.current&&!this.stopped){t=this.extendEventData(t);var e=this.current.inst,n=e.options;return ot.each(this.gestures,function(i){!this.stopped&&e.enabled&&n[i.name]&&i.handler.call(i,t,e)},this),this.current&&(this.current.lastEvent=t),t.eventType==vt&&this.stopDetect(),t}},stopDetect:function(){this.previous=ot.extend({},this.current),this.current=null,this.stopped=!0},getCalculatedData:function(t,e,n,i,o){var r=this.current,a=!1,s=r.lastCalcEvent,l=r.lastCalcData;s&&t.timeStamp-s.timeStamp>st.CALCULATE_INTERVAL&&(e=s.center,n=t.timeStamp-s.timeStamp,i=t.center.clientX-s.center.clientX,o=t.center.clientY-s.center.clientY,a=!0),t.eventType!=yt&&t.eventType!=bt||(r.futureCalcEvent=t),r.lastCalcEvent&&!a||(l.velocity=ot.getVelocity(n,i,o),l.angle=ot.getAngle(e,t.center),l.direction=ot.getDirection(e,t.center),r.lastCalcEvent=r.futureCalcEvent||t,r.futureCalcEvent=t),t.velocityX=l.velocity.x,t.velocityY=l.velocity.y,t.interimAngle=l.angle,t.interimDirection=l.direction},extendEventData:function(t){var e=this.current,n=e.startEvent,i=e.lastEvent||n;t.eventType!=yt&&t.eventType!=bt||(n.touches=[],ot.each(t.touches,function(t){n.touches.push({clientX:t.clientX,clientY:t.clientY})}));var o=t.timeStamp-n.timeStamp,r=t.center.clientX-n.center.clientX,a=t.center.clientY-n.center.clientY;return this.getCalculatedData(t,i.center,o,r,a),ot.extend(t,{startEvent:n,deltaTime:o,deltaX:r,deltaY:a,distance:ot.getDistance(n.center,t.center),angle:ot.getAngle(n.center,t.center),direction:ot.getDirection(n.center,t.center),scale:ot.getScale(n.touches,t.touches),rotation:ot.getRotation(n.touches,t.touches)}),t},register:function(t){var e=t.defaults||{};return void 0===e[t.name]&&(e[t.name]=!0),ot.extend(st.defaults,e,!0),t.index=t.index||1e3,this.gestures.push(t),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},st.Instance=function(t,e){var n=this,i=e&&e.passive?{passive:!0}:void 0;!function(t){st.READY||(it.determineEventTypes(),ot.each(st.gestures,function(t){rt.register(t)}),it.onTouch(st.DOCUMENT,_t,rt.detect,t),it.onTouch(st.DOCUMENT,vt,rt.detect,t),st.READY=!0)}(i),this.element=t,this.enabled=!0,ot.each(e,function(t,n){delete e[n],e[ot.toCamelCase(n)]=t}),this.options=ot.extend(ot.extend({},st.defaults),e||{}),this.options.listenerOptions=i,this.options.behavior&&ot.toggleBehavior(this.element,this.options.behavior,!0),this.eventStartHandler=it.onTouch(t,mt,function(t){n.enabled&&t.eventType==mt?rt.startDetect(n,t):t.eventType==yt&&rt.detect(t)},i),this.eventHandlers=[]},st.Instance.prototype={on:function(t,e,n){var i=this;return it.on(i.element,t,e,Q.extend({},i.options.listenerOptions,n),function(t){i.eventHandlers.push({gesture:t,handler:e})}),i},off:function(t,e,n){var i=this;return it.off(i.element,t,e,Q.extend({},i.options.listenerOptions,n),function(t){var n=ot.inArray(i.eventHandlers,{gesture:t,handler:e},!0);n>=0&&i.eventHandlers.splice(n,1)}),i},trigger:function(t,e){e||(e={});var n=st.DOCUMENT.createEvent("Event");n.initEvent(t,!0,!0),n.gesture=e;var i=this.element;return ot.hasParent(e.target,i)&&(i=e.target),i.dispatchEvent(n),this},enable:function(t){return this.enabled=t,this},dispose:function(){var t,e;for(ot.toggleBehavior(this.element,this.options.behavior,!1),t=-1;e=this.eventHandlers[++t];)ot.off(this.element,e.gesture,e.handler);return this.eventHandlers=[],it.off(this.element,lt[mt],this.eventStartHandler),null}},function(t){var e=!1;st.gestures.Drag={name:t,index:50,handler:function(n,i){var o=rt.current;if(!(i.options.dragMaxTouches>0&&n.touches.length>i.options.dragMaxTouches))switch(n.eventType){case mt:e=!1;break;case _t:if(n.distance0)){var a=Math.abs(i.options.dragMinDistance/n.distance);r.pageX+=n.deltaX*a,r.pageY+=n.deltaY*a,r.clientX+=n.deltaX*a,r.clientY+=n.deltaY*a,n=rt.extendEventData(n)}(o.lastEvent.dragLockToAxis||i.options.dragLockToAxis&&i.options.dragLockMinDistance<=n.distance)&&(n.dragLockToAxis=!0);var s=o.lastEvent.direction;n.dragLockToAxis&&s!==n.direction&&(ot.isVertical(s)?n.direction=n.deltaY<0?ht:ut:n.direction=n.deltaX<0?ct:dt),e||(i.trigger(t+"start",n),e=!0),i.trigger(t,n),i.trigger(t+n.direction,n);var l=ot.isVertical(n.direction);(i.options.dragBlockVertical&&l||i.options.dragBlockHorizontal&&!l)&&n.preventDefault();break;case bt:e&&n.changedLength<=i.options.dragMaxTouches&&(i.trigger(t+"end",n),e=!1);break;case vt:e=!1}},defaults:{dragMinDistance:10,dragDistanceCorrection:!0,dragMaxTouches:1,dragBlockHorizontal:!1,dragBlockVertical:!1,dragLockToAxis:!1,dragLockMinDistance:25}}}("drag"),st.gestures.Gesture={name:"gesture",index:1337,handler:function(t,e){e.trigger(this.name,t)}},function(t){var e;st.gestures.Hold={name:t,index:10,defaults:{holdTimeout:500,holdThreshold:2},handler:function(n,i){var o=i.options,r=rt.current;switch(n.eventType){case mt:clearTimeout(e),r.name=t,e=setTimeout(function(){r&&r.name==t&&i.trigger(t,n)},o.holdTimeout);break;case _t:n.distance>o.holdThreshold&&clearTimeout(e);break;case bt:clearTimeout(e)}}}}("hold"),st.gestures.Release={name:"release",index:1/0,handler:function(t,e){t.eventType==bt&&e.trigger(this.name,t)}},st.gestures.Swipe={name:"swipe",index:40,defaults:{swipeMinTouches:1,swipeMaxTouches:1,swipeVelocityX:.6,swipeVelocityY:.6},handler:function(t,e){if(t.eventType==bt){var n=t.touches.length,i=e.options;if(ni.swipeMaxTouches)return;(t.velocityX>i.swipeVelocityX||t.velocityY>i.swipeVelocityY)&&(e.trigger(this.name,t),e.trigger(this.name+t.direction,t))}}},function(t){var e=!1;st.gestures.Tap={name:t,index:100,handler:function(n,i){var o,r,a=i.options,s=rt.current,l=rt.previous;switch(n.eventType){case mt:e=!1;break;case _t:e=e||n.distance>a.tapMaxDistance;break;case vt:!ot.inStr(n.srcEvent.type,"cancel")&&n.deltaTimei.options.transformMinRotation&&i.trigger("rotate",n),o>i.options.transformMinScale&&(i.trigger("pinch",n),i.trigger("pinch"+(n.scale<1?"in":"out"),n));break;case bt:e&&n.changedLength<2&&(i.trigger(t+"end",n),e=!1)}}}}("transform");var kt=void 0,wt=void 0,Et=new(function(){function t(){p(this,t),this.queue=[]}return g(t,[{key:"add",value:function(t,e){var n=this;this.queue.push(t),1===this.queue.length&&setImmediate(this.queue[0]),e.then(function(){n.queue.shift(),n.queue.length>0&&setTimeout(n.queue[0],1e3/30)})}}]),t}()),Ct=function(t,e){["id","class","animation"].forEach(function(n){return e.hasOwnProperty(n)&&t.setAttribute(n,e[n])}),e.modifier&&Q.addModifier(t,e.modifier)},At=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return e=_({},e),"string"==typeof t?e.message=t:e=t,e&&(e.message||e.messageHTML)||Q.throw("Notifications must contain a message"),(e.hasOwnProperty("buttonLabels")||e.hasOwnProperty("buttonLabel"))&&(e.buttonLabels=e.buttonLabels||e.buttonLabel,Array.isArray(e.buttonLabels)||(e.buttonLabels=[e.buttonLabels||""])),Q.extend({compile:function(t){return t},callback:function(t){return t},animation:"default",cancelable:!1,primaryButtonIndex:(e.buttonLabels||n.buttonLabels||[]).length-1},n,e)},St={};St._createAlertDialog=function(){for(var t=arguments.length,e=Array(t),i=0;i\n ');var r="";i.buttonLabels.forEach(function(t,e){r+='\n \n '+t+"\n \n "});var a={},s=function(){a.dialog.onDialogCancel&&a.dialog.removeEventListener("dialog-cancel",a.dialog.onDialogCancel),Object.keys(a).forEach(function(t){return delete a[t]}),a=null,i.destroy instanceof Function&&i.destroy()};a.dialog=document.createElement("ons-alert-dialog"),a.dialog.innerHTML='\n
\n
\n
\n
\n '+(i.title||"")+'\n
\n
\n '+(i.message||i.messageHTML)+"\n "+o+'\n
\n
\n '+r+"\n
\n
\n
\n ",n(a.dialog),Ct(a.dialog,i),i.isPrompt&&i.submitOnEnter&&(a.input=a.dialog.querySelector(".text-input"),a.input.onkeypress=function(e){13===e.keyCode&&a.dialog.hide().then(function(){if(a){var e=a.input.value;s(),i.callback(e),t(e)}})}),a.footer=a.dialog.querySelector(".alert-dialog-footer"),Q.arrayFrom(a.dialog.querySelectorAll(".alert-dialog-button")).forEach(function(e,n){e.onclick=function(){a.dialog.hide().then(function(){if(a){var e=n;i.isPrompt&&(e=n===i.primaryButtonIndex?a.input.value:null),a.dialog.remove(),s(),i.callback(e),t(e)}})},a.footer.appendChild(e)}),i.cancelable&&(a.dialog.cancelable=!0,a.dialog.onDialogCancel=function(){setImmediate(function(){a.dialog.remove(),s()});var e=i.isPrompt?null:-1;i.callback(e),t(e)},a.dialog.addEventListener("dialog-cancel",a.dialog.onDialogCancel,!1)),document.body.appendChild(a.dialog),i.compile(a.dialog),setImmediate(function(){a.dialog.show().then(function(){if(a.input&&i.isPrompt&&i.autofocus){var t=a.input.value.length;a.input.focus(),a.input.setSelectionRange(t,t)}})})})},St.alert=function(t,e){return St._createAlertDialog(t,e,{buttonLabels:["OK"],title:"Alert"})},St.confirm=function(t,e){return St._createAlertDialog(t,e,{buttonLabels:["Cancel","OK"],title:"Confirm"})},St.prompt=function(t,e){return St._createAlertDialog(t,e,{buttonLabels:["OK"],title:"Alert",isPrompt:!0,autofocus:!0,submitOnEnter:!0})},St.toast=function(t,e){var n=new Promise(function(i){Q.checkMissingImport("Toast"),e=At(t,e,{timeout:0,force:!1});var o=Q.createElement("\n \n "+e.message+"\n "+(e.buttonLabels?"":"")+"\n \n ");Ct(o,e);var r=function(t){o&&o.hide().then(function(){o&&(o.remove(),o=null,e.callback(t),i(t))})};e.buttonLabels&&(Q.findChild(o._toast,"button").onclick=function(){return r(0)}),document.body.appendChild(o),e.compile(o);var a=function(){o.parentElement&&o.show(e).then(function(){e.timeout&&setTimeout(function(){return r(-1)},e.timeout)})};setImmediate(function(){return e.force?a():Et.add(a,n)})});return n};var Pt=function(){};Pt.prototype={on:function(t,e){this._events=this._events||{},this._events[t]=this._events[t]||[],this._events[t].push(e)},once:function(t,e){var n=this;this.on(t,function i(){return n.off(t,i),e.apply(null,arguments)})},off:function(t,e){this._events=this._events||{},t in this._events!=!1&&(this._events[t]=this._events[t].filter(function(t){return!!e&&e!==t}))},emit:function(t){if(this._events=this._events||{},t in this._events!=!1)for(var e=0;ewindow.innerWidth},this},_onDOMContentLoaded:function(){this._installIsPortraitImplementation(),this.emit("change",{isPortrait:this.isPortrait()})},_installIsPortraitImplementation:function(){var t=window.innerWidthwindow.innerWidth}},_onOrientationChange:function(){var t=this,e=this._isPortrait(),n=0,i=setInterval(function(){n++;var o=window.innerWidth,r=window.innerHeight;e&&o<=r||!e&&o>=r?(t.emit("change",{isPortrait:e}),clearInterval(i)):50===n&&(t.emit("change",{isPortrait:e}),clearInterval(i))},20)},_onResize:function(){this.emit("change",{isPortrait:this.isPortrait()})}};return Pt.mixin(t),t}()._init(),xt={add:function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),i=1;i1?e-1:0),i=1;i0&&void 0!==arguments[0]?arguments[0]:{};p(this,t),this._lockList=[],this._waitList=[],this._log=e.log||function(){}}return g(t,[{key:"lock",value:function(){var t=this,e=function e(){t._unlock(e)};return e.id=It(),this._lockList.push(e),this._log("lock: "+e.id),e}},{key:"_unlock",value:function(t){var e=this._lockList.indexOf(t);if(-1===e)throw new Error("This function is not registered in the lock list.");this._lockList.splice(e,1),this._log("unlock: "+t.id),this._tryToFreeWaitList()}},{key:"_tryToFreeWaitList",value:function(){for(;!this.isLocked()&&this._waitList.length>0;)this._waitList.shift()()}},{key:"waitUnlock",value:function(t){if(!(t instanceof Function))throw new Error("The callback param must be a function.");this.isLocked()?this._waitList.push(t):t()}},{key:"isLocked",value:function(){return this._lockList.length>0}}]),t}(),Bt=function(){function t(e,n){p(this,t),this._loader=e instanceof Function?e:function(t,e){var n=t.page,i=t.parent;t.params,P.getPageHTMLAsync(n).then(function(t){var n=Q.createElement(t);i.appendChild(n),e(n)})},this._unloader=n instanceof Function?n:i}return g(t,[{key:"load",value:function(t,e){var n=t.page,i=t.parent,o=t.params,r=void 0===o?{}:o;this._loader({page:n,parent:i,params:r},function(t){if(!(t instanceof Element))throw Error("pageElement must be an instance of Element.");e(t)})}},{key:"unload",value:function(t){if(!(t instanceof Element))throw Error("pageElement must be an instance of Element.");this._unloader(t)}},{key:"internalLoader",set:function(t){if(!(t instanceof Function))throw Error("First parameter must be an instance of Function");this._loader=t},get:function(){return this._loader}}]),t}(),jt=new Bt,Ht=new Bt(function(t,e){var n=t.page,i=t.parent,o=(t.params,Q.createElement(n.trim()));i.appendChild(o),e(o)},i),Rt={animit:nt,defaultPageLoader:jt,elements:c,GestureDetector:st,modifier:xt,notification:St,orientation:Ot,pageAttributeExpression:S,PageLoader:Bt,platform:C,softwareKeyboard:Tt,_autoStyle:N,_internal:P,_readyLock:new Nt,_util:Q};Rt.platform.select((window.location.search.match(/platform=([\w-]+)/)||[])[1]),function(){var t=Rt._readyLock.lock();window.addEventListener("DOMContentLoaded",function(){Rt.isWebView()?window.document.addEventListener("deviceready",t,!1):t()},!1)}();var Ft=function(t){return Q.throw("This method must be called "+(t?"after":"before")+" ons.isReady() is true")};Rt.isReady=function(){return!Rt._readyLock.isLocked()},Rt.isWebView=Rt.platform.isWebView,Rt.ready=function(t){Rt.isReady()?t():Rt._readyLock.waitUnlock(t)},Rt.setDefaultDeviceBackButtonListener=function(t){Rt.isReady()||Ft(!0),Rt._defaultDeviceBackButtonHandler.setListener(t)},Rt.disableDeviceBackButtonHandler=function(){Rt.isReady()||Ft(!0),P.dbbDispatcher.disable()},Rt.enableDeviceBackButtonHandler=function(){Rt.isReady()||Ft(!0),P.dbbDispatcher.enable()},Rt.fireDeviceBackButtonEvent=function(){P.dbbDispatcher.fireDeviceBackButtonEvent()},Rt.enableAutoStatusBarFill=function(){Rt.isReady()&&Ft(!1),P.config.autoStatusBarFill=!0},Rt.disableAutoStatusBarFill=function(){Rt.isReady()&&Ft(!1),P.config.autoStatusBarFill=!1},Rt.mockStatusBar=function(){Rt.isReady()&&Ft(!1);var t=function(){if(!document.body.children[0]||!document.body.children[0].classList.contains("ons-status-bar-mock")){var t=C.isAndroid(),e=function(t){return''},n=t?e("zmdi-twitter")+" "+e("zmdi-google-play"):"No SIM "+e("fa-wifi"),i=t?"":"12:28 PM",o=t?e("zmdi-network")+" "+e("zmdi-wifi")+" "+e("zmdi-battery")+" 12:28 PM":"80% "+e("fa-battery-three-quarters");document.body.insertBefore(Q.createElement('
'+n+"
"+i+"
"+o+"
"),document.body.firstChild)}};document.body?t():P.waitDOMContentLoaded(t)},Rt.disableAnimations=function(){P.config.animationsDisabled=!0},Rt.enableAnimations=function(){P.config.animationsDisabled=!1},Rt._disableWarnings=function(){P.config.warningsDisabled=!0},Rt._enableWarnings=function(){P.config.warningsDisabled=!1},Rt.disableAutoStyling=N.disable,Rt.enableAutoStyling=N.enable,Rt.disableIconAutoPrefix=function(){Q.checkMissingImport("Icon"),c.Icon.setAutoPrefix(!1)},Rt.forceUIWebViewScrollFix=function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];P.config.forceUIWebViewScrollFix=t},Rt.forcePlatformStyling=function(t){Rt.enableAutoStyling(),Rt.platform.select(t||"ios"),Rt._util.arrayFrom(document.querySelectorAll("*")).forEach(function(t){"ons-if"===t.tagName.toLowerCase()?t._platformUpdate():t.tagName.match(/^ons-/i)&&(N.prepare(t,!0),"ons-tabbar"===t.tagName.toLowerCase()&&t._updatePosition())})},Rt.preload=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return Promise.all((t instanceof Array?t:[t]).map(function(t){return"string"!=typeof t&&Q.throw("Expected string arguments but got "+(void 0===t?"undefined":f(t))),P.getTemplateHTMLAsync(t)}))},Rt.createElement=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=function(t){var n=Rt._util.createElement(t);if(n.remove(),e.append){(e.append instanceof HTMLElement?e.append:document.body).insertBefore(n,e.insertBefore||null),e.link instanceof Function&&e.link(n)}return n};return"<"===(t=t.trim()).charAt(0)?n(t):P.getPageHTMLAsync(t).then(n)},Rt.createPopover=Rt.createDialog=Rt.createAlertDialog=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Rt.createElement(t,_({append:!0},e))},Rt.openActionSheet=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return new Promise(function(e){Q.checkMissingImport("ActionSheet"),function(t){var e=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"Function";return Q.throw('"options.'+t+'" must be an instance of '+e)},n=function(e){return Object.hasOwnProperty.call(t,e)},i=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Function;return t[e]instanceof n},o="buttons",r="callback",a="compile",s="destroy";(!n(o)||!i(o,Array))&&e(o,"Array"),n(r)&&!i(r)&&e(r),n(a)&&!i(a)&&e(a),n(s)&&!i(s)&&e(s)}(t);var n=Q.createElement("\n \n
\n \n '),i=function i(o){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;n&&(t.destroy&&t.destroy(n),n.removeEventListener("dialog-cancel",i,!1),n.remove(),n=null,t.callback&&t.callback(r),e(r))};n.addEventListener("dialog-cancel",i,!1);var o=document.createDocumentFragment();t.buttons.forEach(function(e,r){var a="string"==typeof e?{label:e}:_({},e);t.destructive===r&&(a.modifier=(a.modifier||"")+" destructive");var s=Q.createElement("\n \n "+a.label+"\n \n ");s.onclick=function(t){return n.hide().then(function(){return i(t,r)})},o.appendChild(s)}),Q.findChild(n,".action-sheet").appendChild(o),document.body.appendChild(n),t.compile&&t.compile(el.dialog),setImmediate(function(){return n.show({animation:t.animation,animationOptions:t.animationOptions})})})},Rt.resolveLoadingPlaceholder=function(t,e){var n=Rt._util.arrayFrom(window.document.querySelectorAll("[ons-loading-placeholder]"));0===n.length&&Q.throw("No ons-loading-placeholder exists"),n.filter(function(t){return!t.getAttribute("page")}).forEach(function(n){n.setAttribute("ons-loading-placeholder",t),Rt._resolveLoadingPlaceholder(n,t,e)})},Rt._setupLoadingPlaceHolders=function(){Rt.ready(function(){Rt._util.arrayFrom(window.document.querySelectorAll("[ons-loading-placeholder]")).forEach(function(t){var e=t.getAttribute("ons-loading-placeholder");"string"==typeof e&&Rt._resolveLoadingPlaceholder(t,e)})})},Rt._resolveLoadingPlaceholder=function(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(t,e){return e()};e&&Rt.createElement(e).then(function(e){e.style.display="none",t.appendChild(e),n(e,function(){for(;t.firstChild&&t.firstChild!==e;)t.removeChild(t.firstChild);e.style.display=""})}).catch(function(t){return Promise.reject("Unabled to resolve placeholder: "+t)})};var qt="currentScript"in document?function(){return document.currentScript}:function(){return document.scripts[document.scripts.length-1]};Rt.getScriptPage=function(){return qt()&&/ons-page/i.test(qt().parentElement.tagName)&&qt().parentElement||null};var zt=o(function(t){!function(){function e(t,n){var o;if(n=n||{},this.trackingClick=!1,this.trackingClickStart=0,this.targetElement=null,this.touchStartX=0,this.touchStartY=0,this.lastTouchIdentifier=0,this.touchBoundary=n.touchBoundary||10,this.layer=t,this.tapDelay=n.tapDelay||200,this.tapTimeout=n.tapTimeout||700,!e.notNeeded(t)){for(var r=["onMouse","onClick","onTouchStart","onTouchMove","onTouchEnd","onTouchCancel"],a=0,s=r.length;a=0,i=navigator.userAgent.indexOf("Android")>0&&!n,o=/iP(ad|hone|od)/.test(navigator.userAgent)&&!n,r=o&&/OS 4_\d(_\d)?/.test(navigator.userAgent),a=o&&/OS [6-7]_\d/.test(navigator.userAgent),s=navigator.userAgent.indexOf("BB10")>0,l=["email","number","password","search","tel","text","url"];e.prototype.needsClick=function(t){switch(t.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(t.disabled)return!0;break;case"input":if(o&&"file"===t.type||t.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(t.className)},e.prototype.needsFocus=function(t){switch(t.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!i;case"input":switch(t.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!t.disabled&&!t.readOnly;default:return/\bneedsfocus\b/.test(t.className)}},e.prototype.sendClick=function(t,e){var n,i;document.activeElement&&document.activeElement!==t&&document.activeElement.blur(),i=e.changedTouches[0],(n=document.createEvent("MouseEvents")).initMouseEvent(this.determineEventType(t),!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,t.dispatchEvent(n)},e.prototype.determineEventType=function(t){return i&&"select"===t.tagName.toLowerCase()?"mousedown":"click"},e.prototype.focus=function(t){var e;o&&t.setSelectionRange&&0!==t.type.indexOf("date")&&"time"!==t.type&&"month"!==t.type&&"email"!==t.type&&"number"!==t.type?(e=t.value.length,t.setSelectionRange(e,e)):t.focus()},e.prototype.updateScrollParent=function(t){var e,n;if(!(e=t.fastClickScrollParent)||!e.contains(t)){n=t;do{if(n.scrollHeight>n.offsetHeight){e=n,t.fastClickScrollParent=n;break}n=n.parentElement}while(n)}e&&(e.fastClickLastScrollTop=e.scrollTop)},e.prototype.getTargetElementFromEventTarget=function(t){return t.nodeType===Node.TEXT_NODE?t.parentNode:t},e.prototype.isTextField=function(t){return"textarea"===t.tagName.toLowerCase()||-1!==l.indexOf(t.type)},e.prototype.onTouchStart=function(t){var e,n;if(t.targetTouches.length>1)return!0;if(e=this.getTargetElementFromEventTarget(t.target),n=t.targetTouches[0],e.isContentEditable)return!0;if(o){if(e===document.activeElement&&this.isTextField(e))return!0;if(!r){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return t.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(e)}}return this.trackingClick=!0,this.trackingClickStart=t.timeStamp,this.targetElement=e,this.touchStartX=n.pageX,this.touchStartY=n.pageY,t.timeStamp-this.lastClickTime-1&&t.preventDefault(),!0},e.prototype.touchHasMoved=function(t){var e=t.changedTouches[0],n=this.touchBoundary;return Math.abs(e.pageX-this.touchStartX)>n||Math.abs(e.pageY-this.touchStartY)>n},e.prototype.onTouchMove=function(t){return!this.trackingClick||((this.targetElement!==this.getTargetElementFromEventTarget(t.target)||this.touchHasMoved(t))&&(this.trackingClick=!1,this.targetElement=null),!0)},e.prototype.findControl=function(t){return void 0!==t.control?t.control:t.htmlFor?document.getElementById(t.htmlFor):t.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},e.prototype.onTouchEnd=function(t){var e,n,s,l,u,c=this.targetElement;if(!this.trackingClick)return!0;if(t.timeStamp-this.lastClickTime-1)return this.cancelNextClick=!0,!0;if(t.timeStamp-this.trackingClickStart>this.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=t.timeStamp,n=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,a&&(u=t.changedTouches[0],(c=document.elementFromPoint(u.pageX-window.pageXOffset,u.pageY-window.pageYOffset)||c).fastClickScrollParent=this.targetElement.fastClickScrollParent),"label"===(s=c.tagName.toLowerCase())){if(e=this.findControl(c)){if(this.focus(c),i)return!1;c=e}}else if(this.needsFocus(c))return t.timeStamp-n>100||o&&window.top!==window&&"input"===s?(this.targetElement=null,!1):(this.focus(c),this.sendClick(c,t),r&&"select"===s||(this.targetElement=null,t.preventDefault()),!1);return!(!o||r||!(l=c.fastClickScrollParent)||l.fastClickLastScrollTop===l.scrollTop)||(this.needsClick(c)||(t.preventDefault(),this.sendClick(c,t)),!1)},e.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},e.prototype.onMouse=function(t){return!this.targetElement||(!!t.forwardedTouchEvent||(!t.cancelable||(!(!this.needsClick(this.targetElement)||this.cancelNextClick)||(t.stopImmediatePropagation?t.stopImmediatePropagation():t.propagationStopped=!0,t.stopPropagation(),t.preventDefault(),!1))))},e.prototype.onClick=function(t){var e;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===t.target.type&&0===t.detail||((e=this.onMouse(t))||(this.targetElement=null),e)},e.prototype.destroy=function(){var t=this.layer;i&&(t.removeEventListener("mouseover",this.onMouse,!0),t.removeEventListener("mousedown",this.onMouse,!0),t.removeEventListener("mouseup",this.onMouse,!0)),t.removeEventListener("click",this.onClick,!0),t.removeEventListener("touchstart",this.onTouchStart,!1),t.removeEventListener("touchmove",this.onTouchMove,!1),t.removeEventListener("touchend",this.onTouchEnd,!1),t.removeEventListener("touchcancel",this.onTouchCancel,!1)},e.notNeeded=function(t){var e,n,o;if(void 0===window.ontouchstart)return!0;if(n=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!i)return!0;if(e=document.querySelector("meta[name=viewport]")){if(-1!==e.content.indexOf("user-scalable=no"))return!0;if(n>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(s&&(o=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/))[1]>=10&&o[2]>=3&&(e=document.querySelector("meta[name=viewport]"))){if(-1!==e.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===t.style.msTouchAction||"manipulation"===t.style.touchAction||(!!(+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]>=27&&(e=document.querySelector("meta[name=viewport]"))&&(-1!==e.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))||"none"===t.style.touchAction||"manipulation"===t.style.touchAction)},e.attach=function(t,n){return new e(t,n)},t.exports?(t.exports=e.attach,t.exports.FastClick=e):window.FastClick=e}()}).FastClick;window.customElements&&(window.customElements.forcePolyfill=!0);var Vt=o(function(t){var e=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)}),Wt=o(function(t){var e=t.exports={version:"2.5.1"};"number"==typeof __e&&(__e=e)}),Ut=(Wt.version,function(t){return"object"===(void 0===t?"undefined":f(t))?null!==t:"function"==typeof t}),Xt=function(t){if(!Ut(t))throw TypeError(t+" is not an object!");return t},Yt=function(t){try{return!!t()}catch(t){return!0}},Gt=!Yt(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}),$t=Vt.document,Kt=Ut($t)&&Ut($t.createElement),Qt=function(t){return Kt?$t.createElement(t):{}},Jt=!Gt&&!Yt(function(){return 7!=Object.defineProperty(Qt("div"),"a",{get:function(){return 7}}).a}),Zt=function(t,e){if(!Ut(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!Ut(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!Ut(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!Ut(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")},te=Object.defineProperty,ee={f:Gt?Object.defineProperty:function(t,e,n){if(Xt(t),e=Zt(e,!0),Xt(n),Jt)try{return te(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},ne=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},ie=Gt?function(t,e,n){return ee.f(t,e,ne(1,n))}:function(t,e,n){return t[e]=n,t},oe={}.hasOwnProperty,re=function(t,e){return oe.call(t,e)},ae=0,se=Math.random(),le=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++ae+se).toString(36))},ue=o(function(t){var e=le("src"),n=Function.toString,i=(""+n).split("toString");Wt.inspectSource=function(t){return n.call(t)},(t.exports=function(t,n,o,r){var a="function"==typeof o;a&&(re(o,"name")||ie(o,"name",n)),t[n]!==o&&(a&&(re(o,e)||ie(o,e,t[n]?""+t[n]:i.join(String(n)))),t===Vt?t[n]=o:r?t[n]?t[n]=o:ie(t,n,o):(delete t[n],ie(t,n,o)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[e]||n.call(this)})}),ce=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t},he=function(t,e,n){if(ce(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,i){return t.call(e,n,i)};case 3:return function(n,i,o){return t.call(e,n,i,o)}}return function(){return t.apply(e,arguments)}},de=function t(e,n,i){var o,r,a,s,l=e&t.F,u=e&t.G,c=e&t.P,h=e&t.B,d=u?Vt:e&t.S?Vt[n]||(Vt[n]={}):(Vt[n]||{}).prototype,f=u?Wt:Wt[n]||(Wt[n]={}),p=f.prototype||(f.prototype={});u&&(i=n);for(o in i)a=((r=!l&&d&&void 0!==d[o])?d:i)[o],s=h&&r?he(a,Vt):c&&"function"==typeof a?he(Function.call,a):a,d&&ue(d,o,a,e&t.U),f[o]!=a&&ie(f,o,s),c&&p[o]!=a&&(p[o]=a)};Vt.core=Wt,de.F=1,de.G=2,de.S=4,de.P=8,de.B=16,de.W=32,de.U=64,de.R=128;var fe=de,pe={f:{}.propertyIsEnumerable},ge={}.toString,me=function(t){return ge.call(t).slice(8,-1)},_e=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==me(t)?t.split(""):Object(t)},ve=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t},be=function(t){return _e(ve(t))},ye=Object.getOwnPropertyDescriptor,ke={f:Gt?ye:function(t,e){if(t=be(t),e=Zt(e,!0),Jt)try{return ye(t,e)}catch(t){}if(re(t,e))return ne(!pe.f.call(t,e),t[e])}},we=function(t,e){if(Xt(t),!Ut(e)&&null!==e)throw TypeError(e+": can't set as prototype!")},Ee={set:Object.setPrototypeOf||("__proto__"in{}?function(t,e,n){try{(n=he(Function.call,ke.f(Object.prototype,"__proto__").set,2))(t,[]),e=!(t instanceof Array)}catch(t){e=!0}return function(t,i){return we(t,i),e?t.__proto__=i:n(t,i),t}}({},!1):void 0),check:we};fe(fe.S,"Object",{setPrototypeOf:Ee.set});Wt.Object.setPrototypeOf;var Ce=Vt["__core-js_shared__"]||(Vt["__core-js_shared__"]={}),Ae=function(t){return Ce[t]||(Ce[t]={})},Se=o(function(t){var e=Ae("wks"),n=Vt.Symbol,i="function"==typeof n;(t.exports=function(t){return e[t]||(e[t]=i&&n[t]||(i?n:le)("Symbol."+t))}).store=e}),Pe=Se("toStringTag"),Oe="Arguments"==me(function(){return arguments}()),xe=function(t){var e,n,i;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=Object(t),Pe))?n:Oe?me(e):"Object"==(i=me(e))&&"function"==typeof e.callee?"Arguments":i},Te={};Te[Se("toStringTag")]="z",Te+""!="[object z]"&&ue(Object.prototype,"toString",function(){return"[object "+xe(this)+"]"},!0);var Le=Math.ceil,Me=Math.floor,De=function(t){return isNaN(t=+t)?0:(t>0?Me:Le)(t)},Ie={},Ne=Math.min,Be=function(t){return t>0?Ne(De(t),9007199254740991):0},je=Math.max,He=Math.min,Re=Ae("keys"),Fe=function(t){return Re[t]||(Re[t]=le(t))},qe=function(t){return function(e,n,i){var o,r=be(e),a=Be(r.length),s=function(t,e){return(t=De(t))<0?je(t+e,0):He(t,e)}(i,a);if(t&&n!=n){for(;a>s;)if((o=r[s++])!=o)return!0}else for(;a>s;s++)if((t||s in r)&&r[s]===n)return t||s||0;return!t&&-1}}(!1),ze=Fe("IE_PROTO"),Ve="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),We=Object.keys||function(t){return function(t,e){var n,i=be(t),o=0,r=[];for(n in i)n!=ze&&re(i,n)&&r.push(n);for(;e.length>o;)re(i,n=e[o++])&&(~qe(r,n)||r.push(n));return r}(t,Ve)},Ue=Gt?Object.defineProperties:function(t,e){Xt(t);for(var n,i=We(e),o=i.length,r=0;o>r;)ee.f(t,n=i[r++],e[n]);return t},Xe=Vt.document,Ye=Xe&&Xe.documentElement,Ge=Fe("IE_PROTO"),$e=function(){},Ke=function(){var t,e=Qt("iframe"),n=Ve.length;for(e.style.display="none",Ye.appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write(" - - \ No newline at end of file diff --git a/old_frontend/lib/manualcontrol.js b/old_frontend/lib/manualcontrol.js deleted file mode 100644 index caca163a..00000000 --- a/old_frontend/lib/manualcontrol.js +++ /dev/null @@ -1,300 +0,0 @@ -/*global ons */ - -import {ApiService} from "./services/api.service.js"; - -var manualControlSequenceId = 1; -var manualControlDurationMS = 100; -var maxVelocity = 0.3; -var manualControlMinimalVelocity = 0.02; // below this abs limit robot will not move -var manualControlMinimalOmega = 0.1; // below this abs limit (currentAngle) robot will not turn -var manualControlminimalDistanceForOmega = - 10; // below this abs limit (currentXYDistance) the robot will not turn -var currentAngle = 0; -var currentYDistance = 0; -var currentXYDistance = 0; -var currentVelocity = 0; -var currentOmega = 0; -var manualControlStateRefreshTimerMS = 2000; // refresh manual control state each x ms -var manualControlEnabled = false; -var manualControlStateRefreshTimer; -var timedManualControlLoop; - -var startManualControlButton = document.getElementById("start-manual-control-button"); -var endManualControlButton = document.getElementById("stop-manual-control-button"); -var manualControlLoadingBar = document.getElementById("loading-bar-manualcontrol"); - -// API / Manual Control Handling -async function manualMoveRobot(angle, velocity) { - manualControlLoadingBar.setAttribute("indeterminate", "indeterminate"); - try { - // move for twice the interval we're updating at - // to keep on track if one package got lost - await ApiService.setManualControl(angle, velocity, manualControlDurationMS * 2, manualControlSequenceId++); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - manualControlLoadingBar.removeAttribute("indeterminate"); - } -} - -function _startManualControl() { - if (!manualControlEnabled) { - manualControlEnabled = true; - startManualControlButton.setAttribute("disabled", "disabled"); - endManualControlButton.removeAttribute("disabled"); - document.getElementById("sidemenu").removeAttribute("swipeable"); - document.getElementById("appTabbar").removeAttribute("swipeable"); - } -} - -function _stopManualControl() { - if (manualControlEnabled) { - manualControlEnabled = false; - endManualControlButton.setAttribute("disabled", "disabled"); - startManualControlButton.removeAttribute("disabled"); - document.getElementById("sidemenu").setAttribute("swipeable", "swipeable"); - document.getElementById("appTabbar").setAttribute("swipeable", "swipeable"); - stopManualControlTimer(); - } -} - -function postponeRefreshManualControlMode() { - clearInterval(manualControlStateRefreshTimer); - manualControlStateRefreshTimer = - setInterval(function() { - refreshManualControlMode(); - }, manualControlStateRefreshTimerMS); -} - -async function startManualControl() { - if (!manualControlEnabled) { - manualControlLoadingBar.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.startManualControl(); - _startManualControl(); - postponeRefreshManualControlMode(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - manualControlLoadingBar.removeAttribute("indeterminate"); - } - } -} - -async function stopManualControl() { - if (manualControlEnabled) { - manualControlLoadingBar.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.stopManualControl(); - _stopManualControl(); - postponeRefreshManualControlMode(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - manualControlLoadingBar.removeAttribute("indeterminate"); - } - } -} - -function sendManualControl() { - // limit velocity to square (up, bottom, left, right are to be equal!) - if (currentYDistance > cY) { - currentYDistance = cY; - } - currentVelocity = (currentYDistance / cY) * maxVelocity; - - // center deadzone - if (Math.abs(currentVelocity) < manualControlMinimalVelocity) { - currentVelocity = 0; - } - - if (Math.abs(currentAngle) < manualControlMinimalOmega || - Math.abs(currentXYDistance) < manualControlminimalDistanceForOmega) { - currentOmega = 0; - } else { - currentOmega = currentAngle; - } - - drawValuesToCanvas(); - manualMoveRobot(currentOmega, currentVelocity); -} - -function startManualControlTimer() { - if (!timedManualControlLoop && manualControlEnabled) { - sendManualControl(); // send + start repetitive timer - timedManualControlLoop = - setInterval(function() { - sendManualControl(); - }, manualControlDurationMS); - } -} - -function stopManualControlTimer() { - if (timedManualControlLoop) { - clearInterval(timedManualControlLoop); - timedManualControlLoop = 0; - } -} - -// Canvas orga -let manualControlCanvas = document.getElementById("manual-control-area"); -// apply shown dimensions to canvas - required because of percentual css dimension -manualControlCanvas.setAttribute("width", manualControlCanvas.clientWidth); -manualControlCanvas.setAttribute("height", manualControlCanvas.clientHeight); - -var manualControlCanvasContext = manualControlCanvas.getContext("2d"); -var cX = manualControlCanvas.width / 2; -var cY = manualControlCanvas.height / 2; - -manualControlCanvasContext.moveTo(cX, cY); -manualControlCanvasContext.fillStyle = "#ff0044"; -manualControlCanvasContext.arc(cX, cY, 5, 0, 360, false); -manualControlCanvasContext.fill(); - -function drawValuesToCanvas() { - // delete old values / draw background - manualControlCanvasContext.fillStyle = "#FFFFFF"; //#9ea7b833 - manualControlCanvasContext.fillRect(0, 0, 200, 50); - // draw values - manualControlCanvasContext.font = "12px Helvetica"; - manualControlCanvasContext.textAlign = "left"; - manualControlCanvasContext.fillStyle = "#8A8A8A"; - manualControlCanvasContext.fillText("Velocity:\t" + currentVelocity.toPrecision(2) + - "\tOmega:\t" + currentOmega.toPrecision(2), - 30, 30); -} - -// Mouse Handling -function getMousePos(canvasDom, mouseEvent) { - var rect = canvasDom.getBoundingClientRect(); - return {x: mouseEvent.clientX - rect.left, y: mouseEvent.clientY - rect.top}; -} - -["mousedown", "mouseenter", "mouseup", "mouseleave", "mouseout"].forEach(function(evt) { - manualControlCanvas.addEventListener(evt, function() { - startManualControlTimer(); - }, false); -}); - -manualControlCanvas.addEventListener("mousemove", function(e) { - event.preventDefault(); - var m = getMousePos(manualControlCanvas, e); - calculateAngleAndDistance(m); -}, false); - -// Touch Handling -function getTouchPos(evt) { - var rect = manualControlCanvas.getBoundingClientRect(); - - if (evt && evt.touches) { - if (evt.touches.length === 1) { // Only deal with one finger - var touch = evt.touches[0]; // Get the information for finger #1 - return { - x: touch.pageX - rect.left, //-touch.target.offsetLeft, - y: touch.pageY - rect.top //-touch.target.offsetTop - }; - } - } else { - return {x: 0, y: 0}; - } -} - -function touchStart(e) { - e.preventDefault(); - startManualControlTimer(); - var m = getTouchPos(); - calculateAngleAndDistance(m); -} - -function touchMove(e) { - e.preventDefault(); - var m = getTouchPos(e); - calculateAngleAndDistance(m); -} - -function touchEnd() { - stopManualControlTimer(); -} - -manualControlCanvas.addEventListener("touchstart", touchStart, false); -manualControlCanvas.addEventListener("touchmove", touchMove, false); -manualControlCanvas.addEventListener("touchcancel", touchEnd, false); -manualControlCanvas.addEventListener("touchend", touchEnd, false); - -function calculateAngleAndDistance(m) { - var tX = Math.abs(cX - m.x); - var tY = Math.abs(cY - m.y); - - currentYDistance = cY - m.y; - currentXYDistance = Math.floor(Math.sqrt(tX * tX + tY * tY)); - - if (m.x < cX) { - if (m.y < cY) { - // upper left - currentAngle = -Math.atan((cX - m.x) / (m.y - cY)); - } else { - // lower left - if (m.y === cY) { - currentAngle = 0; - } else { - currentAngle = -Math.atan((m.x - cX) / (m.y - cY)); - } - } - } else { - if (m.y < cY) { - // upper right - currentAngle = Math.atan((cX - m.x) / (cY - m.y)); - } else { - // lower right - if (cY === m.y) { - currentAngle = 0; - } else { - currentAngle = Math.atan((m.x - cX) / (cY - m.y)); - } - } - } -} - -// Page Handling (refresh/update/onload/onhide) -async function refreshManualControlMode() { - try { - let res = await ApiService.getVacuumState(); - var StatusStateAttribute = res.find(e => e.__class === "StatusStateAttribute"); - - - if (StatusStateAttribute && StatusStateAttribute.value === "manual_control") { - _startManualControl(); - } else { - _stopManualControl(); - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - manualControlLoadingBar.removeAttribute("indeterminate"); - } -} - -function ManualControlInit() { - manualControlLoadingBar.setAttribute("indeterminate", "indeterminate"); - refreshManualControlMode(); - // Since the robot may disable manual control mode by itself, this timer keeps the - // state of the robot in track with the UI - manualControlStateRefreshTimer = - setInterval(function() { - refreshManualControlMode(); - }, manualControlStateRefreshTimerMS); -} - -function ManualControlHide() { - stopManualControl(); - clearInterval(manualControlStateRefreshTimer); -} - -window.ManualControlInit = ManualControlInit; -window.startManualControl = startManualControl; -window.stopManualControl = stopManualControl; -window.ManualControlHide = ManualControlHide; diff --git a/old_frontend/lib/map.html b/old_frontend/lib/map.html deleted file mode 100644 index 33baadb6..00000000 --- a/old_frontend/lib/map.html +++ /dev/null @@ -1,39 +0,0 @@ - -
- - - -
- -
- - - - - - - - - -
- - - -
diff --git a/old_frontend/lib/map.js b/old_frontend/lib/map.js deleted file mode 100644 index af0708a8..00000000 --- a/old_frontend/lib/map.js +++ /dev/null @@ -1,149 +0,0 @@ -/*global ons */ -import {VacuumMap} from "./js/js-modules/vacuum-map.js"; -import {ApiService} from "./services/api.service.js"; - -const loadingBar = document.getElementById("loading-bar-map"); -let map = null; - -async function updateMapPage() { - loadingBar.setAttribute("indeterminate", "indeterminate"); - try { - let mapData = await ApiService.getLatestMap(); - if (map === null) { - map = new VacuumMap(document.getElementById("map-canvas")); - map.initCanvas(mapData); - } else { - map.updateMap(mapData); - } - map.initSSE(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - throw err; - } finally { - loadingBar.removeAttribute("indeterminate"); - } -} - -// Register update function to be accessible outside of es6 module (see - - diff --git a/old_frontend/lib/segment-edit-map.js b/old_frontend/lib/segment-edit-map.js deleted file mode 100644 index 98cb54f2..00000000 --- a/old_frontend/lib/segment-edit-map.js +++ /dev/null @@ -1,151 +0,0 @@ -/*global ons, fn*/ -import {VacuumMap} from "./js/js-modules/vacuum-map.js"; -import {ApiService} from "./services/api.service.js"; - -async function segmentConfigInit() { - const map = new VacuumMap(document.getElementById("segment-edit-map")); - const loadingBarSegmentEdit = document.getElementById("loading-bar-segment-edit"); - const addSplitLineButton = document.getElementById("segment-edit-add-split-line"); - const splitSegmentButton = document.getElementById("segment-edit-split"); - const joinSegmentButton = document.getElementById("segment-edit-join"); - const renameSegmentButton = document.getElementById("segment-rename"); - const topPage = fn.getTopPage(); - const mapData = JSON.parse(JSON.stringify(topPage.data.map)); //cloned for good measure - - try { - let robotCapabilities = await ApiService.getRobotCapabilities(); - - if (robotCapabilities.includes("MapSegmentRenameCapability")) { - renameSegmentButton.classList.remove("hidden"); - } - - if (robotCapabilities.includes("MapSegmentEditCapability")) { - addSplitLineButton.classList.remove("hidden"); - splitSegmentButton.classList.remove("hidden"); - joinSegmentButton.classList.remove("hidden"); - } - } catch (err) { - ons.notification.toast(err.message, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - - mapData.layers.forEach(layer => { - if (layer.type === "segment") { - layer.metaData.active = false; - } - }); - - map.initCanvas(mapData, {metaData: "segments", noGotoPoints: true, noPath: true}); - window.fn.map = map; - - document.getElementById("segment-edit-map-page-h1").innerText = "Editing Segments"; - - addSplitLineButton.onclick = () => { - if (map.getLocations().virtualWalls.length === 0) { - map.addVirtualWall(null, false, true); - } else { - ons.notification.toast("There can only be one split line.",{buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - }; - - splitSegmentButton.onclick = async () => { - let locations = map.getLocations(); - - if (locations.selectedSegments.length === 1) { - if (locations.virtualWalls.length === 1) { - loadingBarSegmentEdit.setAttribute("indeterminate", "indeterminate"); - - try { - await ApiService.splitSegment( - { - x: locations.virtualWalls[0][0], - y: locations.virtualWalls[0][1] - }, - { - x: locations.virtualWalls[0][2], - y: locations.virtualWalls[0][3] - }, - locations.selectedSegments[0].id - ); - await ons.notification.toast( - "Successfully split segment!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - fn.popPage(); - } catch (err) { - ons.notification.toast(err.message, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSegmentEdit.removeAttribute("indeterminate"); - } - } else { - ons.notification.toast("You need to have a split line to split",{buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - } else { - ons.notification.toast("You need to select exactly one segment to execute a split",{buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - }; - - joinSegmentButton.onclick = async () => { - let locations = map.getLocations(); - - if (locations.selectedSegments.length === 2) { - loadingBarSegmentEdit.setAttribute("indeterminate", "indeterminate"); - - try { - await ApiService.joinSegments( - locations.selectedSegments[0].id, - locations.selectedSegments[1].id - ); - await ons.notification.toast( - "Successfully joined segment!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - fn.popPage(); - } catch (err) { - ons.notification.toast(err.message, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSegmentEdit.removeAttribute("indeterminate"); - } - } else { - ons.notification.toast("You need to select exactly two segment to execute a join",{buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - }; - - const segmentRenameDialog = document.getElementById("segment-rename-dialog"); - const segmentRenameDialogNameInput = document.getElementById("segment-rename-input-name"); - let segmentId = null; - - renameSegmentButton.onclick = () => { - let locations = map.getLocations(); - if (locations.selectedSegments.length === 1) { - segmentId = locations.selectedSegments[0].id; - segmentRenameDialogNameInput.value = locations.selectedSegments[0].name; - segmentRenameDialog.show(); - } else { - ons.notification.toast("You need to select exactly one segment to rename it.",{buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - }; - - document.getElementById("segment-rename-dialog-cancel-button").onclick = () => { - segmentRenameDialog.hide(); - }; - - document.getElementById("segment-rename-dialog-update-button").onclick = async () => { - loadingBarSegmentEdit.setAttribute("indeterminate", "indeterminate"); - - try { - await ApiService.renameSegment( - segmentId, - segmentRenameDialogNameInput.value - ); - segmentRenameDialog.hide(); - await ons.notification.toast( - "Successfully renamed segment!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - fn.popPage(); - } catch (err) { - ons.notification.toast(err.message, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSegmentEdit.removeAttribute("indeterminate"); - } - }; -} - -window.segmentConfigInit = segmentConfigInit; diff --git a/old_frontend/lib/services/timezone.service.js b/old_frontend/lib/services/timezone.service.js deleted file mode 100644 index 977c44c5..00000000 --- a/old_frontend/lib/services/timezone.service.js +++ /dev/null @@ -1,354 +0,0 @@ -export class TimezoneService { - static getAllTimezones() { - return [ - "Africa/Abidjan", - "Africa/Accra", - "Africa/Algiers", - "Africa/Bissau", - "Africa/Cairo", - "Africa/Casablanca", - "Africa/Ceuta", - "Africa/El_Aaiun", - "Africa/Johannesburg", - "Africa/Juba", - "Africa/Khartoum", - "Africa/Lagos", - "Africa/Maputo", - "Africa/Monrovia", - "Africa/Nairobi", - "Africa/Ndjamena", - "Africa/Sao_Tome", - "Africa/Tripoli", - "Africa/Tunis", - "Africa/Windhoek", - "America/Adak", - "America/Anchorage", - "America/Araguaina", - "America/Argentina/Buenos_Aires", - "America/Argentina/Catamarca", - "America/Argentina/Cordoba", - "America/Argentina/Jujuy", - "America/Argentina/La_Rioja", - "America/Argentina/Mendoza", - "America/Argentina/Rio_Gallegos", - "America/Argentina/Salta", - "America/Argentina/San_Juan", - "America/Argentina/San_Luis", - "America/Argentina/Tucuman", - "America/Argentina/Ushuaia", - "America/Asuncion", - "America/Atikokan", - "America/Bahia", - "America/Bahia_Banderas", - "America/Barbados", - "America/Belem", - "America/Belize", - "America/Blanc-Sablon", - "America/Boa_Vista", - "America/Bogota", - "America/Boise", - "America/Cambridge_Bay", - "America/Campo_Grande", - "America/Cancun", - "America/Caracas", - "America/Cayenne", - "America/Chicago", - "America/Chihuahua", - "America/Costa_Rica", - "America/Creston", - "America/Cuiaba", - "America/Curacao", - "America/Danmarkshavn", - "America/Dawson", - "America/Dawson_Creek", - "America/Denver", - "America/Detroit", - "America/Edmonton", - "America/Eirunepe", - "America/El_Salvador", - "America/Fortaleza", - "America/Fort_Nelson", - "America/Glace_Bay", - "America/Godthab", - "America/Goose_Bay", - "America/Grand_Turk", - "America/Guatemala", - "America/Guayaquil", - "America/Guyana", - "America/Halifax", - "America/Havana", - "America/Hermosillo", - "America/Indiana/Indianapolis", - "America/Indiana/Knox", - "America/Indiana/Marengo", - "America/Indiana/Petersburg", - "America/Indiana/Tell_City", - "America/Indiana/Vevay", - "America/Indiana/Vincennes", - "America/Indiana/Winamac", - "America/Inuvik", - "America/Iqaluit", - "America/Jamaica", - "America/Juneau", - "America/Kentucky/Louisville", - "America/Kentucky/Monticello", - "America/La_Paz", - "America/Lima", - "America/Los_Angeles", - "America/Maceio", - "America/Managua", - "America/Manaus", - "America/Martinique", - "America/Matamoros", - "America/Mazatlan", - "America/Menominee", - "America/Merida", - "America/Metlakatla", - "America/Mexico_City", - "America/Miquelon", - "America/Moncton", - "America/Monterrey", - "America/Montevideo", - "America/Nassau", - "America/New_York", - "America/Nipigon", - "America/Nome", - "America/Noronha", - "America/North_Dakota/Beulah", - "America/North_Dakota/Center", - "America/North_Dakota/New_Salem", - "America/Ojinaga", - "America/Panama", - "America/Pangnirtung", - "America/Paramaribo", - "America/Phoenix", - "America/Port-au-Prince", - "America/Porto_Velho", - "America/Port_of_Spain", - "America/Puerto_Rico", - "America/Punta_Arenas", - "America/Rainy_River", - "America/Rankin_Inlet", - "America/Recife", - "America/Regina", - "America/Resolute", - "America/Rio_Branco", - "America/Santarem", - "America/Santiago", - "America/Santo_Domingo", - "America/Sao_Paulo", - "America/Scoresbysund", - "America/Sitka", - "America/St_Johns", - "America/Swift_Current", - "America/Tegucigalpa", - "America/Thule", - "America/Thunder_Bay", - "America/Tijuana", - "America/Toronto", - "America/Vancouver", - "America/Whitehorse", - "America/Winnipeg", - "America/Yakutat", - "America/Yellowknife", - "Antarctica/Casey", - "Antarctica/Davis", - "Antarctica/DumontDUrville", - "Antarctica/Macquarie", - "Antarctica/Mawson", - "Antarctica/Palmer", - "Antarctica/Rothera", - "Antarctica/Syowa", - "Antarctica/Troll", - "Antarctica/Vostok", - "Asia/Almaty", - "Asia/Amman", - "Asia/Anadyr", - "Asia/Aqtau", - "Asia/Aqtobe", - "Asia/Ashgabat", - "Asia/Atyrau", - "Asia/Baghdad", - "Asia/Baku", - "Asia/Bangkok", - "Asia/Barnaul", - "Asia/Beirut", - "Asia/Bishkek", - "Asia/Brunei", - "Asia/Chita", - "Asia/Choibalsan", - "Asia/Colombo", - "Asia/Damascus", - "Asia/Dhaka", - "Asia/Dili", - "Asia/Dubai", - "Asia/Dushanbe", - "Asia/Famagusta", - "Asia/Gaza", - "Asia/Hebron", - "Asia/Hong_Kong", - "Asia/Hovd", - "Asia/Ho_Chi_Minh", - "Asia/Irkutsk", - "Asia/Jakarta", - "Asia/Jayapura", - "Asia/Jerusalem", - "Asia/Kabul", - "Asia/Kamchatka", - "Asia/Karachi", - "Asia/Kathmandu", - "Asia/Khandyga", - "Asia/Kolkata", - "Asia/Krasnoyarsk", - "Asia/Kuala_Lumpur", - "Asia/Kuching", - "Asia/Macau", - "Asia/Magadan", - "Asia/Makassar", - "Asia/Manila", - "Asia/Nicosia", - "Asia/Novokuznetsk", - "Asia/Novosibirsk", - "Asia/Omsk", - "Asia/Oral", - "Asia/Pontianak", - "Asia/Pyongyang", - "Asia/Qatar", - "Asia/Qostanay", - "Asia/Qyzylorda", - "Asia/Riyadh", - "Asia/Sakhalin", - "Asia/Samarkand", - "Asia/Seoul", - "Asia/Shanghai", - "Asia/Singapore", - "Asia/Srednekolymsk", - "Asia/Taipei", - "Asia/Tashkent", - "Asia/Tbilisi", - "Asia/Tehran", - "Asia/Thimphu", - "Asia/Tokyo", - "Asia/Tomsk", - "Asia/Ulaanbaatar", - "Asia/Urumqi", - "Asia/Ust-Nera", - "Asia/Vladivostok", - "Asia/Yakutsk", - "Asia/Yangon", - "Asia/Yekaterinburg", - "Asia/Yerevan", - "Atlantic/Azores", - "Atlantic/Bermuda", - "Atlantic/Canary", - "Atlantic/Cape_Verde", - "Atlantic/Faroe", - "Atlantic/Madeira", - "Atlantic/Reykjavik", - "Atlantic/South_Georgia", - "Atlantic/Stanley", - "Australia/Adelaide", - "Australia/Brisbane", - "Australia/Broken_Hill", - "Australia/Currie", - "Australia/Darwin", - "Australia/Eucla", - "Australia/Hobart", - "Australia/Lindeman", - "Australia/Lord_Howe", - "Australia/Melbourne", - "Australia/Perth", - "Australia/Sydney", - "Europe/Amsterdam", - "Europe/Andorra", - "Europe/Astrakhan", - "Europe/Athens", - "Europe/Belgrade", - "Europe/Berlin", - "Europe/Brussels", - "Europe/Bucharest", - "Europe/Budapest", - "Europe/Chisinau", - "Europe/Copenhagen", - "Europe/Dublin", - "Europe/Gibraltar", - "Europe/Helsinki", - "Europe/Istanbul", - "Europe/Kaliningrad", - "Europe/Kiev", - "Europe/Kirov", - "Europe/Lisbon", - "Europe/London", - "Europe/Luxembourg", - "Europe/Madrid", - "Europe/Malta", - "Europe/Minsk", - "Europe/Monaco", - "Europe/Moscow", - "Europe/Oslo", - "Europe/Paris", - "Europe/Prague", - "Europe/Riga", - "Europe/Rome", - "Europe/Samara", - "Europe/Saratov", - "Europe/Simferopol", - "Europe/Sofia", - "Europe/Stockholm", - "Europe/Tallinn", - "Europe/Tirane", - "Europe/Ulyanovsk", - "Europe/Uzhgorod", - "Europe/Vienna", - "Europe/Vilnius", - "Europe/Volgograd", - "Europe/Warsaw", - "Europe/Zaporozhye", - "Europe/Zurich", - "Indian/Chagos", - "Indian/Christmas", - "Indian/Cocos", - "Indian/Kerguelen", - "Indian/Mahe", - "Indian/Maldives", - "Indian/Mauritius", - "Indian/Reunion", - "Pacific/Apia", - "Pacific/Auckland", - "Pacific/Bougainville", - "Pacific/Chatham", - "Pacific/Chuuk", - "Pacific/Easter", - "Pacific/Efate", - "Pacific/Enderbury", - "Pacific/Fakaofo", - "Pacific/Fiji", - "Pacific/Funafuti", - "Pacific/Galapagos", - "Pacific/Gambier", - "Pacific/Guadalcanal", - "Pacific/Guam", - "Pacific/Honolulu", - "Pacific/Kiritimati", - "Pacific/Kosrae", - "Pacific/Kwajalein", - "Pacific/Majuro", - "Pacific/Marquesas", - "Pacific/Nauru", - "Pacific/Niue", - "Pacific/Norfolk", - "Pacific/Noumea", - "Pacific/Pago_Pago", - "Pacific/Palau", - "Pacific/Pitcairn", - "Pacific/Pohnpei", - "Pacific/Port_Moresby", - "Pacific/Rarotonga", - "Pacific/Tahiti", - "Pacific/Tarawa", - "Pacific/Tongatapu", - "Pacific/Wake", - "Pacific/Wallis" - ]; - } -} diff --git a/old_frontend/lib/settings-access-control.html b/old_frontend/lib/settings-access-control.html deleted file mode 100644 index 194d2cc8..00000000 --- a/old_frontend/lib/settings-access-control.html +++ /dev/null @@ -1,74 +0,0 @@ - - -
- Settings -
-
Access Control Settings
-
-
-
- - HTTP Authentication Settings - - -
- - Enabled - -
- -
- - - - - - - - - - -
- Save credentials -
-
-
- - -
diff --git a/old_frontend/lib/settings-access-control.js b/old_frontend/lib/settings-access-control.js deleted file mode 100644 index 292f8163..00000000 --- a/old_frontend/lib/settings-access-control.js +++ /dev/null @@ -1,60 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsAccessControlPage() { - var loadingBarSettingsAccessControl = document.getElementById("loading-bar-settings-access-control"); - var httpAuthInputEnabled = - document.getElementById("settings-access-control-http-auth-input-enabled"); - var httpAuthInputUsername = - document.getElementById("settings-access-control-http-auth-input-username"); - var httpAuthInputPassword = - document.getElementById("settings-access-control-http-auth-input-password"); - - loadingBarSettingsAccessControl.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getHttpAuthConfig(); - httpAuthInputEnabled.checked = res.enabled; - httpAuthInputUsername.value = res.username; - httpAuthInputPassword.value = ""; - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsAccessControl.removeAttribute("indeterminate"); - } -} - -async function handleHttpAuthSettingsSaveButton() { - var loadingBarSettingsAccessControl = document.getElementById("loading-bar-settings-access-control"); - var httpAuthInputEnabled = - document.getElementById("settings-access-control-http-auth-input-enabled"); - var httpAuthInputUsername = - document.getElementById("settings-access-control-http-auth-input-username"); - var httpAuthInputPassword = - document.getElementById("settings-access-control-http-auth-input-password"); - var httpAuthInputPasswordConfirm = - document.getElementById("settings-access-control-http-auth-input-password-confirm"); - - if (httpAuthInputPassword.value !== httpAuthInputPasswordConfirm.value) { - return ons.notification.toast( - "Passwords don't match", - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - - loadingBarSettingsAccessControl.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.saveHttpAuthConfig({ - enabled: httpAuthInputEnabled.checked === true, - username: httpAuthInputUsername.value, - password: httpAuthInputPassword.value, - }); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsAccessControl.removeAttribute("indeterminate"); - } -} - -window.updateSettingsAccessControlPage = updateSettingsAccessControlPage; -window.handleHttpAuthSettingsSaveButton = handleHttpAuthSettingsSaveButton; diff --git a/old_frontend/lib/settings-carpet-mode.html b/old_frontend/lib/settings-carpet-mode.html deleted file mode 100644 index 9f7cec9e..00000000 --- a/old_frontend/lib/settings-carpet-mode.html +++ /dev/null @@ -1,46 +0,0 @@ - - -
- Settings -
-
Carpet Mode
-
-
-
- - Carpet Mode Configuration - - - In Carpet Mode, the vacuum will recognize carpets automatically and increase the suction. - - -
- - - Enabled - - - - -
-
- - - Save - - -
- -
\ No newline at end of file diff --git a/old_frontend/lib/settings-carpet-mode.js b/old_frontend/lib/settings-carpet-mode.js deleted file mode 100644 index 82f73579..00000000 --- a/old_frontend/lib/settings-carpet-mode.js +++ /dev/null @@ -1,47 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsCarpetModePage() { - var loadingBarSettingsCarpetMode = document.getElementById("loading-bar-settings-carpet-mode"); - - loadingBarSettingsCarpetMode.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getCarpetModeStatus(); - document.getElementById("carpet_mode_enabled").checked = res.enabled; - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsCarpetMode.removeAttribute("indeterminate"); - } -} - -async function saveCarpetMode() { - var loadingBarSettingsCarpetMode = document.getElementById("loading-bar-settings-carpet-mode"); - - let answer = await ons.notification - .confirm("Do you really want to save the modifications made in the carpet mode?"); - - if (answer === 1) { - loadingBarSettingsCarpetMode.setAttribute("indeterminate", "indeterminate"); - var enabled = document.getElementById("carpet_mode_enabled").checked; - - try { - if (enabled) { - await ApiService.enableCarpetMode(); - } else { - await ApiService.disableCarpetMode(); - } - - updateSettingsCarpetModePage(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsCarpetMode.removeAttribute("indeterminate"); - } - } -} - -window.updateSettingsCarpetModePage = updateSettingsCarpetModePage; -window.saveCarpetMode = saveCarpetMode; diff --git a/old_frontend/lib/settings-cleaning-history.html b/old_frontend/lib/settings-cleaning-history.html deleted file mode 100644 index 5fbcfd86..00000000 --- a/old_frontend/lib/settings-cleaning-history.html +++ /dev/null @@ -1,30 +0,0 @@ - - -
- Settings -
-
Cleaning History
-
-
-
-
- - Last cleaning runs - - - - - -
\ No newline at end of file diff --git a/old_frontend/lib/settings-cleaning-history.js b/old_frontend/lib/settings-cleaning-history.js deleted file mode 100644 index c1fdb268..00000000 --- a/old_frontend/lib/settings-cleaning-history.js +++ /dev/null @@ -1,139 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -var remainingShownCount; -var historyArray, timeZone; - -function loadMoreItems() { - remainingShownCount = historyArray.length > 5 ? 5 : historyArray.length; - loadNextRemainingElements(); -} - -async function updateSettingsCleaningHistoryPage() { - var loadingBarSettingsCleaningHistory = - document.getElementById("loading-bar-settings-cleaning-history"); - var settingsCleaningHistory = document.getElementById("settings-cleaning-history"); - - remainingShownCount = 5; - - loadingBarSettingsCleaningHistory.setAttribute("indeterminate", "indeterminate"); - while (settingsCleaningHistory.lastChild) { - settingsCleaningHistory.removeChild(settingsCleaningHistory.lastChild); - } - try { - let res = await ApiService.getCleanSummary(); - // summary succeeded - historyArray = res.lastRuns; - // getting current timezone for properly showing local time - res = await ApiService.getTimezone(); - timeZone = res; - loadNextRemainingElements(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsCleaningHistory.removeAttribute("indeterminate"); - } -} - -function formatTwoDigitNumber(number) { - if (number >= 0 && number <= 9) { - return "0" + number; - } else { - return number; - } -} - -async function loadNextRemainingElements() { - var loadingBarSettingsCleaningHistory = - document.getElementById("loading-bar-settings-cleaning-history"); - var settingsCleaningHistory = document.getElementById("settings-cleaning-history"); - var settingsCleaningHistoryLoadMoreButtons = - document.getElementById("settings-cleaning-history-load-more"); - - if (!historyArray.length) { - remainingShownCount = 0; - } - if (remainingShownCount > 0) { - loadingBarSettingsCleaningHistory.setAttribute("indeterminate", "indeterminate"); - var historyTimestamp = - historyArray.shift(); // array is sorted with latest items in the beginning - try { - let res = await ApiService.retrieveCleanRecord(historyTimestamp); - // adjust counters - remainingShownCount--; - // set variables - var currentEntryId = historyArray.length + 1; - var fromTime = - new Date(res.startTime).toLocaleString("default", {timeZone: timeZone}); - var durationTotalSeconds = res.duration; - var durationHours = Math.floor(durationTotalSeconds / 3600); - var remsecs = durationTotalSeconds % 3600; - var durationMinutes = Math.floor(remsecs / 60); - var durationSeconds = (remsecs % 60); - var area = res.area.toFixed(1); - var errorCode = res.errorCode; - var errorDescription = res.errorDescription; - var completedFlag = res.finished; - settingsCleaningHistory.appendChild(ons.createElement( - "\n" + - " " + - " " + - " #" + - currentEntryId + " started on " + fromTime + "" + - " " + - " " + - " " + - " " + - " Duration" + - " " + durationHours + - ":" + formatTwoDigitNumber(durationMinutes) + ":" + - formatTwoDigitNumber(durationSeconds) + "" + - " " + - " " + - " " + - " " + - " Area" + - " " + area + - " m2" + - " " + - " " + - " " + - " " + - " Completed" + - " " + - (completedFlag ? "" : - "") + - "" + - " " + - " " + - (errorCode > 0 ? - " " + - " " + - "  " + - errorDescription + " (Code: " + errorCode + ")" + - " " + - " " : - "") + - "")); - // load next element - loadNextRemainingElements(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsCleaningHistory.removeAttribute("indeterminate"); - } - } else { - if (historyArray.length > 0) { - // show link to load more - settingsCleaningHistoryLoadMoreButtons.style.display = "block"; - } else { - // hide link to load more - settingsCleaningHistoryLoadMoreButtons.style.display = "none"; - } - } -} - -window.updateSettingsCleaningHistoryPage = updateSettingsCleaningHistoryPage; -window.loadMoreItems = loadMoreItems; diff --git a/old_frontend/lib/settings-consumables.html b/old_frontend/lib/settings-consumables.html deleted file mode 100644 index add97bdc..00000000 --- a/old_frontend/lib/settings-consumables.html +++ /dev/null @@ -1,64 +0,0 @@ - - -
- Settings -
-
Consumables
-
-
-
- - - Consumables - - - - - - - -
diff --git a/old_frontend/lib/settings-consumables.js b/old_frontend/lib/settings-consumables.js deleted file mode 100644 index 1e0fac64..00000000 --- a/old_frontend/lib/settings-consumables.js +++ /dev/null @@ -1,100 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -const TYPE_MAPPING = Object.freeze({ - "brush": "Brush", - "filter": "Filter", - "sensor": "Sensor cleaning", - "mop": "Mop" -}); - -const SUBTYPE_MAPPING = Object.freeze({ - "main": "Main", - "side_right": "Right", - "side_left": "Left", - "all": "", - "none": "" -}); - -async function handleConsumableResetButton(type, subType) { - var loadingBarSettingsConsumables = document.getElementById("loading-bar-settings-consumables"); - - let answer = await ons.notification.confirm("Do you really want to reset this consumable?"); - if (answer === 1) { - loadingBarSettingsConsumables.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.resetConsumable(type, subType); - updateSettingsConsumablesPage(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsConsumables.removeAttribute("indeterminate"); - } - } -} - -function formatConsumableType(type, subType) { - let ret = ""; - if (SUBTYPE_MAPPING[subType]) { - ret += SUBTYPE_MAPPING[subType] + " "; - } - if (TYPE_MAPPING[type]) { - ret += TYPE_MAPPING[type]; - } - return ret || "Unknown consumable: " + type + ", " + subType; -} - -async function updateSettingsConsumablesPage() { - var loadingBarSettingsConsumables = document.getElementById("loading-bar-settings-consumables"); - /*var consumableStatisticsArea = - document.getElementById("settings-consumables-status-statistics-area"); - var consumableStatisticsHours = - document.getElementById("settings-consumables-status-statistics-hours"); - var consumableStatisticsCount = - document.getElementById("settings-consumables-status-statistics-count");*/ - - loadingBarSettingsConsumables.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getConsumableStatus(); - - const consumablesList = document.getElementById("consumables-list"); - while (consumablesList.lastChild) { - consumablesList.removeChild(consumablesList.lastChild); - } - - res.forEach(consumable => { - let item = document.createElement("ons-list-item"); - let title = document.createElement("div"); - title.classList.add("left"); - title.classList.add("consumables-list-item-title"); - title.innerText = formatConsumableType(consumable.type, consumable.subType); - item.appendChild(title); - - let value = document.createElement("div"); - value.classList.add("center"); - value.style.marginLeft = "5%"; - value.innerText = (consumable.remaining.value / 60).toFixed(1) + " hours left"; - item.appendChild(value); - - let reset = document.createElement("div"); - reset.classList.add("right"); - reset.innerHTML = ""; - item.appendChild(reset); - - consumablesList.appendChild(item); - }); - - /*consumableStatisticsArea.innerHTML = res.summary.cleanArea.toFixed(1) + " m²"; - consumableStatisticsHours.innerHTML = res.summary.cleanTime.toFixed(1) + " hours"; - consumableStatisticsCount.innerHTML = res.summary.cleanCount;*/ - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsConsumables.removeAttribute("indeterminate"); - } -} - -window.updateSettingsConsumablesPage = updateSettingsConsumablesPage; -window.handleConsumableResetButton = handleConsumableResetButton; diff --git a/old_frontend/lib/settings-info.html b/old_frontend/lib/settings-info.html deleted file mode 100644 index d779094f..00000000 --- a/old_frontend/lib/settings-info.html +++ /dev/null @@ -1,134 +0,0 @@ - - -
- Settings -
-
Info
-
-
-
- - - System - - -
- Device Manufacturer: -
-
- ??? -
-
- -
- Device Model: -
-
- ??? -
-
- -
- Valetudo Device Implementation: -
-
- ??? -
-
- - - -
- Valetudo - - -
- Running Valetudo version: -
-
- ??? -
-
- -
- Running commit id: -
-
- ??? -
-
- -
- Newest Valetudo version: -
-
- Check for new Valetudo Version -
-
- - -
- Refresh Log - Unknown log level -
-
- - - -
- - - - -
diff --git a/old_frontend/lib/settings-info.js b/old_frontend/lib/settings-info.js deleted file mode 100644 index 23b8d8f3..00000000 --- a/old_frontend/lib/settings-info.js +++ /dev/null @@ -1,127 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -var currentLoglevel = ""; -var loglevelPresets = []; - -async function updateSettingsInfoPage() { - var loadingBarSettingsInfo = document.getElementById("loading-bar-settings-info"); - - loadingBarSettingsInfo.setAttribute("indeterminate", "indeterminate"); - try { - let valetudoVersionRes = await ApiService.getValetudoVersion(); - document.getElementById("info_valetudo_version").innerText = valetudoVersionRes.release; - document.getElementById("info_valetudo_commit").innerText = valetudoVersionRes.commit; - - let robotRes = await ApiService.getRobot(); - document.getElementById("info_device_valetudo_implementation").innerText = robotRes.implementation; - document.getElementById("info_device_model_manufacturer").innerText = robotRes.manufacturer; - document.getElementById("info_device_model_name").innerText = robotRes.modelName; - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsInfo.removeAttribute("indeterminate"); - } -} - -async function checkNewValetudoVersion() { - var loadingBarSettingsInfo = document.getElementById("loading-bar-settings-info"); - - loadingBarSettingsInfo.setAttribute("indeterminate", "indeterminate"); - try { - let res = await fetch("https://api.github.com/repos/Hypfer/Valetudo/releases", {method: "GET"}); - if (!res.ok) { - // noinspection ExceptionCaughtLocallyJS - throw Error(await res.text()); - } - let json = await res.json(); - let info_valetudo_newest_release = json[0]; - document.getElementById("info_newest_valetudo_version").innerHTML = - info_valetudo_newest_release.tag_name; - document.getElementById("info_valetudo_update_url").innerHTML = - "" + - info_valetudo_newest_release.html_url + ""; - if (document.getElementById("info_valetudo_version").innerHTML !== - info_valetudo_newest_release.tag_name) { - document.getElementById("info_valetudo_update_url_list").style.display = - ""; // make entry visible if newer version is availiable - } - } catch (err) { - ons.notification.toast(err.message, {buttonLabel: "Dismiss", timeout: 1500}); - } finally { - loadingBarSettingsInfo.removeAttribute("indeterminate"); - } -} - -async function updateValetudoLogLevels() { - var loglevelButton = document.getElementById("settings-info-valetudo-loglevel-button"); - var levels = await ApiService.getValetudoLogLevel(); - - loglevelPresets = levels.presets; - currentLoglevel = levels.current; - if (loglevelPresets) { - loglevelButton.removeAttribute("disabled"); - } else { - loglevelButton.setAttribute("disabled","disabled"); - } - if (currentLoglevel) { - loglevelButton.innerHTML = "Log level: " + currentLoglevel; - } else { - loglevelButton.innerHTML = "Unknown log level"; - } -} - -async function initValetudoLog() { - await updateValetudoLogLevels(); - await getValetudoLog(); -} - -async function getValetudoLog() { - var loadingBarSettingsInfo = document.getElementById("loading-bar-settings-info"); - var logTextArea = document.getElementById("settings-info-valetudo-log"); - - loadingBarSettingsInfo.setAttribute("indeterminate", "indeterminate"); - try { - var valetudoLogRes = await ApiService.getValetudoLogContent(); - logTextArea.value = valetudoLogRes || "Empty Logfile"; - logTextArea.scrollTop = logTextArea.scrollHeight; - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsInfo.removeAttribute("indeterminate"); - } -} - -async function handleLoglevelButton() { - var loadingBarSettingsInfo = document.getElementById("loading-bar-settings-info"); - var loglevelButton = document.getElementById("settings-info-valetudo-loglevel-button"); - var index = await ons.openActionSheet({ - title: "Select log level", - cancelable: true, - buttons: [...loglevelPresets, {label: "Cancel", icon: "md-close"}] - }); - var logLevel = loglevelPresets[index]; - - if (logLevel) { - loadingBarSettingsInfo.setAttribute("indeterminate", "indeterminate"); - loglevelButton.setAttribute("disabled", "disabled"); - try { - await ApiService.setValetudoLogLevel(logLevel); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsInfo.removeAttribute("indeterminate"); - loglevelButton.removeAttribute("disabled"); - } - } - await updateValetudoLogLevels(); -} - -window.updateSettingsInfoPage = updateSettingsInfoPage; -window.checkNewValetudoVersion = checkNewValetudoVersion; -window.initValetudoLog = initValetudoLog; -window.getValetudoLog = getValetudoLog; -window.handleLoglevelButton = handleLoglevelButton; diff --git a/old_frontend/lib/settings-mqtt.html b/old_frontend/lib/settings-mqtt.html deleted file mode 100644 index a33673cb..00000000 --- a/old_frontend/lib/settings-mqtt.html +++ /dev/null @@ -1,248 +0,0 @@ - - -
- Settings -
-
MQTT
-
-
-
- - - General - - -
- Enabled: -
- -
-
- - Connection - - -
- Host: -
- -
- -
- Port: -
- -
-
- - TLS - - -
- Enabled: -
- -
- -
- CA: -
- -
-
- - Credentials Authentication - - -
- Enabled: -
- -
- -
- Username: -
- -
- -
- Password: -
- -
-
- - Client Certificate Authentication - - -
- Enabled: -
- -
- -
- Certificate: -
- -
- -
- Key: -
- -
-
- - Identity - - -
- Friendly name: -
- -
- -
- Identifier: -
- -
-
- - Homie autodiscovery - - -
- Enabled: -
- -
- -
- Provide autodiscovery for "I Can't Believe It's Not Valetudo" map: -
- -
- -
- Delete autodiscovery on shutdown: -
- -
-
- - Home Assistant autodiscovery - - -
- Enabled: -
- -
- -
- Delete autodiscovery on shutdown: -
- -
-
- - - Customization - - -
- Topic Prefix: -
- -
- -
- Provide map data: -
- -
-
- - - -
- Save MQTT configuration -
-
-
- - - - -
diff --git a/old_frontend/lib/settings-mqtt.js b/old_frontend/lib/settings-mqtt.js deleted file mode 100644 index fda32c14..00000000 --- a/old_frontend/lib/settings-mqtt.js +++ /dev/null @@ -1,212 +0,0 @@ -/*global ons, fn*/ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsMqttPage() { - var loadingBarSettingsMqtt = document.getElementById("loading-bar-settings-mqtt"); - - var mqttInputEnabled = document.getElementById("settings-mqtt-input-enabled"); - - var mqttInputConnectionHost = document.getElementById("settings-mqtt-input-connection-host"); - var mqttInputConnectionPort = document.getElementById("settings-mqtt-input-connection-port"); - - var mqttInputTlsEnabled = document.getElementById("settings-mqtt-input-tls-enabled"); - var mqttInputTlsCa = document.getElementById("settings-mqtt-input-tls-ca"); - - var mqttInputCredentialsAuthEnabled = document.getElementById("settings-mqtt-input-credentials-auth-enabled"); - var mqttInputCredentialsAuthUsername = document.getElementById("settings-mqtt-input-credentials-auth-username"); - var mqttInputCredentialsAuthPassword = document.getElementById("settings-mqtt-input-credentials-auth-password"); - - var mqttInputClientCertAuthEnabled = document.getElementById("settings-mqtt-input-client-cert-auth-enabled"); - var mqttInputClientCertAuthCert = document.getElementById("settings-mqtt-input-client-cert-auth-client-cert"); - var mqttInputClientCertAuthKey = document.getElementById("settings-mqtt-input-client-cert-auth-client-key"); - - var mqttInputIdentityFriendlyName = document.getElementById("settings-mqtt-input-identity-friendly-name"); - var mqttInputIdentityIdentifier = document.getElementById("settings-mqtt-input-identity-identifier"); - - var mqttInputInterfacesHomieEnabled = document.getElementById("settings-mqtt-input-interfaces-homie-enabled"); - var mqttInputInterfacesHomieICBINVProperty = document.getElementById("settings-mqtt-input-interfaces-homie-icbinv-property"); - var mqttInputInterfacesHomieCleanAttrsShutdown = document.getElementById("settings-mqtt-input-interfaces-homie-clean-attrs-shutdown"); - - var mqttInputInterfacesHomeassistantEnabled = document.getElementById("settings-mqtt-input-interfaces-homeassistant-enabled"); - var mqttInputInterfacesHomeassistantCleanAutoconfShutdown = document.getElementById("settings-mqtt-input-interfaces-homeassistant-clean-autoconf-shutdown"); - - var mqttInputCustomizationTopicPrefix = document.getElementById("settings-mqtt-input-customization-topic-prefix"); - var mqttInputCustomizationProvideMapData = document.getElementById("settings-mqtt-input-customization-provide-map-data"); - - [ - mqttInputEnabled, - - mqttInputConnectionHost, - mqttInputConnectionPort, - - mqttInputTlsEnabled, - mqttInputTlsCa, - - mqttInputCredentialsAuthEnabled, - mqttInputCredentialsAuthUsername, - mqttInputCredentialsAuthPassword, - - mqttInputClientCertAuthEnabled, - mqttInputClientCertAuthCert, - mqttInputClientCertAuthKey, - - mqttInputIdentityFriendlyName, - mqttInputIdentityIdentifier, - - mqttInputInterfacesHomieEnabled, - mqttInputInterfacesHomieICBINVProperty, - mqttInputInterfacesHomieCleanAttrsShutdown, - - mqttInputInterfacesHomeassistantEnabled, - mqttInputInterfacesHomeassistantCleanAutoconfShutdown, - - mqttInputCustomizationTopicPrefix, - mqttInputCustomizationProvideMapData - ].forEach(elem => { - elem.addEventListener("input", updateMqttSaveButton) - }); - - loadingBarSettingsMqtt.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getMqttConfig(); - - mqttInputEnabled.checked = (res.enabled === true); - - mqttInputConnectionHost.value = res.connection.host; - mqttInputConnectionPort.value = res.connection.port; - - mqttInputTlsEnabled.checked = (res.connection.tls.enabled === true); - mqttInputTlsCa.value = res.connection.tls.ca; - - mqttInputCredentialsAuthEnabled.checked = (res.connection.authentication.credentials.enabled === true); - mqttInputCredentialsAuthUsername.value = res.connection.authentication.credentials.username; - mqttInputCredentialsAuthPassword.value = res.connection.authentication.credentials.password; - - mqttInputClientCertAuthEnabled.checked = (res.connection.authentication.clientCertificate.enabled === true); - mqttInputClientCertAuthCert.value = res.connection.authentication.clientCertificate.certificate; - mqttInputClientCertAuthKey.value = res.connection.authentication.clientCertificate.key; - - mqttInputIdentityFriendlyName.value = res.identity.friendlyName; - mqttInputIdentityIdentifier.value = res.identity.identifier; - - mqttInputInterfacesHomieEnabled.checked = (res.interfaces.homie.enabled === true); - mqttInputInterfacesHomieICBINVProperty.checked = (res.interfaces.homie.addICBINVMapProperty === true); - mqttInputInterfacesHomieCleanAttrsShutdown.checked = (res.interfaces.homie.cleanAttributesOnShutdown === true); - - mqttInputInterfacesHomeassistantEnabled.checked = (res.interfaces.homeassistant.enabled === true); - mqttInputInterfacesHomeassistantCleanAutoconfShutdown.checked = (res.interfaces.homeassistant.cleanAutoconfOnShutdown === true); - - mqttInputCustomizationTopicPrefix.value = res.customizations.topicPrefix; - mqttInputCustomizationProvideMapData.checked = (res.customizations.provideMapData === true); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsMqtt.removeAttribute("indeterminate"); - } -} - -function updateMqttSaveButton() { - var mqttInputSaveButton = document.getElementById("settings-mqtt-input-save-button"); - var mqttInputConnectionHost = document.getElementById("settings-mqtt-input-connection-host"); - var mqttInputConnectionPort = document.getElementById("settings-mqtt-input-connection-port"); - - if (mqttInputConnectionHost.value && mqttInputConnectionHost.value !== "" && - mqttInputConnectionPort.value && mqttInputConnectionPort.value !== "") { - - mqttInputSaveButton.removeAttribute("disabled"); - } else { - mqttInputSaveButton.setAttribute("disabled", "disabled"); - } -} - -async function handleMqttSettingsSaveButton() { - var loadingBarSettingsMqtt = document.getElementById("loading-bar-settings-mqtt"); - - var mqttInputEnabled = document.getElementById("settings-mqtt-input-enabled"); - - var mqttInputConnectionHost = document.getElementById("settings-mqtt-input-connection-host"); - var mqttInputConnectionPort = document.getElementById("settings-mqtt-input-connection-port"); - - var mqttInputTlsEnabled = document.getElementById("settings-mqtt-input-tls-enabled"); - var mqttInputTlsCa = document.getElementById("settings-mqtt-input-tls-ca"); - - var mqttInputCredentialsAuthEnabled = document.getElementById("settings-mqtt-input-credentials-auth-enabled"); - var mqttInputCredentialsAuthUsername = document.getElementById("settings-mqtt-input-credentials-auth-username"); - var mqttInputCredentialsAuthPassword = document.getElementById("settings-mqtt-input-credentials-auth-password"); - - var mqttInputClientCertAuthEnabled = document.getElementById("settings-mqtt-input-client-cert-auth-enabled"); - var mqttInputClientCertAuthCert = document.getElementById("settings-mqtt-input-client-cert-auth-client-cert"); - var mqttInputClientCertAuthKey = document.getElementById("settings-mqtt-input-client-cert-auth-client-key"); - - var mqttInputIdentityFriendlyName = document.getElementById("settings-mqtt-input-identity-friendly-name"); - var mqttInputIdentityIdentifier = document.getElementById("settings-mqtt-input-identity-identifier"); - - var mqttInputInterfacesHomieEnabled = document.getElementById("settings-mqtt-input-interfaces-homie-enabled"); - var mqttInputInterfacesHomieICBINVProperty = document.getElementById("settings-mqtt-input-interfaces-homie-icbinv-property"); - var mqttInputInterfacesHomieCleanAttrsShutdown = document.getElementById("settings-mqtt-input-interfaces-homie-clean-attrs-shutdown"); - - var mqttInputInterfacesHomeassistantEnabled = document.getElementById("settings-mqtt-input-interfaces-homeassistant-enabled"); - var mqttInputInterfacesHomeassistantCleanAutoconfShutdown = document.getElementById("settings-mqtt-input-interfaces-homeassistant-clean-autoconf-shutdown"); - - var mqttInputCustomizationTopicPrefix = document.getElementById("settings-mqtt-input-customization-topic-prefix"); - var mqttInputCustomizationProvideMapData = document.getElementById("settings-mqtt-input-customization-provide-map-data"); - loadingBarSettingsMqtt.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.saveMqttConfig({ - "enabled": mqttInputEnabled.checked, - "connection": { - "host": mqttInputConnectionHost.value, - "port": parseInt(mqttInputConnectionPort.value), - "tls": { - "enabled": mqttInputTlsEnabled.checked, - "ca": mqttInputTlsCa.value - }, - "authentication": { - "credentials": { - "enabled": mqttInputCredentialsAuthEnabled.checked, - "username": mqttInputCredentialsAuthUsername.value, - "password": mqttInputCredentialsAuthPassword.value - }, - "clientCertificate": { - "enabled": mqttInputClientCertAuthEnabled.checked, - "certificate": mqttInputClientCertAuthCert.value, - "key": mqttInputClientCertAuthKey.value - } - } - }, - "identity": { - "friendlyName": mqttInputIdentityFriendlyName.value, - "identifier": mqttInputIdentityIdentifier.value - }, - "interfaces": { - "homie": { - "enabled": mqttInputInterfacesHomieEnabled.checked, - "addICBINVMapProperty": mqttInputInterfacesHomieICBINVProperty.checked, - "cleanAttributesOnShutdown": mqttInputInterfacesHomieCleanAttrsShutdown.checked - }, - "homeassistant": { - "enabled": mqttInputInterfacesHomeassistantEnabled.checked, - "cleanAutoconfOnShutdown": mqttInputInterfacesHomeassistantCleanAutoconfShutdown.checked - } - }, - "customizations": { - "topicPrefix": mqttInputCustomizationTopicPrefix.value, - "provideMapData": mqttInputCustomizationProvideMapData.checked - } - }); - - ons.notification.toast( - "MQTT settings saved. MQTT Client will apply changes now.", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - fn.popPage(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsMqtt.removeAttribute("indeterminate"); - } -} - -window.updateSettingsMqttPage = updateSettingsMqttPage; -window.handleMqttSettingsSaveButton = handleMqttSettingsSaveButton; diff --git a/old_frontend/lib/settings-persistent-data.html b/old_frontend/lib/settings-persistent-data.html deleted file mode 100644 index 22eca651..00000000 --- a/old_frontend/lib/settings-persistent-data.html +++ /dev/null @@ -1,117 +0,0 @@ - - -
- Settings -
-
Persistent Data
-
-
-
- - Persistent Data Configuration - - - Persistent data is a feature of some robots which allows to save no-go areas and virtual walls. It also allows the robot to drive back to the dock wherever it is and keeps the map from being rotated. - - - - - - - - - - - - -

This deletes the currently saved map, all no-go areas and virtual walls. Are you sure to proceed?

- Delete now! - Cancel -
- - - - -
diff --git a/old_frontend/lib/settings-persistent-data.js b/old_frontend/lib/settings-persistent-data.js deleted file mode 100644 index 85ad2e45..00000000 --- a/old_frontend/lib/settings-persistent-data.js +++ /dev/null @@ -1,111 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -function disableResetMap(flag) { - const resetMapButton = document.getElementById("reset_map_button"); - if (flag) { - resetMapButton.setAttribute("disabled", "true"); - } else { - resetMapButton.removeAttribute("disabled"); - } -} - -async function initForm() { - var labMode = document.getElementById("lab_mode_enabled"); - labMode.addEventListener("change", function() { - disableResetMap(!labMode.checked); - }); - - const res = await ApiService.getPersistentMapCapabilityStatus(); - - labMode.checked = (res && res.enabled === true); - disableResetMap(!labMode.checked); -} - -async function updateSettingsPersistentDataPage() { - var loadingBarSettingsPersistentData = document.getElementById("loading-bar-settings-persistent-data"); - - loadingBarSettingsPersistentData.setAttribute("indeterminate", "indeterminate"); - - try { - let persistentMapEnabled = false; - const capabilities = await ApiService.getCapabilities(); - const state = await ApiService.getVacuumState(); - if (state) { - const PersistentMapSettingStateAttribute = state.find(e => e.__class === "PersistentMapSettingStateAttribute"); - - if (PersistentMapSettingStateAttribute) { - persistentMapEnabled = PersistentMapSettingStateAttribute.value === "enabled"; - } - } - - if (Array.isArray(capabilities) && capabilities.includes("PersistentMapControlCapability")) { - document.getElementById("persistent_data_control_form").classList.remove("hidden"); - - await initForm(); - } else { - loadingBarSettingsPersistentData.removeAttribute("indeterminate"); - - if (persistentMapEnabled === true) { - document.getElementById("persistent_data_supported").classList.remove("hidden"); - } else { - document.getElementById("persistent_data_not_supported").classList.remove("hidden"); - } - } - if (Array.isArray(capabilities) && capabilities.includes("MapResetCapability")) { - document.getElementById("reset_map_row").classList.remove("hidden"); - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsPersistentData.removeAttribute("indeterminate"); - } -} - -async function resetMap() { - var loadingBarSettingsPersistentData = - document.getElementById("loading-bar-settings-persistent-data"); - - loadingBarSettingsPersistentData.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.resetPersistentMaps(); - ons.notification.toast("Map resetted!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsPersistentData.removeAttribute("indeterminate"); - } -} - -async function savePersistentData() { - var loadingBarSettingsPersistentData = - document.getElementById("loading-bar-settings-persistent-data"); - - var labMode = document.getElementById("lab_mode_enabled"); - const labStatus = true === labMode.checked; - - loadingBarSettingsPersistentData.setAttribute("indeterminate", "indeterminate"); - try { - if (labStatus === true) { - await ApiService.enablePersistentMaps(); - } else { - await ApiService.disablePersistentMaps(); - } - - ons.notification.toast("Saved settings!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsPersistentData.removeAttribute("indeterminate"); - } -} - -window.updateSettingsPersistentDataPage = updateSettingsPersistentDataPage; -window.disableResetMap = disableResetMap; -window.resetMap = resetMap; -window.savePersistentData = savePersistentData; diff --git a/old_frontend/lib/settings-sound-voice.html b/old_frontend/lib/settings-sound-voice.html deleted file mode 100644 index d8bea0ba..00000000 --- a/old_frontend/lib/settings-sound-voice.html +++ /dev/null @@ -1,73 +0,0 @@ - - -
- Settings -
-
Sound Volume
-
-
-
- - - Sound Volume Settings - - -
- Volume: -
- -
- -
- Save sound volume -
-
- -
- Test sound volume -
-
-
- - - -
diff --git a/old_frontend/lib/settings-sound-voice.js b/old_frontend/lib/settings-sound-voice.js deleted file mode 100644 index 6f23e9aa..00000000 --- a/old_frontend/lib/settings-sound-voice.js +++ /dev/null @@ -1,181 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsSoundVolumePage() { - var loadingBarSettingsSoundVolume = document.getElementById("loading-bar-settings-sound-voice"); - var soundVolumeInputVolume = document.getElementById("settings-sound-voice-input-volume"); - - loadingBarSettingsSoundVolume.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getSpeakerVolume(); - soundVolumeInputVolume.value = res.volume; - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsSoundVolume.removeAttribute("indeterminate"); - } -} - -function updateSoundVolumeSaveButton() { - var soundVolumeInputVolume = document.getElementById("settings-sound-voice-input-volume"); - var soundVolumeInputSaveButton = document.getElementById("settings-sound-voice-input-save-button"); - - if (soundVolumeInputVolume.value && soundVolumeInputVolume.value !== "") { - soundVolumeInputSaveButton.removeAttribute("disabled"); - } else { - soundVolumeInputSaveButton.setAttribute("disabled", "disabled"); - } -} - -async function handleSoundVolumeSettingsSaveButton() { - var loadingBarSettingsSoundVolume = document.getElementById("loading-bar-settings-sound-voice"); - var soundVolumeInputVolume = document.getElementById("settings-sound-voice-input-volume"); - - loadingBarSettingsSoundVolume.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.setSpeakerVolume(parseInt(soundVolumeInputVolume.value)); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsSoundVolume.removeAttribute("indeterminate"); - } -} - -async function handleSoundVolumeSettingsTestButton() { - var loadingBarSettingsSoundVolume = document.getElementById("loading-bar-settings-sound-voice"); - - loadingBarSettingsSoundVolume.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.testSpeakerVolume(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsSoundVolume.removeAttribute("indeterminate"); - } -} - -function InitSettingsSoundVolumePage() { - /*var voiceUploadForm = document.getElementById("voice-upload-form"); - - voiceUploadForm.onsubmit = - function(event) { - var loadingBarSettingsSoundVolume = document.getElementById("loading-bar-settings-sound-voice"); - var voicePackUploadButton = document.getElementById("settings-sound-voice-upload-pack-button"); - var voicePackFileBrowser = document.getElementById("settings-sound-voice-upload-browser"); - - event.preventDefault(); - var file = voicePackFileBrowser.files[0]; - if (file === undefined) { - ons.notification.toast("Please select a voice pack before uploading.", - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } else { - loadingBarSettingsSoundVolume.removeAttribute("indeterminate"); - voicePackUploadButton.disabled = true; - var uploadText = voicePackUploadButton.innerText; - voicePackUploadButton.innerText = "Uploading voice pack..."; - postFile( - "api/install_voice_pack", file, - function(p) { - loadingBarSettingsSoundVolume.value = (p * 0.9); - }, - function(err, res) { - if (err) { - ons.notification.toast( - err, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - voicePackUploadButton.innerText = uploadText; - voicePackUploadButton.disabled = false; - loadingBarSettingsSoundVolume.value = 0; - } else { - voicePackUploadButton.innerText = "Installing voice pack..."; - getVoicePackInstallStatus(function(err, data) { - if (!err) { - loadingBarSettingsSoundVolume.value = 90 + (data.progress * 0.1); - - if (data.progress === 100 || data.error !== 0) { - if (data.error !== 0) { - ons.notification.toast("Failed to install voice pack.", { - buttonLabel: "Dismiss", - timeout: window.fn.toastErrorTimeout - }); - } else { - ons.notification.toast("Voice pack was successfully installed.", - { - buttonLabel: "Dismiss", - timeout: window.fn.toastOKTimeout - }); - } - voicePackUploadButton.innerText = uploadText; - voicePackUploadButton.disabled = false; - loadingBarSettingsSoundVolume.value = 0; - } - } else { - voicePackUploadButton.innerText = uploadText; - voicePackUploadButton.disabled = false; - loadingBarSettingsSoundVolume.value = 0; - } - }); - } - }); - } - }; */ - - updateSettingsSoundVolumePage(); -} -/* -function postFile(url, path, progressCallback, callback) { - var formData = new FormData(); - formData.append("file", path); - - var request = new XMLHttpRequest(); - request.onerror = function(e) { - console.error(request); - callback("There was an error: " + request.status); - }; - - request.onload = function(e) { - if (request.status >= 200 && request.status < 400) { - try { - callback(null, JSON.parse(request.responseText)); - } catch (err) { - callback(null, request.responseText); - } - } else { - console.error(request); - callback("There was an error: " + request.status); - } - }; - - request.upload.onprogress = function(e) { - var p = Math.round(100 / e.total * e.loaded); - progressCallback(p); - }; - - request.onerror = function() { - callback("Connection error"); - }; - - request.open("POST", url); - request.send(formData); -} - -function getVoicePackInstallStatus(callback) { - setTimeout(async function() { - try { - let res = await ApiService.getInstallVoicePackStatus(); - callback(null, res); - if (res.progress !== 100 && res.error === 0) { - getVoicePackInstallStatus(callback); - } - } catch (err) { - callback(err); - } - }, 1000); -} */ - -window.InitSettingsSoundVolumePage = InitSettingsSoundVolumePage; -window.updateSoundVolumeSaveButton = updateSoundVolumeSaveButton; -window.handleSoundVolumeSettingsSaveButton = handleSoundVolumeSettingsSaveButton; -window.handleSoundVolumeSettingsTestButton = handleSoundVolumeSettingsTestButton; diff --git a/old_frontend/lib/settings-timers.html b/old_frontend/lib/settings-timers.html deleted file mode 100644 index e50b9ca0..00000000 --- a/old_frontend/lib/settings-timers.html +++ /dev/null @@ -1,174 +0,0 @@ - - -
-
- -

Select the date the timer should be triggered on.
Empty means any month/day.

- - Month - - - - Day - - -
- -

Select the time the timer should be triggered on.
Empty means any hour/minute.

- - Hour - - - - Minute - - -
- -

Select the days the timer should be triggered on.
Empty means any day.

- - Days - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Cancel - Save -
-
-
-
- -
-
- - Start Hour - - Start Minute - - - - End Hour - - End Minute - - -
- Cancel - Save - -
-
-
-
- -
-
- Your current timezone is set to:
-

-
- Close - Save - -
-
-
-
- -
- Settings -
-
Timers
-
- -
-
- - - - "Do Not Disturb" - Timer - - - - - - To edit cleaning timers you may use the new UI. - - - - - - -
diff --git a/old_frontend/lib/settings-timers.js b/old_frontend/lib/settings-timers.js deleted file mode 100644 index 748cee80..00000000 --- a/old_frontend/lib/settings-timers.js +++ /dev/null @@ -1,464 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; -import {TimezoneService} from "./services/timezone.service.js"; - -async function showTimeZoneDialog() { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - try { - let currentTimeZone = await ApiService.getTimezone(); - - var timeZoneSelection = document.getElementById("timezone-selection"); - if (timeZoneSelection.childElementCount === 0) { - // initialize select options only if not already done - var allTimezones = await TimezoneService.getAllTimezones(); - allTimezones.forEach(function(tmpTimeZone) { - var tmpOption = document.createElement("option"); - tmpOption.innerText = tmpTimeZone; - tmpOption.value = tmpTimeZone; - if (tmpTimeZone === currentTimeZone) { - tmpOption.selected = true; - } - timeZoneSelection.appendChild(tmpOption); - }); - } else { - // adjust selection to match server side setting - for (var i = 0; i < timeZoneSelection.options.length; i++) { - let tmpOption = timeZoneSelection.options[i]; - tmpOption.selected = tmpOption.value === currentTimeZone; - } - } - document.getElementById("edit-timezone-dialog").show(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } -} - -function hideTimeZoneDialog() { - document.getElementById("edit-timezone-dialog").hide(); -} - -async function saveTimeZone() { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - - var timeZoneSelection = document.getElementById("timezone-selection"); - var newTimezone = timeZoneSelection.options[timeZoneSelection.selectedIndex].value; - - let answer = await ons.notification.confirm("Do you really want to set your timezone to \"" + newTimezone + "\"?"); - - if (answer === 1) { - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.setTimezone(newTimezone); - hideTimeZoneDialog(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } - } -} - -var showDndTimerDialog = function(startHour, startMinute, endHour, endMinute) { - document.getElementById("edit-dnd-form").start_hour.value = (startHour >= 0 ? startHour : ""); - document.getElementById("edit-dnd-form").start_minute.value = - (startMinute >= 0 ? startMinute : ""); - document.getElementById("edit-dnd-form").end_hour.value = (endHour >= 0 ? endHour : ""); - document.getElementById("edit-dnd-form").end_minute.value = (endMinute >= 0 ? endMinute : ""); - document.getElementById("edit-dnd-timer-dialog").show(); -}; - -var hideDndTimerDialog = function() { - document.getElementById("edit-dnd-timer-dialog").hide(); -}; - -// TODO: There should be some util to convert numbers to leading zero numbers -function asTwoDigitNumber(number) { - if (number < 10) { - return "0" + number; - } else { - return number; - } -} - -async function updateDndTimerPage() { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - var dndTimerList = document.getElementById("settings-dnd-timer-list"); - - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - while (dndTimerList.lastChild) { - dndTimerList.removeChild(dndTimerList.lastChild); - } - try { - const robotCapabilities = await ApiService.getCapabilities() || []; - - if(!robotCapabilities.includes("DoNotDisturbCapability")) { - dndTimerList.appendChild(ons.createElement( - "\n" + - "
Your robot doesn't support DND timers.
" + - "
")); - return; - } - - let res = await ApiService.getDndConfiguration(); - if (res.length === 0 || !(res.enabled) ) { - // no timer is enabled yet, show possibility to add dnd timer - dndTimerList.appendChild(ons.createElement( - "\n" + - "
There is no DND timer enabled yet.
" + - "
" + - " " + - " " + - " " + - "
" + - "
")); - } else { - // Show current active timer - const offset = new Date().getTimezoneOffset() *-1; - const dndTime = { - start: convertTime(res.start.hour, res.start.minute, offset), - end: convertTime(res.end.hour, res.end.minute, offset) - }; - - dndTimerList.appendChild(ons.createElement( - "\n" + - "
DND will start at " + dndTime.start.hour + ":" + - asTwoDigitNumber(dndTime.start.minute) + " and end on " + - dndTime.end.hour + ":" + asTwoDigitNumber(dndTime.end.minute) + "
" + - "
" + - " " + - " " + - " " + - " " + - " " + - " " + - "
" + - "
" - )); - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } -} - -function convertTime(hour, minute, offset) { - const dayInMinutes = 24*60; - - const inMidnightOffset = hour * 60 + minute; - let outMidnightOffset = inMidnightOffset + offset; - - if (outMidnightOffset < 0) { - outMidnightOffset += dayInMinutes; - } else if (outMidnightOffset > dayInMinutes) { - outMidnightOffset -= dayInMinutes; - } - - return { - hour: outMidnightOffset/60 |0, - minute: outMidnightOffset%60 - }; -} - -async function deleteDndTimer() { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - try { - let answer = await ons.notification.confirm("Do you really want to disable DND?"); - if (answer === 1) { - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - await ApiService.setDndConfiguration(false, 0, 0, 0, 0); - updateDndTimerPage(); - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } - -} - -async function saveDndTimer() { - var start_hour = document.getElementById("edit-dnd-form").start_hour.value; - var start_minute = document.getElementById("edit-dnd-form").start_minute.value; - var end_hour = document.getElementById("edit-dnd-form").end_hour.value; - var end_minute = document.getElementById("edit-dnd-form").end_minute.value; - - if (start_hour && start_minute && end_hour && end_minute) { - const offset = new Date().getTimezoneOffset(); - const dndTime = { - start: convertTime(parseInt(start_hour), parseInt(start_minute), offset), - end: convertTime(parseInt(end_hour), parseInt(end_minute), offset) - }; - - try { - await ApiService.setDndConfiguration( - true, - dndTime.start.hour, - dndTime.start.minute, - dndTime.end.hour, - dndTime.end.minute - ); - - hideDndTimerDialog(); - updateDndTimerPage(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - } else { - ons.notification.toast( - "Could not save DND Timer since not all required attributes are provided!", - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } -} - -async function updateSettingsTimersPage() { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - var timersSettingsTimersList = document.getElementById("settings-timers-timer-list"); - - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - while (timersSettingsTimersList.lastChild) { - timersSettingsTimersList.removeChild(timersSettingsTimersList.lastChild); - } - try { - let res = await ApiService.getTimers(); - if (res === null || res === undefined || res.length === 0) { - timersSettingsTimersList.appendChild(ons.createElement( - "\n" + - "
There is no timer configured yet.
" + - "
")); - - return; - } - - res.forEach(function(timer) { - // ADD EDIT (equals create new + delete!) - var elem = ons.createElement( - "\n" + - "
" + timer.human_desc + " (" + timer.cron + ")
" + - "
" + - " " + - " " + - " " + - " " + - "
" + - "
"); - - elem.querySelector(".timer-active-switch") - .addEventListener("change", - function(event) { - toggleTimer(timer.id, event.value); - }); - - elem.querySelector(".timer-delete") - .addEventListener("click", function(event) { - deleteTimer(timer.id); - }); - - timersSettingsTimersList.appendChild(elem); - }); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } -} - -async function toggleTimer(id, enabled) { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - - disableTimerInputElements(); - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.toggleTimer(id, enabled); - window.setTimeout(function() { - updateSettingsTimersPage(); - }, 350); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } -} - -function disableTimerInputElements() { - var timersSettingsTimersList = document.getElementById("settings-timers-timer-list"); - - timersSettingsTimersList.querySelectorAll(".timer-active-switch") - .forEach(function(elem) { - elem.setAttribute("disabled", "disabled"); - }); - timersSettingsTimersList.querySelectorAll(".timer-delete") - .forEach(function(elem) { - elem.setAttribute("disabled", "disabled"); - }); -} - -function enableTimerInputElements() { - var timersSettingsTimersList = document.getElementById("settings-timers-timer-list"); - - timersSettingsTimersList.querySelectorAll(".timer-active-switch") - .forEach(function(elem) { - elem.removeAttribute("disabled"); - }); - timersSettingsTimersList.querySelectorAll(".timer-delete") - .forEach(function(elem) { - elem.removeAttribute("disabled"); - }); -} - -async function deleteTimer(id) { - var loadingBarSettingsTimers = document.getElementById("loading-bar-settings-timers"); - - disableTimerInputElements(); - let answer = await ons.notification.confirm("Do you really want to delete this timer?"); - if (answer === 1) { - loadingBarSettingsTimers.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.deleteTimer(id); - updateSettingsTimersPage(); - } catch (err) { - ons.notification.toast( - err, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsTimers.removeAttribute("indeterminate"); - } - } else { - enableTimerInputElements(); - } -} - -function clearNewTimerDialog() { - document.getElementById("add-timer-form").month.value = ""; - document.getElementById("add-timer-form").day.value = ""; - document.getElementById("add-timer-form").hour.value = ""; - document.getElementById("add-timer-form").minute.value = ""; - var daysRunner; - for (daysRunner = 0; daysRunner < document.getElementById("add-timer-form").days.length; - daysRunner++) { - document.getElementById("add-timer-form").days[daysRunner].checked = false; - } -} - -async function addNewTimer() { - // get and validate selected month - var monthValue = document.getElementById("add-timer-form").month.value; - if (monthValue === "") { - monthValue = "*"; - } else { - // verify limits of month - var monthNumber = parseInt(monthValue) || 0; - if (monthNumber < 1) { - monthValue = 1; - } else if (monthNumber > 12) { - monthValue = 12; - } - } - // get and validate selected day - var dayValue = document.getElementById("add-timer-form").day.value; - if (dayValue === "") { - dayValue = "*"; - } else { - // verify limits of day - var dayNumber = parseInt(dayValue) || 0; - if (dayNumber < 1) { - dayValue = 1; - } else if (dayNumber > 31) { - dayValue = 31; - } - } - // get and validate selected hour - var hoursValue = document.getElementById("add-timer-form").hour.value; - if (hoursValue === "") { - hoursValue = "*"; - } else { - // verify limits of hour - var hoursNumber = parseInt(hoursValue) || 0; - if (hoursNumber < 0) { - hoursValue = 0; - } else if (hoursNumber > 23) { - hoursValue = hoursNumber % 24; - } - } - // get and validate selected minute - var minutesValue = document.getElementById("add-timer-form").minute.value; - if (minutesValue === "") { - minutesValue = "*"; - } else { - // verify limits of minute - var minutesNumber = parseInt(minutesValue) || 0; - if (minutesNumber < 0) { - minutesValue = 0; - } else if (minutesNumber > 59) { - minutesValue = minutesNumber % 60; - } - } - // get and validate selected days - var daySelection = ""; - var daysElementArray = document.getElementById("add-timer-form").days; - var daysTotal = daysElementArray.length; - var daysRunner; - for (daysRunner = 0; daysRunner < daysTotal; daysRunner++) { - if (daysElementArray[daysRunner].checked) { - var currentDayValue = daysElementArray[daysRunner].value; - if (daySelection === "") { - daySelection = currentDayValue; - } else { - daySelection += "," + currentDayValue; - } - } - } - if (daySelection === "") { - daySelection = "*"; - } - // build cron timer - var cronTimer = "" + minutesValue + " " + hoursValue + " " + dayValue + " " + monthValue + " " + - daySelection; - // save timer - try { - await ApiService.addTimer(cronTimer); - updateSettingsTimersPage(); - hideNewTimerDialog(); - } catch (err) { - ons.notification.toast( - err, {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } -} - -// if timerId is set to -1, the timer is deleted -var showAddTimerDialog = function(timerId) { - if (timerId === -1) { - clearNewTimerDialog(); - } - document.getElementById("add-timer-dialog").show(); -}; - -var hideNewTimerDialog = function() { - document.getElementById("add-timer-dialog").hide(); -}; - -window.updateSettingsTimersPage = updateSettingsTimersPage; -window.updateDndTimerPage = updateDndTimerPage; -window.showTimeZoneDialog = showTimeZoneDialog; -window.hideTimeZoneDialog = hideTimeZoneDialog; -window.saveTimeZone = saveTimeZone; -window.showDndTimerDialog = showDndTimerDialog; -window.hideDndTimerDialog = hideDndTimerDialog; -window.deleteDndTimer = deleteDndTimer; -window.saveDndTimer = saveDndTimer; -window.addNewTimer = addNewTimer; -window.showAddTimerDialog = showAddTimerDialog; -window.hideNewTimerDialog = hideNewTimerDialog; diff --git a/old_frontend/lib/settings-token.html b/old_frontend/lib/settings-token.html deleted file mode 100644 index 17f41347..00000000 --- a/old_frontend/lib/settings-token.html +++ /dev/null @@ -1,48 +0,0 @@ - - -
- Settings -
-
Token
-
-
-
- - - Current Token - - -
- Cloud Token -
-
- - ???????????????????????????????? - -
-
- -
- Local Token -
-
- - ???????????????????????????????? - -
-
-
- -
\ No newline at end of file diff --git a/old_frontend/lib/settings-token.js b/old_frontend/lib/settings-token.js deleted file mode 100644 index f9a0a336..00000000 --- a/old_frontend/lib/settings-token.js +++ /dev/null @@ -1,24 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsTokenPage() { - var loadingBarSettingsToken = document.getElementById("loading-bar-settings-token"); - var settingsTokenLabel = { - local: document.getElementById("settings-token-label"), - cloud: document.getElementById("settings-cloud-token-label") - }; - - loadingBarSettingsToken.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getToken(); - settingsTokenLabel.cloud.innerHTML = res.cloud; - settingsTokenLabel.local.innerHTML = res.local; - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsToken.removeAttribute("indeterminate"); - } -} - -window.updateSettingsTokenPage = updateSettingsTokenPage; diff --git a/old_frontend/lib/settings-wifi.html b/old_frontend/lib/settings-wifi.html deleted file mode 100644 index cbbd2eff..00000000 --- a/old_frontend/lib/settings-wifi.html +++ /dev/null @@ -1,92 +0,0 @@ - - -
- Settings -
-
Wifi
-
-
-
- - - Current connection - - -
- Status -
-
- ??? -
-
- -
- SSID -
-
- ??? -
-
- -
- Signal -
-
- -?? dBm -
-
-
- - Wifi Settings - - -
- SSID: -
- -
- -
- Password: -
- -
- -
- Save new Wifi configuration -
-
-
- - - - -
\ No newline at end of file diff --git a/old_frontend/lib/settings-wifi.js b/old_frontend/lib/settings-wifi.js deleted file mode 100644 index b6a52d27..00000000 --- a/old_frontend/lib/settings-wifi.js +++ /dev/null @@ -1,81 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsWifiPage() { - var loadingBarSettingsWifi = document.getElementById("loading-bar-settings-wifi"); - var wifiCurrentConnectionStatusConnected = - document.getElementById("settings-wifi-current-connection-status-connected"); - var wifiCurrentConnectionStatusSSID = - document.getElementById("settings-wifi-current-connection-status-ssid"); - var wifiCurrentConnectionStatusSignal = - document.getElementById("settings-wifi-current-connection-status-signal"); - - var wifiInputSSID = document.getElementById("settings-wifi-input-ssid"); - var wifiInputPassword = document.getElementById("settings-wifi-input-password"); - - wifiInputSSID.addEventListener("input", updateWifiCredentialsSaveButton); - wifiInputPassword.addEventListener("input", updateWifiCredentialsSaveButton); - - loadingBarSettingsWifi.setAttribute("indeterminate", "indeterminate"); - try { - let res = await ApiService.getWifiStatus(); - wifiCurrentConnectionStatusConnected.innerHTML = res.details.state; - if (res.details.state === "connected") { - wifiCurrentConnectionStatusSSID.innerHTML = res.ssid; - wifiCurrentConnectionStatusSignal.innerHTML = `${res.details.signal} dBm`; - - wifiInputSSID.value = res.ssid; - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsWifi.removeAttribute("indeterminate"); - } -} - -function updateWifiCredentialsSaveButton() { - var wifiInputSSID = document.getElementById("settings-wifi-input-ssid"); - var wifiInputPassword = document.getElementById("settings-wifi-input-password"); - var wifiInputSaveButton = document.getElementById("settings-wifi-input-save-button"); - - if (wifiInputSSID.value && wifiInputSSID.value !== "" && wifiInputPassword.value && - wifiInputPassword.value !== "") { - - wifiInputSaveButton.removeAttribute("disabled"); - } else { - wifiInputSaveButton.setAttribute("disabled", "disabled"); - } -} - -async function handleWifiSettingsSaveButton() { - var loadingBarSettingsWifi = document.getElementById("loading-bar-settings-wifi"); - var wifiInputSSID = document.getElementById("settings-wifi-input-ssid"); - var wifiInputPassword = document.getElementById("settings-wifi-input-password"); - - let answer = await ons.notification - .confirm("Are you sure you want to apply the new wifi settings?

" + - "Hint: You can always revert back to the " + - "integrated Wifi Hotspot by pressing the reset button located underneath the lid."); - - if (answer === 1) { - loadingBarSettingsWifi.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.saveWifiConfig(wifiInputSSID.value, wifiInputPassword.value); - await ons.notification - .alert( - "Successfully applied new wifi credentials.
After pressing OK the page will refresh.
" + - "However, you will most likely need to change the URL since the robot will connect to a new wifi."); - location.reload(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSettingsWifi.removeAttribute("indeterminate"); - } - } - -} - -window.updateSettingsWifiPage = updateSettingsWifiPage; -window.handleWifiSettingsSaveButton = handleWifiSettingsSaveButton; diff --git a/old_frontend/lib/settings.html b/old_frontend/lib/settings.html deleted file mode 100644 index f5681c99..00000000 --- a/old_frontend/lib/settings.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/old_frontend/lib/settings.js b/old_frontend/lib/settings.js deleted file mode 100644 index fbe155df..00000000 --- a/old_frontend/lib/settings.js +++ /dev/null @@ -1,41 +0,0 @@ -/*global ons */ -import {ApiService} from "./services/api.service.js"; - -async function updateSettingsPage() { - try { - const robotCapabilities = await ApiService.getCapabilities() || []; - const buttonStateMap = { - info: true, - timers: true, - "carpet-mode": robotCapabilities.includes("CarpetModeControlCapability"), - "cleaning-history": false, // commented out in settings.html? - "persistent-data": robotCapabilities.includes("PersistentMapControlCapability") || - robotCapabilities.includes("MapResetCapability"), - consumables: robotCapabilities.includes("ConsumableMonitoringCapability"), - wifi: robotCapabilities.includes("WifiConfigurationCapability"), - mqtt: true, - token: false, // commented out in settings.html? - sound: robotCapabilities.includes("SpeakerVolumeControlCapability"), - "access-control": true - }; - - Object.keys(buttonStateMap).forEach((key) => { - const state = buttonStateMap[key]; - const element = document.getElementById(`settings-${key}`); - if (element) { - if (state === true) { - element.classList.remove("hidden"); - } else { - element.classList.add("hidden"); - } - } - - }); - } catch (err) { - ons.notification.toast(`Error: ${err.message}`, - { buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout }); - } -} - - -window.updateSettingsPage = updateSettingsPage; diff --git a/old_frontend/lib/spot-configuration-map.html b/old_frontend/lib/spot-configuration-map.html deleted file mode 100644 index c6596959..00000000 --- a/old_frontend/lib/spot-configuration-map.html +++ /dev/null @@ -1,82 +0,0 @@ - - -
-

Edit spot name

- -
- Cancel - Save -
-
-
- -
-
- Spots - -
- - - -
- -
- - - - - - - - - -
- - - - -
diff --git a/old_frontend/lib/spot-configuration-map.js b/old_frontend/lib/spot-configuration-map.js deleted file mode 100644 index 7483de6c..00000000 --- a/old_frontend/lib/spot-configuration-map.js +++ /dev/null @@ -1,103 +0,0 @@ -/*global ons, fn*/ -import {VacuumMap} from "./js/js-modules/vacuum-map.js"; -import {ApiService} from "./services/api.service.js"; - -let map; -let loadingBarSavespot; -let saveButton; -let renameButton; -let infoButton; -let renameDialog; -let renameSpotInput; - -let topPage; -let spotConfig; -let spotToModify; - -function spotMapInit() { - map = new VacuumMap(document.getElementById("spot-configuration-map")); - loadingBarSavespot = document.getElementById("loading-bar-save-spot"); - saveButton = document.getElementById("spot-configuration-save"); - renameButton = document.getElementById("spot-configuration-rename"); - infoButton = document.getElementById("spot-configuration-get-id"); - renameDialog = document.getElementById("rename-spot-dialog"); - renameSpotInput = document.getElementById("rename-spot-input"); - - topPage = fn.getTopPage(); - spotConfig = topPage.data.spotConfig; - spotToModify = topPage.data.spotToModify; - - map.initCanvas(topPage.data.map, {metaData: "forbidden"}); - - updateSpotName(); - - map.addSpot([spotConfig[spotToModify].coordinates[0], spotConfig[spotToModify].coordinates[1]]); - - /** - * Yes, this is a bad solution. - * Go write a better UI - */ - infoButton.onclick = () => { - console.log(spotConfig[spotToModify].id); - alert(spotConfig[spotToModify].id); - }; - - saveButton.onclick = () => { - saveSpot(true); - }; - - renameButton.onclick = () => { - renameSpotInput.value = spotConfig[spotToModify].name; - renameDialog.show(); - }; -} - -async function saveSpot(hide) { - const spotOnMap = map.getLocations().gotoPoints[0]; - spotConfig[spotToModify].coordinates = [spotOnMap.x, spotOnMap.y]; - - loadingBarSavespot.setAttribute("indeterminate", "indeterminate"); - saveButton.setAttribute("disabled", "disabled"); - - try { - await ApiService.saveSpots(spotConfig); - ons.notification.toast( - "Successfully saved spot!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - if (hide) { - fn.popPage(); - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSavespot.removeAttribute("indeterminate"); - saveButton.removeAttribute("disabled"); - } -} - -function updateSpotName() { - document.getElementById("spot-configuration-map-page-h1").innerText = - `Editing spot: ${spotConfig[spotToModify].name}`; -} - -function hideRenameSpotDialog() { - renameDialog.hide(); -} - -function renameSpot() { - var newSpotName = renameSpotInput.value.trim(); - if (newSpotName === "") { - ons.notification.toast("Please enter a spot name", - {buttonLabel: "Dismiss", timeout: 1500}); - } else { - spotConfig[spotToModify].name = newSpotName; - renameDialog.hide(); - saveSpot(false); - updateSpotName(); - } -} - -window.hideRenameSpotDialog = hideRenameSpotDialog; -window.renameSpot = renameSpot; -window.spotMapInit = spotMapInit; diff --git a/old_frontend/lib/zones-configuration-map.html b/old_frontend/lib/zones-configuration-map.html deleted file mode 100644 index dee2dd77..00000000 --- a/old_frontend/lib/zones-configuration-map.html +++ /dev/null @@ -1,84 +0,0 @@ - - -
-

Edit zone name

- -
- Cancel - Save -
-
-
- -
-
- Zones - -
- - - -
- -
- - - - - - - - - - - - -
- - - -
diff --git a/old_frontend/lib/zones-configuration-map.js b/old_frontend/lib/zones-configuration-map.js deleted file mode 100644 index b6a56692..00000000 --- a/old_frontend/lib/zones-configuration-map.js +++ /dev/null @@ -1,108 +0,0 @@ -/*global ons, fn*/ -import {VacuumMap} from "./js/js-modules/vacuum-map.js"; -import {ApiService} from "./services/api.service.js"; - -let map; -let loadingBarSaveZones; -let saveButton; -let renameButton; -let infoButton; -let renameDialog; -let renameZoneInput; - -let topPage; -/** @type {Array<{id:number, name:string, user: boolean, areas: Array}>} */ -let zonesConfig; -let zoneToModify; - -function zoneMapInit() { - map = new VacuumMap(document.getElementById("zone-configuration-map")); - loadingBarSaveZones = document.getElementById("loading-bar-save-zones"); - saveButton = document.getElementById("zones-configuration-save"); - renameButton = document.getElementById("zones-configuration-rename"); - infoButton = document.getElementById("zones-configuration-get-id"); - renameDialog = document.getElementById("rename-zone-dialog"); - renameZoneInput = document.getElementById("rename-zone-input"); - - topPage = fn.getTopPage(); - zonesConfig = topPage.data.zonesConfig; - zoneToModify = topPage.data.zoneToModify; - map.initCanvas(topPage.data.map, {metaData: "forbidden", noGotoPoints: true}); - - updateZoneName(); - for (let zone of zonesConfig[zoneToModify].areas) { - map.addZone([zone[0], zone[1], zone[2], zone[3]], true); - } - - document.getElementById("zones-configuration-add-zone").onclick = () => { - map.addZone(); - }; - - /** - * Yes, this is a bad solution. - * Go write a better UI - */ - infoButton.onclick = () => { - console.log(zonesConfig[zoneToModify].id); - alert(zonesConfig[zoneToModify].id); - }; - - saveButton.onclick = () => { - saveZone(true); - }; - - renameButton.onclick = () => { - renameZoneInput.value = zonesConfig[zoneToModify].name; - renameDialog.show(); - }; -} - -async function saveZone(hide) { - const areasOnMap = map.getLocations().zones.map(zoneCoordinates => [...zoneCoordinates, 1]); - zonesConfig[zoneToModify].areas = areasOnMap; - - loadingBarSaveZones.setAttribute("indeterminate", "indeterminate"); - saveButton.setAttribute("disabled", "disabled"); - - try { - await ApiService.saveZones(zonesConfig); - ons.notification.toast( - "Successfully saved zones!", - {buttonLabel: "Dismiss", timeout: window.fn.toastOKTimeout}); - if (hide) { - fn.popPage(); - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarSaveZones.removeAttribute("indeterminate"); - saveButton.removeAttribute("disabled"); - } -} - -function updateZoneName() { - document.getElementById("zones-configuration-map-page-h1").innerText = - `Editing zone: ${zonesConfig[zoneToModify].name}`; -} - -function hideRenameZoneDialog() { - renameDialog.hide(); -} - -function renameZone() { - var newZoneName = renameZoneInput.value.trim(); - if (newZoneName === "") { - ons.notification.toast("Please enter a spot name", - {buttonLabel: "Dismiss", timeout: 1500}); - } else { - zonesConfig[zoneToModify].name = newZoneName; - renameDialog.hide(); - saveZone(false); - updateZoneName(); - } -} - -window.hideRenameZoneDialog = hideRenameZoneDialog; -window.renameZone = renameZone; -window.zoneMapInit = zoneMapInit; diff --git a/old_frontend/lib/zones.html b/old_frontend/lib/zones.html deleted file mode 100644 index 00156284..00000000 --- a/old_frontend/lib/zones.html +++ /dev/null @@ -1,63 +0,0 @@ - -
- - - - - - - - - - - -
diff --git a/old_frontend/lib/zones.js b/old_frontend/lib/zones.js deleted file mode 100644 index feed8817..00000000 --- a/old_frontend/lib/zones.js +++ /dev/null @@ -1,269 +0,0 @@ -/*global ons, fn*/ - -import {ApiService} from "./services/api.service.js"; - -let loadingBarZones = document.getElementById("loading-bar-zones"); -let zonesList = document.getElementById("zones-list"); -let spotList = document.getElementById("spot-list"); -let forbiddenZonesItem = document.getElementById("forbidden-zones-item"); -let segmentEditItem = document.getElementById("segment-edit-item"); -let zonePresetsItem = document.getElementById("zone-presets-item"); -let gotoLocationPresetsItem = document.getElementById("goto-location-presets-item"); - -/** @type {Array<{id:number, name:string, user: boolean, areas: Array}>} */ -let zonesConfig = []; -let spotConfig = []; - -async function switchToMapZoneEdit(index) { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - try { - let mapData = await ApiService.getLatestMap(); - fn.pushPage({ - "id": "zones-configuration-map.html", - "title": "Zone configuration map", - "data": {"map": mapData, "zonesConfig": zonesConfig, "zoneToModify": index} - }); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarZones.removeAttribute("indeterminate"); - } -} - -async function switchToMapSpotEdit(index) { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - try { - let mapData = await ApiService.getLatestMap(); - fn.pushPage({ - "id": "spot-configuration-map.html", - "title": "Spot configuration map", - "data": {"map": mapData, "spotConfig": spotConfig, "spotToModify": index} - }); - } catch (err) { - ons.notification.toast(err.message,{buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarZones.removeAttribute("indeterminate"); - } -} - -async function switchToForbiddenMarkersEdit(index) { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - try { - let mapData = await ApiService.getLatestMap(); - let supportedVirtualRestrictions = await ApiService.getSupportedVirtualRestrictions(); - - fn.pushPage({ - "id": "forbidden-markers-configuration-map.html", - "title": "Forbidden markers configuration map", - "data": {"map": mapData, supportedVirtualRestrictions: supportedVirtualRestrictions} - }); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarZones.removeAttribute("indeterminate"); - } -} - -async function switchToSegmentEdit(index) { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - try { - let mapData = await ApiService.getLatestMap(); - fn.pushPage({ - "id": "segment-edit-map.html", - "title": "Segment edit map", - "data": {"map": mapData} - }); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarZones.removeAttribute("indeterminate"); - } -} - -function deleteZone(index) { - zonesConfig.splice(index, 1); - saveZones(); -} - -function deleteSpot(index) { - spotConfig.splice(index, 1); - - saveSpots(); -} - -async function saveZones() { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.saveZones(zonesConfig); - generateZonesList(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarZones.removeAttribute("indeterminate"); - } -} - -async function saveSpots() { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - try { - await ApiService.saveSpots(spotConfig); - generateSpotList(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } finally { - loadingBarZones.removeAttribute("indeterminate"); - } -} - -function addNewZone() { - const newZoneName = document.getElementById("add-zone-name").value; - - if (newZoneName.trim() === "") { - ons.notification.toast("Please enter a zone name", - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } else { - zonesConfig.push({name: newZoneName, areas: []}); - } - - saveZones(); -} - -function addNewSpot() { - const newSpotName = document.getElementById("add-spot-name").value; - - if (newSpotName.trim() === "") { - ons.notification.toast("Please enter a spot name", - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } else { - spotConfig.push({name: newSpotName, coordinates: [25000, 25000]}); - } - - saveSpots(); -} - -function generateZonesList() { - let out = ""; - Object.values(zonesConfig).forEach((zone, index) => { - out += ` - - - - Delete - - `; - }); - - out += ` - - - - - - Add - - `; - - zonesList.innerHTML = out; -} - -function generateSpotList() { - let out = ""; - Object.values(spotConfig).forEach((spot, index) => { - out += ` - - - - Delete - - `; - }); - - out += ` - - - - - - Add - - `; - - spotList.innerHTML = out; -} - -async function ZonesInit() { - loadingBarZones.setAttribute("indeterminate", "indeterminate"); - - try { - let robotCapabilities = await ApiService.getRobotCapabilities(); - if (robotCapabilities.includes("CombinedVirtualRestrictionsCapability")) { - forbiddenZonesItem.hidden = false; - } - - if (robotCapabilities.includes("MapSegmentEditCapability") || robotCapabilities.includes("MapSegmentRenameCapability")) { - segmentEditItem.hidden = false; - } - - if (robotCapabilities.includes("ZoneCleaningCapability")) { - zonePresetsItem.hidden = false; - - try { - zonesConfig = Object.values(await ApiService.getZones()); - generateZonesList(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - } - - if (robotCapabilities.includes("GoToLocationCapability")) { - gotoLocationPresetsItem.hidden = false; - - try { - spotConfig = await ApiService.getSpots(); - generateSpotList(); - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - - } - } catch (err) { - ons.notification.toast(err.message, - {buttonLabel: "Dismiss", timeout: window.fn.toastErrorTimeout}); - } - - loadingBarZones.removeAttribute("indeterminate"); -} - -window.ZonesInit = ZonesInit; -window.switchToMapZoneEdit = switchToMapZoneEdit; -window.switchToMapSpotEdit = switchToMapSpotEdit; -window.switchToForbiddenMarkersEdit = switchToForbiddenMarkersEdit; -window.switchToSegmentEdit = switchToSegmentEdit; -window.deleteZone = deleteZone; -window.deleteSpot = deleteSpot; -window.addNewZone = addNewZone; -window.addNewSpot = addNewSpot; - diff --git a/old_frontend/package.json b/old_frontend/package.json deleted file mode 100644 index b16da2c8..00000000 --- a/old_frontend/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "valetudo-frontend", - "description": "Self-contained control webinterface for vacuum robots", - "license": "Apache-2.0", - "author": "", - "engines": { - "node": ">=14" - }, - "scripts": { - "lint": "eslint .", - "lint_fix": "eslint . --fix", - "ts-check": "tsc --noEmit -p jsconfig.json", - "build": "tsc -p jsconfig.json" - }, - "devDependencies": { - "typescript": "^3.8.3" - } -} diff --git a/package-lock.json b/package-lock.json index 1e5a5d39..4ce358e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,36 +1,37 @@ { "name": "valetudo", - "version": "2022.02.0-conga.0", + "version": "2022.09.0-conga.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "valetudo", - "version": "2022.02.0-conga.0", + "version": "2022.09.0-conga.0", "license": "Apache-2.0", "workspaces": [ "backend", "frontend" ], "devDependencies": { - "@typescript-eslint/eslint-plugin": "5.4.0", - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/parser": "5.4.0", - "eslint": "7.32.0", - "eslint-plugin-jsdoc": "37.0.3", + "@typescript-eslint/eslint-plugin": "5.40.0", + "@typescript-eslint/experimental-utils": "5.40.0", + "@typescript-eslint/parser": "5.40.0", + "auto-changelog": "2.4.0", + "eslint": "8.25.0", + "eslint-plugin-jsdoc": "39.3.6", "eslint-plugin-node": "11.1.0", - "eslint-plugin-react": "7.27.1", - "eslint-plugin-react-hooks": "4.3.0", - "eslint-plugin-regexp": "1.5.1", - "eslint-plugin-sort-keys-fix": "^1.1.1", + "eslint-plugin-react": "7.31.10", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-regexp": "1.9.0", + "eslint-plugin-sort-keys-fix": "1.1.2", "eslint-plugin-sort-requires": "git+https://npm@github.com/Hypfer/eslint-plugin-sort-requires.git#2.1.1", "swagger-jsdoc": "git+https://npm@github.com/Hypfer/swagger-jsdoc.git#7.0.0-rc.6-noyaml-monorepo-fix", - "swagger-parser": "^10.0.2", - "typescript": "4.5.2", - "upx": "git+https://npm@github.com/Hypfer/upx#v1.0.7" + "swagger-parser": "10.0.3", + "typescript": "4.8.4", + "upx": "git+https://npm@github.com/Hypfer/upx#1.0.11" }, "engines": { - "node": ">=14" + "node": ">=16" } }, "backend": { @@ -39,30 +40,27 @@ "dependencies": { "@agnoc/core": "~0.16.0-next.7", "@destinationstransfers/ntp": "2.0.0", - "ajv": "8.8.2", - "async-mqtt": "2.6.1", - "axios": "0.24.0", - "body-parser": "1.19.0", - "bonjour-service": "git+https://npm@github.com/Hypfer/bonjour-service.git#113d63c3a07f739001198545d2a9c1043e9a5b0b", + "ajv": "8.11.0", + "async-mqtt": "2.6.3", + "axios": "0.27.2", + "bonjour-service": "1.0.14", "compression": "1.7.4", - "crc": "3.8.0", - "escape-html": "1.0.3", - "express": "4.17.2", + "crc": "4.1.1", + "express": "4.18.2", "express-basic-auth": "1.2.1", "express-dynamic-middleware": "1.0.0", "express-list-endpoints": "6.0.0", - "express-rate-limit": "5.5.1", + "express-rate-limit": "6.6.0", + "hashlru": "git+https://npm@github.com/Hypfer/hashlru#3.0.0", "is-in-subnet": "4.0.1", - "jstoxml": "2.2.7", - "mqtt": "4.2.8", + "jstoxml": "3.2.5", + "mqtt": "4.3.7", "nested-object-assign": "1.0.4", "nested-property": "4.0.0", - "node-ssdp": "4.0.1", - "openapi-validator-middleware": "3.2.4", - "quick-lru": "5.1.1", + "openapi-validator-middleware": "3.2.6", "semaphore": "1.1.0", - "swagger-ui-express": "4.3.0", - "uuid": "8.3.2", + "swagger-ui-express": "4.5.0", + "uuid": "9.0.0", "zoo-ids": "2.0.7" }, "bin": { @@ -70,26 +68,27 @@ }, "devDependencies": { "@types/compression": "1.7.2", - "@types/express": "4.17.13", + "@types/express": "4.17.14", "@types/express-list-endpoints": "6.0.0", - "@types/jstoxml": "2.0.1", - "@types/mocha": "7.0.2", - "@types/node": "16.11.1", + "@types/jstoxml": "2.0.2", + "@types/mocha": "10.0.0", + "@types/node": "18.8.4", "@types/node-ssdp": "4.0.1", "@types/semaphore": "1.1.1", - "@types/uuid": "8.3.3", + "@types/uuid": "8.3.4", "cross-env": "7.0.3", - "mocha": "7.1.1", - "pkg": "5.3.2", + "mocha": "10.0.0", + "pkg": "5.7.0", "should": "13.2.3" }, "engines": { - "node": ">=15" + "node": ">=16" } }, "backend/node_modules/ajv": { - "version": "8.8.2", - "license": "MIT", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -101,393 +100,232 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "backend/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==" - }, - "backend/node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "frontend": { "name": "valetudo-frontend", "dependencies": { - "@emotion/react": "11.6.0", - "@emotion/styled": "11.6.0", - "@fontsource/roboto": "4.5.1", - "@mui/icons-material": "5.2.0", - "@mui/lab": "5.0.0-alpha.48", - "@mui/material": "5.2.0", - "axios": "0.24.0", - "color": "4.0.1", - "date-fns": "2.26.0", - "notistack": "2.0.3", - "react": "17.0.2", + "@emotion/react": "11.10.4", + "@emotion/styled": "11.10.4", + "@fontsource/jetbrains-mono": "4.5.11", + "@fontsource/roboto": "4.5.8", + "@mui/base": "5.0.0-alpha.81", + "@mui/icons-material": "5.10.9", + "@mui/lab": "5.0.0-alpha.82", + "@mui/material": "5.10.9", + "axios": "0.27.2", + "date-fns": "2.29.3", + "jsencrypt": "3.2.1", + "notistack": "2.0.5", + "react": "18.2.0", "react-div-100vh": "0.7.0", - "react-dom": "17.0.2", - "react-markdown": "7.1.0", - "react-query": "3.33.5", - "react-router-dom": "5.3.0", - "react-scripts": "4.0.3", - "rehype-raw": "6.1.0", + "react-dom": "18.2.0", + "react-markdown": "8.0.3", + "react-query": "3.39.2", + "react-router-dom": "5.3.3", + "react-scripts": "5.0.1", + "reconnecting-eventsource": "1.5.2", + "rehype-raw": "6.1.1", "remark-gfm": "3.0.1", - "semaphore": "^1.1.0", - "uuid": "8.3.2" + "semaphore": "1.1.0", + "use-long-press": "2.0.2", + "uuid": "9.0.0", + "zustand": "4.1.2" }, "devDependencies": { - "@types/color": "3.0.2", - "@types/react": "17.0.37", - "@types/react-dom": "17.0.11", - "@types/react-router-dom": "5.1.8", - "@types/uuid": "8.3.3", - "cra-build-watch": "3.4.0", + "@types/react": "18.0.21", + "@types/react-dom": "18.0.6", + "@types/react-router-dom": "5.3.3", + "@types/uuid": "8.3.4", + "cra-build-watch": "git+https://npm@github.com/Hypfer/cra-build-watch.git#5.0.0", "tsutils": "3.21.0" } }, - "frontend/node_modules/@babel/core": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", - "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", + "node_modules/@agnoc/core": { + "version": "0.16.0-next.7", + "resolved": "https://registry.npmjs.org/@agnoc/core/-/core-0.16.0-next.7.tgz", + "integrity": "sha512-sA9M8laq+UmYYTMww1s1GPja9JSqVivIoQ/eesXxh0rWo0JPnU/qPEUgyOsShczGGPnNqRUMhE4t8BmZuQLV9Q==", "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.1", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.1", - "@babel/parser": "^7.12.3", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" + "debug": "^4.3.1", + "protobufjs": "^6.11.2", + "tiny-typed-emitter": "^2.0.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "frontend/node_modules/@babel/core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "frontend/node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "engines": { - "node": ">=0.10.0" + "node": ">=12.3" } }, - "frontend/node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", - "integrity": "sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ==", + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dependencies": { - "ansi-html": "^0.0.7", - "error-stack-parser": "^2.0.6", - "html-entities": "^1.2.1", - "native-url": "^0.2.6", - "schema-utils": "^2.6.5", - "source-map": "^0.7.3" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">= 10.x" - }, - "peerDependencies": { - "@types/webpack": "4.x", - "react-refresh": ">=0.8.3 <0.10.0", - "sockjs-client": "^1.4.0", - "type-fest": "^0.13.1", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" - }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } + "node": ">=6.0.0" } }, - "frontend/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=10" }, "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "ajv": ">=8" } }, - "frontend/node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, + "node_modules/@apideck/better-ajv-errors/node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" + "node": ">=6" } }, - "frontend/node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "node": ">=10" } }, - "frontend/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" }, "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "openapi-types": ">=7" } }, - "frontend/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" + "@babel/highlight": "^7.18.6" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.9.0" } }, - "frontend/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "node_modules/@babel/compat-data": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.9.0" } }, - "frontend/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "node_modules/@babel/core": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=6.9.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://opencollective.com/babel" } }, - "frontend/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" + "node_modules/@babel/core/node_modules/@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.0.0" } }, - "frontend/node_modules/cra-build-watch": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/cra-build-watch/-/cra-build-watch-3.4.0.tgz", - "integrity": "sha512-8PM8WPHtauwNATGi7I5aI2TNrSDA1HdwCYzusqlMCNAHXleaj/R2+RQfNclCyrevqj1YzXG7aF6aiKhVVzNBsg==", - "dev": true, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "cross-spawn": "7.0.3", - "fs-extra": "^9.0.1", - "html-webpack-plugin": "^4.5.0", - "import-cwd": "3.0.0", - "meow": "8.0.0", - "ora": "4.0.3", - "semver": "^7.1.1" - }, - "bin": { - "cra-build-watch": "bin/cra-build-watch.js" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "react-scripts": ">= 1.0.x" + "node": ">=6.9.0" } }, - "frontend/node_modules/eslint-config-react-app": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz", - "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==", - "dependencies": { - "confusing-browser-globals": "^1.0.10" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.0.0", - "@typescript-eslint/parser": "^4.0.0", - "babel-eslint": "^10.0.0", - "eslint": "^7.5.0", - "eslint-plugin-flowtype": "^5.2.0", - "eslint-plugin-import": "^2.22.0", - "eslint-plugin-jest": "^24.0.0", - "eslint-plugin-jsx-a11y": "^6.3.1", - "eslint-plugin-react": "^7.20.3", - "eslint-plugin-react-hooks": "^4.0.8", - "eslint-plugin-testing-library": "^3.9.0" - }, - "peerDependenciesMeta": { - "eslint-plugin-jest": { - "optional": true - }, - "eslint-plugin-testing-library": { - "optional": true - } + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" } }, - "frontend/node_modules/eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "node_modules/@babel/eslint-parser": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", + "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", "dependencies": { - "@typescript-eslint/experimental-utils": "^4.0.1" + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" }, "engines": { - "node": ">=10" + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": ">= 4", - "eslint": ">=5" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } + "@babel/core": ">=7.11.0", + "eslint": "^7.5.0 || ^8.0.0" } }, - "frontend/node_modules/eslint-visitor-keys": { + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", @@ -495,354 +333,110 @@ "node": ">=10" } }, - "frontend/node_modules/html-webpack-plugin": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz", - "integrity": "sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==", + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dependencies": { - "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.15", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" }, "engines": { - "node": ">=6.9" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "frontend/node_modules/react-scripts": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", - "integrity": "sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A==", - "dependencies": { - "@babel/core": "7.12.3", - "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", - "@svgr/webpack": "5.5.0", - "@typescript-eslint/eslint-plugin": "^4.5.0", - "@typescript-eslint/parser": "^4.5.0", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.0", - "babel-loader": "8.1.0", - "babel-plugin-named-asset-import": "^0.3.7", - "babel-preset-react-app": "^10.0.0", - "bfj": "^7.0.2", - "camelcase": "^6.1.0", - "case-sensitive-paths-webpack-plugin": "2.3.0", - "css-loader": "4.3.0", - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0", - "eslint": "^7.11.0", - "eslint-config-react-app": "^6.0.0", - "eslint-plugin-flowtype": "^5.2.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jest": "^24.1.0", - "eslint-plugin-jsx-a11y": "^6.3.1", - "eslint-plugin-react": "^7.21.5", - "eslint-plugin-react-hooks": "^4.2.0", - "eslint-plugin-testing-library": "^3.9.2", - "eslint-webpack-plugin": "^2.5.2", - "file-loader": "6.1.1", - "fs-extra": "^9.0.1", - "html-webpack-plugin": "4.5.0", - "identity-obj-proxy": "3.0.0", - "jest": "26.6.0", - "jest-circus": "26.6.0", - "jest-resolve": "26.6.0", - "jest-watch-typeahead": "0.6.1", - "mini-css-extract-plugin": "0.11.3", - "optimize-css-assets-webpack-plugin": "5.0.4", - "pnp-webpack-plugin": "1.6.4", - "postcss-flexbugs-fixes": "4.2.1", - "postcss-loader": "3.0.0", - "postcss-normalize": "8.0.1", - "postcss-preset-env": "6.7.0", - "postcss-safe-parser": "5.0.2", - "prompts": "2.4.0", - "react-app-polyfill": "^2.0.0", - "react-dev-utils": "^11.0.3", - "react-refresh": "^0.8.3", - "resolve": "1.18.1", - "resolve-url-loader": "^3.1.2", - "sass-loader": "^10.0.5", - "semver": "7.3.2", - "style-loader": "1.3.0", - "terser-webpack-plugin": "4.2.3", - "ts-pnp": "1.2.0", - "url-loader": "4.1.1", - "webpack": "4.44.2", - "webpack-dev-server": "3.11.1", - "webpack-manifest-plugin": "2.2.0", - "workbox-webpack-plugin": "5.1.4" - }, - "bin": { - "react-scripts": "bin/react-scripts.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.1.3" - }, - "peerDependencies": { - "react": ">= 16", - "typescript": "^3.2.1 || ^4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "frontend/node_modules/react-scripts/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "frontend/node_modules/resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", - "dependencies": { - "is-core-module": "^2.0.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "frontend/node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "frontend/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@agnoc/core": { - "version": "0.16.0-next.7", - "resolved": "https://registry.npmjs.org/@agnoc/core/-/core-0.16.0-next.7.tgz", - "integrity": "sha512-sA9M8laq+UmYYTMww1s1GPja9JSqVivIoQ/eesXxh0rWo0JPnU/qPEUgyOsShczGGPnNqRUMhE4t8BmZuQLV9Q==", - "dependencies": { - "debug": "^4.3.1", - "protobufjs": "^6.11.2", - "tiny-typed-emitter": "^2.0.3" - }, - "engines": { - "node": ">=12.3" - } - }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", - "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.6", - "call-me-maybe": "^1.0.1", - "js-yaml": "^4.1.0" - } - }, - "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@apidevtools/openapi-schemas": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", - "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", - "engines": { - "node": ">=10" + "node": ">=6.9.0" } }, - "node_modules/@apidevtools/swagger-methods": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", - "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" - }, - "node_modules/@apidevtools/swagger-parser": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", - "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "node_modules/@babel/generator/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@apidevtools/json-schema-ref-parser": "^9.0.6", - "@apidevtools/openapi-schemas": "^2.0.4", - "@apidevtools/swagger-methods": "^3.0.2", - "@jsdevtools/ono": "^7.1.3", - "call-me-maybe": "^1.0.1", - "z-schema": "^5.0.1" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, - "peerDependencies": { - "openapi-types": ">=7" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", + "node_modules/@babel/generator/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==", "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=6.0.0" } }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dependencies": { - "@babel/highlight": "^7.16.0" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", + "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", - "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dependencies": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.17.5", + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", "semver": "^6.3.0" }, "engines": { @@ -861,17 +455,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", - "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -881,12 +475,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "regexpu-core": "^4.7.1" + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" }, "engines": { "node": ">=6.9.0" @@ -896,14 +490,12 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dependencies": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2", @@ -922,279 +514,458 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", + "node_modules/@babel/helper-explode-assignable-expression/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dependencies": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "node_modules/@babel/helper-function-name/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", - "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", + "node_modules/@babel/helper-hoist-variables/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", + "node_modules/@babel/helper-member-expression-to-functions/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", - "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==", + "node_modules/@babel/helper-module-imports/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", - "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", - "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", + "node_modules/@babel/helper-module-transforms/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "node_modules/@babel/helper-optimise-call-expression/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", - "dependencies": { - "@babel/types": "^7.16.0" - }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", - "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", "dependencies": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "node_modules/@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/types": "^7.19.4" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@babel/helper-simple-access/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "color-convert": "^1.9.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/types": "^7.18.9" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/@babel/helper-skip-transparent-expression-wrappers/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "color-name": "1.1.3" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/color-name": { + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "dependencies": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } @@ -1202,7 +973,7 @@ "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } @@ -1219,9 +990,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz", + "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1230,11 +1001,11 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1244,13 +1015,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1260,12 +1031,13 @@ } }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", - "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -1276,12 +1048,12 @@ } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", - "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1291,12 +1063,12 @@ } }, "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", - "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -1307,13 +1079,15 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.16.5.tgz", - "integrity": "sha512-XAiZll5oCdp2Dd2RbXA3LVPlFyIRhhcQy+G34p9ePpl6mjFkbqHAYHovyw2j5mqUrlBf0/+MtOIJ3JGYtz8qaw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz", + "integrity": "sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-decorators": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/plugin-syntax-decorators": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1323,11 +1097,11 @@ } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", - "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -1338,11 +1112,11 @@ } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", - "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1353,11 +1127,11 @@ } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", - "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1368,11 +1142,11 @@ } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", - "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1383,11 +1157,11 @@ } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", - "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1398,11 +1172,11 @@ } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", - "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1413,15 +1187,15 @@ } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", - "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.5" + "@babel/plugin-transform-parameters": "^7.18.8" }, "engines": { "node": ">=6.9.0" @@ -1431,11 +1205,11 @@ } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", - "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -1446,12 +1220,12 @@ } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", - "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -1462,12 +1236,12 @@ } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", - "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1477,13 +1251,13 @@ } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", - "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1494,12 +1268,12 @@ } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", - "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=4" @@ -1556,11 +1330,11 @@ } }, "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.16.5.tgz", - "integrity": "sha512-3CbYTXfflvyy8O819uhZcZSMedZG4J8yS/NLTc/8T24M9ke1GssTGvg8VZu3Yn2LU5IyQSv1CmPq0a9JWHXJwg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", + "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1592,11 +1366,25 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.5.tgz", - "integrity": "sha512-Nrx+7EAJx1BieBQseZa2pavVH2Rp7hADK2xn7coYqVbWRu9C2OFizYcsKo6TrrqJkJl+qF/+Qqzrk/+XDu4GnA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", + "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1628,11 +1416,11 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz", - "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1736,11 +1524,11 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", - "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1750,11 +1538,11 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", - "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1764,13 +1552,13 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", - "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", "dependencies": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5" + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1780,11 +1568,11 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", - "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1794,11 +1582,11 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", - "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz", + "integrity": "sha512-934S2VLLlt2hRJwPf4MczaOr4hYF0z+VKPwqTNxyKX7NthTiPfhuKFWQZHXRM0vh/wo/VyXB3s4bZUNA08l+tQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1808,17 +1596,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", - "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" }, "engines": { @@ -1837,11 +1626,11 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", - "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1851,11 +1640,11 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", - "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.19.4.tgz", + "integrity": "sha512-t0j0Hgidqf0aM86dF8U+vXYReUgJnlv4bZLsyoPnwZNrGY+7/38o8YjaELrvHeVfTZao15kjR0PVv0nju2iduA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -1865,12 +1654,12 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", - "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1880,11 +1669,11 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", - "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1894,12 +1683,12 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", - "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1909,12 +1698,12 @@ } }, "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.5.tgz", - "integrity": "sha512-skE02E/MptkZdBS4HwoRhjWXqeKQj0BWKEAPfPC+8R4/f6bjQqQ9Nftv/+HkxWwnVxh/E2NV9TNfzLN5H/oiBw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", + "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-flow": "^7.16.5" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-flow": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1924,11 +1713,11 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", - "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1938,12 +1727,13 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", - "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dependencies": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1953,11 +1743,11 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", - "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -1967,11 +1757,11 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", - "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -1981,12 +1771,12 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", - "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -1997,13 +1787,13 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", - "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -2014,14 +1804,14 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", - "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-identifier": "^7.15.7", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.18.6", "babel-plugin-dynamic-import-node": "^2.3.3" }, "engines": { @@ -2032,12 +1822,12 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", - "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "dependencies": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2047,11 +1837,12 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", - "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" + "@babel/helper-create-regexp-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -2061,11 +1852,11 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", - "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2075,12 +1866,12 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", - "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2090,11 +1881,11 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", - "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2104,11 +1895,11 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", - "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2118,11 +1909,11 @@ } }, "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.16.5.tgz", - "integrity": "sha512-fdc1s5npHMZ9A+w9bYbrZu4499WyYPVaTTsRO8bU0GJcMuK4ejIX4lyjnpvi+YGLK/EhFQxWszqylO0vaMciFw==", + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.12.tgz", + "integrity": "sha512-Q99U9/ttiu+LMnRU8psd23HhvwXmKWDQIpocm0JKaICcZHnw+mdQbHm6xnSy7dOl8I5PELakYtNBubNQlBXbZw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -2132,11 +1923,11 @@ } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz", - "integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2146,15 +1937,15 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz", - "integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-jsx": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -2164,11 +1955,11 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.5.tgz", - "integrity": "sha512-uQSLacMZSGLCxOw20dzo1dmLlKkd+DsayoV54q3MHXhbqgPzoiGerZQgNPl/Ro8/OcXV2ugfnkx+rxdS0sN5Uw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.16.5" + "@babel/plugin-transform-react-jsx": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2177,13 +1968,26 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.5.tgz", - "integrity": "sha512-0nYU30hCxnCVCbRjSy9ahlhWZ2Sn6khbY4FqR91W+2RbSqkWEbVu2gXh45EqNy4Bq7sRU+H4i0/6YKwOSzh16A==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", + "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2193,11 +1997,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", - "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", "dependencies": { - "regenerator-transform": "^0.14.2" + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" }, "engines": { "node": ">=6.9.0" @@ -2207,11 +2012,11 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", - "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2221,15 +2026,15 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz", - "integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz", + "integrity": "sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA==", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", "semver": "^6.3.0" }, "engines": { @@ -2248,11 +2053,11 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", - "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2262,12 +2067,12 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", - "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -2277,11 +2082,11 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", - "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2291,11 +2096,11 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", - "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -2305,11 +2110,11 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", - "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -2319,13 +2124,13 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", + "integrity": "sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.16.0" + "@babel/helper-create-class-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-typescript": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2335,11 +2140,11 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", - "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { "node": ">=6.9.0" @@ -2349,12 +2154,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", - "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2364,36 +2169,37 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", - "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", - "dependencies": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.5", - "@babel/plugin-proposal-class-properties": "^7.16.5", - "@babel/plugin-proposal-class-static-block": "^7.16.5", - "@babel/plugin-proposal-dynamic-import": "^7.16.5", - "@babel/plugin-proposal-export-namespace-from": "^7.16.5", - "@babel/plugin-proposal-json-strings": "^7.16.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-numeric-separator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-proposal-private-methods": "^7.16.5", - "@babel/plugin-proposal-private-property-in-object": "^7.16.5", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", + "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", + "dependencies": { + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.19.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.19.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -2403,44 +2209,44 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-block-scoped-functions": "^7.16.5", - "@babel/plugin-transform-block-scoping": "^7.16.5", - "@babel/plugin-transform-classes": "^7.16.5", - "@babel/plugin-transform-computed-properties": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-dotall-regex": "^7.16.5", - "@babel/plugin-transform-duplicate-keys": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-function-name": "^7.16.5", - "@babel/plugin-transform-literals": "^7.16.5", - "@babel/plugin-transform-member-expression-literals": "^7.16.5", - "@babel/plugin-transform-modules-amd": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/plugin-transform-modules-systemjs": "^7.16.5", - "@babel/plugin-transform-modules-umd": "^7.16.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", - "@babel/plugin-transform-new-target": "^7.16.5", - "@babel/plugin-transform-object-super": "^7.16.5", - "@babel/plugin-transform-parameters": "^7.16.5", - "@babel/plugin-transform-property-literals": "^7.16.5", - "@babel/plugin-transform-regenerator": "^7.16.5", - "@babel/plugin-transform-reserved-words": "^7.16.5", - "@babel/plugin-transform-shorthand-properties": "^7.16.5", - "@babel/plugin-transform-spread": "^7.16.5", - "@babel/plugin-transform-sticky-regex": "^7.16.5", - "@babel/plugin-transform-template-literals": "^7.16.5", - "@babel/plugin-transform-typeof-symbol": "^7.16.5", - "@babel/plugin-transform-unicode-escapes": "^7.16.5", - "@babel/plugin-transform-unicode-regex": "^7.16.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.19.4", + "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.19.4", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.0", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", + "@babel/types": "^7.19.4", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", "semver": "^6.3.0" }, "engines": { @@ -2450,6 +2256,19 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-env/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2474,16 +2293,16 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.5.tgz", - "integrity": "sha512-3kzUOQeaxY/2vhPDS7CX/KGEGu/1bOYGvdRDJ2U5yjEz5o5jmIeTPLoiQBPGjfhPascLuW5OlMiPzwOOuB6txg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", + "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-react-display-name": "^7.16.5", - "@babel/plugin-transform-react-jsx": "^7.16.5", - "@babel/plugin-transform-react-jsx-development": "^7.16.5", - "@babel/plugin-transform-react-pure-annotations": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-react-display-name": "^7.18.6", + "@babel/plugin-transform-react-jsx": "^7.18.6", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-pure-annotations": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2493,13 +2312,13 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", - "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.16.1" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -2509,9 +2328,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", - "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -2520,11 +2339,11 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.16.5.tgz", - "integrity": "sha512-F1pMwvTiUNSAM8mc45kccMQxj31x3y3P+tA/X8hKNWp3/hUsxdGxZ3D3H8JIkxtfA8qGkaBTKvcmvStaYseAFw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.4.tgz", + "integrity": "sha512-HzjQ8+dzdx7dmZy4DQ8KV8aHi/74AjEbBGTFutBmg/pd3dY5/q1sfuOGPTFGEytlQhWoeVXqcK5BwMgIkRkNDQ==", "dependencies": { - "core-js-pure": "^3.19.0", + "core-js-pure": "^3.25.1", "regenerator-runtime": "^0.13.4" }, "engines": { @@ -2532,42 +2351,55 @@ } }, "node_modules/@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "node_modules/@babel/template/node_modules/@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/highlight": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2575,12 +2407,25 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "node_modules/@babel/traverse/node_modules/@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", "dependencies": { - "@babel/highlight": "^7.16.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" @@ -2595,11 +2440,11 @@ } }, "node_modules/@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.10.tgz", + "integrity": "sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2611,182 +2456,426 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "node_modules/@csstools/normalize.css": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", + "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=0.1.95" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", + "node_modules/@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=4.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/@csstools/normalize.css": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", - "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" - }, - "node_modules/@date-io/core": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz", - "integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw==" - }, - "node_modules/@date-io/date-fns": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.11.0.tgz", - "integrity": "sha512-mPQ71plBeFrArvBSHtjWMHXA89IUbZ6kuo2dsjlRC/1uNOybo91spIb+wTu03NxKTl8ut07s0jJ9svF71afpRg==", + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", "dependencies": { - "@date-io/core": "^2.11.0" + "postcss-value-parser": "^4.2.0" }, - "peerDependencies": { - "date-fns": "^2.0.0" + "engines": { + "node": "^12 || ^14 || >=16" }, - "peerDependenciesMeta": { - "date-fns": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/@date-io/dayjs": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.11.0.tgz", - "integrity": "sha512-w67vRK56NZJIKhJM/CrNbfnIcuMvR3ApfxzNZiCZ5w29sxgBDeKuX4M+P7A9r5HXOMGcsOcpgaoTDINNGkdpGQ==", + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", "dependencies": { - "@date-io/core": "^2.11.0" + "postcss-value-parser": "^4.2.0" }, - "peerDependencies": { - "dayjs": "^1.8.17" + "engines": { + "node": "^12 || ^14 || >=16" }, - "peerDependenciesMeta": { - "dayjs": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/@date-io/luxon": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.11.1.tgz", - "integrity": "sha512-JUXo01kdPQxLORxqdENrgdUhooKgDUggsNRSdi2BcUhASIY2KGwwWXu8ikVHHGkw+DUF4FOEKGfkQd0RHSvX6g==", + "node_modules/@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", "dependencies": { - "@date-io/core": "^2.11.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" }, - "peerDependencies": { - "luxon": "^1.21.3 || ^2.x" + "engines": { + "node": "^12 || ^14 || >=16" }, - "peerDependenciesMeta": { - "luxon": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/@date-io/moment": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.11.0.tgz", - "integrity": "sha512-QSL+83qezQ9Ty0dtFgAkk6eC0GMl/lgYfDajeVUDB3zVA2A038hzczRLBg29ifnBGhQMPABxuOafgWwhDjlarg==", + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", "dependencies": { - "@date-io/core": "^2.11.0" + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" }, - "peerDependencies": { - "moment": "^2.24.0" + "engines": { + "node": "^12 || ^14 || >=16" }, - "peerDependenciesMeta": { - "moment": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/@destinationstransfers/ntp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@destinationstransfers/ntp/-/ntp-2.0.0.tgz", - "integrity": "sha512-0gYbtXpyNlk0p+jWy+lftUkB+uJIBjNUWTB2tv7/fxl8zO3pQsaVFDLFDozbQ1wnYw/PrHDeRdYwAg2frY48Tg==", + "node_modules/@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=11.13.0" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.7.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz", - "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/runtime": "^7.13.10", - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.5", - "@emotion/serialize": "^1.0.2", - "babel-plugin-macros": "^2.6.1", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.0.13" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "postcss": "^8.2" } }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.7.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", - "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", - "dependencies": { - "@emotion/memoize": "^0.7.4", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", - "stylis": "4.0.13" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", + "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2", + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@date-io/core": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.16.0.tgz", + "integrity": "sha512-DYmSzkr+jToahwWrsiRA2/pzMEtz9Bq1euJwoOuYwuwIYXnZFtHajY2E6a1VNVDc9jP8YUXK1BvnZH9mmT19Zg==" + }, + "node_modules/@date-io/date-fns": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.16.0.tgz", + "integrity": "sha512-bfm5FJjucqlrnQcXDVU5RD+nlGmL3iWgkHTq3uAZWVIuBu6dDmGa3m8a6zo2VQQpu8ambq9H22UyUpn7590joA==", + "dependencies": { + "@date-io/core": "^2.16.0" + }, + "peerDependencies": { + "date-fns": "^2.0.0" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + } + } + }, + "node_modules/@date-io/dayjs": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.16.0.tgz", + "integrity": "sha512-y5qKyX2j/HG3zMvIxTobYZRGnd1FUW2olZLS0vTj7bEkBQkjd2RO7/FEwDY03Z1geVGlXKnzIATEVBVaGzV4Iw==", + "dependencies": { + "@date-io/core": "^2.16.0" + }, + "peerDependencies": { + "dayjs": "^1.8.17" + }, + "peerDependenciesMeta": { + "dayjs": { + "optional": true + } + } + }, + "node_modules/@date-io/luxon": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.16.0.tgz", + "integrity": "sha512-L8UXHa/9VbfRqP4KB7JUZwFgOVxo22rONVod1o7GMN2Oku4PzJ0k1kXc+nLP9lRlF1UAA28oQsQqn85Y/PdBZw==", + "dependencies": { + "@date-io/core": "^2.16.0" + }, + "peerDependencies": { + "luxon": "^1.21.3 || ^2.x" + }, + "peerDependenciesMeta": { + "luxon": { + "optional": true + } + } + }, + "node_modules/@date-io/moment": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.16.0.tgz", + "integrity": "sha512-wvu/40k128kF6P0jPbiyZcPR14VjJAgYEs+mYtsXz/AyWpC2DEJKly7ub+dpevUywbTzzpZysyCxCdzLzxD/uw==", + "dependencies": { + "@date-io/core": "^2.16.0" + }, + "peerDependencies": { + "moment": "^2.24.0" + }, + "peerDependenciesMeta": { + "moment": { + "optional": true + } + } + }, + "node_modules/@destinationstransfers/ntp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@destinationstransfers/ntp/-/ntp-2.0.0.tgz", + "integrity": "sha512-0gYbtXpyNlk0p+jWy+lftUkB+uJIBjNUWTB2tv7/fxl8zO3pQsaVFDLFDozbQ1wnYw/PrHDeRdYwAg2frY48Tg==", + "engines": { + "node": ">=11.13.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", + "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", + "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "dependencies": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.0.13" } }, "node_modules/@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz", - "integrity": "sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", "dependencies": { - "@emotion/memoize": "^0.7.4" + "@emotion/memoize": "^0.8.0" } }, "node_modules/@emotion/memoize": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, "node_modules/@emotion/react": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.6.0.tgz", - "integrity": "sha512-23MnRZFBN9+D1lHXC5pD6z4X9yhPxxtHr6f+iTGz6Fv6Rda0GdefPrsHL7otsEf+//7uqCdT5QtHeRxHCERzuw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@emotion/cache": "^11.6.0", - "@emotion/serialize": "^1.0.2", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", + "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/cache": "^11.10.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { @@ -2803,32 +2892,33 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", "dependencies": { - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.4", - "@emotion/unitless": "^0.7.5", - "@emotion/utils": "^1.0.0", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", - "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", + "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" }, "node_modules/@emotion/styled": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.6.0.tgz", - "integrity": "sha512-mxVtVyIOTmCAkFbwIp+nCjTXJNgcz4VWkOYQro87jE2QBTydnkiYusMrRGFtzuruiGK4dDaNORk4gH049iiQuw==", + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.4.tgz", + "integrity": "sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@emotion/babel-plugin": "^11.3.0", - "@emotion/is-prop-valid": "^1.1.1", - "@emotion/serialize": "^1.0.2", - "@emotion/utils": "^1.0.0" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" }, "peerDependencies": { "@babel/core": "^7.0.0", @@ -2845,125 +2935,80 @@ } }, "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, - "node_modules/@emotion/utils": { + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" }, "node_modules/@emotion/weak-memoize": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.12.0.tgz", - "integrity": "sha512-Gw4/j9v36IKY8ET+W0GoOzrRw17xjf21EIFFRL3zx21fF5MnqmeNpNi+PU/LKjqLpPb2Pw2XdlJbYM31VVo/PQ==", + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", + "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", "dev": true, "dependencies": { - "comment-parser": "1.2.4", + "comment-parser": "1.3.1", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "2.0.0" + "jsdoc-type-pratt-parser": "~3.1.0" }, "engines": { - "node": "^12 || ^14 || ^16 || ^17" - } - }, - "node_modules/@es-joy/jsdoccomment/node_modules/jsdoc-type-pratt-parser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.0.tgz", - "integrity": "sha512-sUuj2j48wxrEpbFjDp1sAesAxPiLT+z0SWVmMafyIINs6Lj5gIPKh3VrkBZu4E/Dv+wHpOot0m6H8zlHQjwqeQ==", - "dev": true, - "engines": { - "node": ">=12.0.0" + "node": "^14 || ^16 || ^17 || ^18" } }, "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "dependencies": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } + "node_modules/@fontsource/jetbrains-mono": { + "version": "4.5.11", + "resolved": "https://registry.npmjs.org/@fontsource/jetbrains-mono/-/jetbrains-mono-4.5.11.tgz", + "integrity": "sha512-IW1qgWGkjlN1O6Jf+6LWF9DpcdXhyQEXhTlzfVKrWHX+ProuOT5FcrEAj34AR+19CgAb9Sheda2slORnybBsdw==" }, "node_modules/@fontsource/roboto": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.1.tgz", - "integrity": "sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg==" - }, - "node_modules/@gar/promisify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", - "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==" - }, - "node_modules/@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", - "deprecated": "Moved to 'npm install @sideway/address'" - }, - "node_modules/@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", - "deprecated": "This version has been deprecated and is no longer supported or maintained" - }, - "node_modules/@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", - "deprecated": "This version has been deprecated and is no longer supported or maintained" - }, - "node_modules/@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "deprecated": "Switch to 'npm install joi'", - "dependencies": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "node_modules/@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", - "deprecated": "This version has been deprecated and is no longer supported or maintained", - "dependencies": { - "@hapi/hoek": "^8.3.0" - } + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz", + "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", + "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.4" }, @@ -2971,6 +3016,18 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -2991,6 +3048,14 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2999,391 +3064,329 @@ "node": ">=6" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "engines": { - "node": ">=8" + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/core/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "node": ">=8" } }, - "node_modules/@jest/core/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", + "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2" + "jest-mock": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" + "v8-to-istanbul": "^8.1.0" }, "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@jest/reporters/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, - "engines": { - "node": ">= 10.14.2" + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@jest/reporters/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "@sinclair/typebox": "^0.24.1" }, "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/@jest/reporters/node_modules/node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "dependencies": { "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "source-map": "^0.6.0" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^16.0.0", "chalk": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "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==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" }, "engines": { "node": ">=6.0.0" @@ -3414,6 +3417,19 @@ "@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==", + "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.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", @@ -3434,30 +3450,35 @@ "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", - "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.56", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.56.tgz", - "integrity": "sha512-BlPuRx778JoNIF34m8wOPDZSburwFbH+Y1y97KoAEqC2Qra2UGV3+vII3R9+qkikIKEWJvv1327J7sCfxfpGFQ==", - "dependencies": { - "@babel/runtime": "^7.16.3", - "@emotion/is-prop-valid": "^1.1.1", - "@mui/utils": "^5.2.0", - "@popperjs/core": "^2.4.4", + "version": "5.0.0-alpha.81", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.81.tgz", + "integrity": "sha512-KJP+RdKBLSbhiAliy1b5xFuoAezawupfIHc/MRtEZdqAmUW0+UFNDXIUDlBKR9zLCjgjQ7eVJsSe0TwAgd8OMQ==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@emotion/is-prop-valid": "^1.1.2", + "@mui/types": "^7.1.3", + "@mui/utils": "^5.8.0", + "@popperjs/core": "^2.11.5", "clsx": "^1.1.1", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "react-is": "^17.0.2" }, "engines": { "node": ">=12.0.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, "peerDependencies": { - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3470,51 +3491,33 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, - "node_modules/@mui/core": { - "version": "5.0.0-alpha.48", - "resolved": "https://registry.npmjs.org/@mui/core/-/core-5.0.0-alpha.48.tgz", - "integrity": "sha512-H/QQwKsr2EqPAnP35DGDpWihk5BOFYGhO52rIHb3XKOfoUjDCrCHBy2kvr3dLWJDmJXr/QzYj3AX10n5XzlaMg==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "@emotion/is-prop-valid": "^1.1.0", - "@mui/utils": "^5.0.1", - "clsx": "^1.1.1", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^17.0.2", - "react-dom": "^17.0.2" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "node_modules/@mui/core-downloads-tracker": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.9.tgz", + "integrity": "sha512-rqoFu4qww6KJBbXYhyRd9YXjwBHa3ylnBPSWbGf1bdfG0AYMKmVzg8zxkWvxAWOp97kvx3M2kNPb0xMIDZiogQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" } }, - "node_modules/@mui/core/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, "node_modules/@mui/icons-material": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.2.0.tgz", - "integrity": "sha512-NvyrVaGKpP4R1yFw8BCnE0QcsQ67RtpgxPr4FtH8q60MDYPuPVczLOn5Ash5CFavoDWur/NfM/4DpT54yf3InA==", + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.9.tgz", + "integrity": "sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg==", "dependencies": { - "@babel/runtime": "^7.16.3" + "@babel/runtime": "^7.19.0" }, "engines": { "node": ">=12.0.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, "peerDependencies": { "@mui/material": "^5.0.0", - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^17.0.2" + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3523,36 +3526,37 @@ } }, "node_modules/@mui/lab": { - "version": "5.0.0-alpha.48", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.48.tgz", - "integrity": "sha512-ukYcx1ReSy4taQBMIPTkOaSz+CwgxYih3XwTCGTv84atRWMFhfqJO3Ofe8rQ5/innMDbBlSPkjaiMSag8d3QeQ==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "@date-io/date-fns": "^2.10.6", - "@date-io/dayjs": "^2.10.6", - "@date-io/luxon": "^2.10.6", - "@date-io/moment": "^2.10.6", - "@mui/core": "5.0.0-alpha.48", - "@mui/system": "^5.0.1", - "@mui/utils": "^5.0.1", + "version": "5.0.0-alpha.82", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.82.tgz", + "integrity": "sha512-SUkHbMUVTmn+tqOjkRBNdX/wKS97rfvoOBMY6+QThJhTyIOym9ELcpKbEN7uf/UEPEnRNuqekLid5wHudS2cLw==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@mui/base": "5.0.0-alpha.81", + "@mui/system": "^5.8.0", + "@mui/utils": "^5.8.0", + "@mui/x-date-pickers": "5.0.0-alpha.0", "clsx": "^1.1.1", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "react-is": "^17.0.2", "react-transition-group": "^4.4.2", - "rifm": "^0.12.0" + "rifm": "^0.12.1" }, "engines": { "node": ">=12.0.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, "peerDependencies": { - "@mui/material": "^5.0.0-rc.0", - "@types/react": "^16.8.6 || ^17.0.0", - "date-fns": "^2.24.0", + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "date-fns": "^2.25.0", "dayjs": "^1.10.7", - "luxon": "^1.28.0", + "luxon": "^1.28.0 || ^2.0.0", "moment": "^2.29.1", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3578,36 +3582,36 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "node_modules/@mui/material": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.2.0.tgz", - "integrity": "sha512-AJehUbf0pWA+X9x+rXM4xHjLdNSf3YZzVt9YP/Pa75HCIDn4Dg2neiZu/Cg57C19WMlUf3nyn4Vkz4nD48DgPA==", - "dependencies": { - "@babel/runtime": "^7.16.3", - "@mui/base": "5.0.0-alpha.56", - "@mui/system": "^5.2.0", - "@mui/types": "^7.1.0", - "@mui/utils": "^5.2.0", - "@types/react-transition-group": "^4.4.4", - "clsx": "^1.1.1", - "csstype": "^3.0.10", - "hoist-non-react-statics": "^3.3.2", - "prop-types": "^15.7.2", - "react-is": "^17.0.2", - "react-transition-group": "^4.4.2" + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.9.tgz", + "integrity": "sha512-sdOzlgpCmyw48je+E7o9UGGJpgBaF+60FlTRpVpcd/z+LUhnuzzuis891yPI5dPPXLBDL/bO4SsGg51lgNeLBw==", + "dependencies": { + "@babel/runtime": "^7.19.0", + "@mui/base": "5.0.0-alpha.101", + "@mui/core-downloads-tracker": "^5.10.9", + "@mui/system": "^5.10.9", + "@mui/types": "^7.2.0", + "@mui/utils": "^5.10.9", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/material-ui" + "url": "https://opencollective.com/mui" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -3621,19 +3625,51 @@ } } }, + "node_modules/@mui/material/node_modules/@mui/base": { + "version": "5.0.0-alpha.101", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.101.tgz", + "integrity": "sha512-a54BcXvArGOKUZ2zyS/7B9GNhAGgfomEQSkfEZ88Nc9jKvXA+Mppenfz5o4JCAnD8c4VlePmz9rKOYvvum1bZw==", + "dependencies": { + "@babel/runtime": "^7.19.0", + "@emotion/is-prop-valid": "^1.2.0", + "@mui/types": "^7.2.0", + "@mui/utils": "^5.10.9", + "@popperjs/core": "^2.11.6", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/@mui/private-theming": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.2.3.tgz", - "integrity": "sha512-Lc1Cmu8lSsYZiXADi9PBb17Ho82ZbseHQujUFAcp6bCJ5x/d+87JYCIpCBMagPu/isRlFCwbziuXPmz7WOzJPQ==", + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.9.tgz", + "integrity": "sha512-BN7/CnsVPVyBaQpDTij4uV2xGYHHHhOgpdxeYLlIu+TqnsVM7wUeF+37kXvHovxM6xmL5qoaVUD98gDC0IZnHg==", "dependencies": { - "@babel/runtime": "^7.16.3", - "@mui/utils": "^5.2.3", - "prop-types": "^15.7.2" + "@babel/runtime": "^7.19.0", + "@mui/utils": "^5.10.9", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" @@ -3643,8 +3679,8 @@ "url": "https://opencollective.com/mui" }, "peerDependencies": { - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^17.0.2" + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3653,13 +3689,14 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.2.6.tgz", - "integrity": "sha512-bqAhli8eGS6v2qxivy2/4K0Ag8o//jsu1G2G6QcieFiT6y7oIF/nd/6Tvw6OSm3roOTifVQWNKwkt1yFWhGS+w==", + "version": "5.10.8", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.8.tgz", + "integrity": "sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw==", "dependencies": { - "@babel/runtime": "^7.16.3", - "@emotion/cache": "^11.7.1", - "prop-types": "^15.7.2" + "@babel/runtime": "^7.19.0", + "@emotion/cache": "^11.10.3", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" @@ -3671,7 +3708,7 @@ "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", - "react": "^17.0.2" + "react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -3683,18 +3720,18 @@ } }, "node_modules/@mui/system": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.2.6.tgz", - "integrity": "sha512-PZ7bmpWOLikWgqn2zWv9/Xa7lxnRBOmfjoMH7c/IVYJs78W3971brXJ3xV9MEWWQcoqiYQeXzUJaNf4rFbKCBA==", + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.9.tgz", + "integrity": "sha512-B6fFC0sK06hNmqY7fAUfwShQv594+u/DT1YEFHPtK4laouTu7V4vSGQWi1WJT9Bjs9Db5D1bRDJ+Yy+tc3QOYA==", "dependencies": { - "@babel/runtime": "^7.16.3", - "@mui/private-theming": "^5.2.3", - "@mui/styled-engine": "^5.2.6", - "@mui/types": "^7.1.0", - "@mui/utils": "^5.2.3", - "clsx": "^1.1.1", - "csstype": "^3.0.10", - "prop-types": "^15.7.2" + "@babel/runtime": "^7.19.0", + "@mui/private-theming": "^5.10.9", + "@mui/styled-engine": "^5.10.8", + "@mui/types": "^7.2.0", + "@mui/utils": "^5.10.9", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" @@ -3706,8 +3743,8 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@types/react": "^16.8.6 || ^17.0.0", - "react": "^17.0.2" + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -3722,9 +3759,9 @@ } }, "node_modules/@mui/types": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.0.tgz", - "integrity": "sha512-Hh7ALdq/GjfIwLvqH3XftuY3bcKhupktTm+S6qRIDGOtPtRuq2L21VWzOK4p7kblirK0XgGVH5BLwa6u8z/6QQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz", + "integrity": "sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==", "peerDependencies": { "@types/react": "*" }, @@ -3735,15 +3772,46 @@ } }, "node_modules/@mui/utils": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.2.3.tgz", - "integrity": "sha512-sQujlajIS0zQKcGIS6tZR0L1R+ib26B6UtuEn+cZqwKHsPo3feuS+SkdscYBdcCdMbrZs4gj8WIJHl2z6tbSzQ==", + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz", + "integrity": "sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA==", "dependencies": { - "@babel/runtime": "^7.16.3", - "@types/prop-types": "^15.7.4", + "@babel/runtime": "^7.19.0", + "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/x-date-pickers": { + "version": "5.0.0-alpha.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.0-alpha.0.tgz", + "integrity": "sha512-JTzTaNSWbxNi8KDUJjHCH6im0YlIEv88gPoKhGm7s6xCGT1q6FtMp/oQ40nhfwrJ73nkM5G1JXRIzI/yfsHXQQ==", + "dependencies": { + "@date-io/date-fns": "^2.11.0", + "@date-io/dayjs": "^2.11.0", + "@date-io/luxon": "^2.11.1", + "@date-io/moment": "^2.11.0", + "@mui/utils": "^5.2.3", + "clsx": "^1.1.1", "prop-types": "^15.7.2", - "react-is": "^17.0.2" + "react-transition-group": "^4.4.2", + "rifm": "^0.12.1" }, "engines": { "node": ">=12.0.0" @@ -3753,13 +3821,36 @@ "url": "https://opencollective.com/mui" }, "peerDependencies": { + "@mui/material": "^5.2.3", + "@mui/system": "^5.2.3", + "date-fns": "^2.25.0", + "dayjs": "^1.10.7", + "luxon": "^1.28.0 || ^2.0.0", + "moment": "^2.29.1", "react": "^17.0.2" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + } } }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dependencies": { + "eslint-scope": "5.1.1" + } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", @@ -3793,45 +3884,67 @@ "node": ">= 8" } }, - "node_modules/@npmcli/fs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz", - "integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==", + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.8.tgz", + "integrity": "sha512-wxXRwf+IQ6zvHSJZ+5T2RQNEsq+kx4jKRXfFvdt3nBIUzJUAvXEFsUeoaohDe/Kr84MTjGwcuIUPNcstNJORsA==", "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" + "node": ">= 10.13" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <4.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } } }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "engines": { - "node": ">=10" + "node": ">= 8" } }, "node_modules/@popperjs/core": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz", - "integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==", + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -3840,7 +3953,7 @@ "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", @@ -3855,12 +3968,12 @@ "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -3869,41 +3982,64 @@ "node_modules/@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", - "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", "dependencies": { - "@rollup/pluginutils": "^3.0.8", - "@types/resolve": "0.0.8", + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", "is-module": "^1.0.0", - "resolve": "^1.14.2" + "resolve": "^1.19.0" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 10.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0" @@ -3942,6 +4078,16 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", + "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.46", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.46.tgz", + "integrity": "sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==" + }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -3951,20 +4097,22 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", "dependencies": { "@sinonjs/commons": "^1.7.0" } }, "node_modules/@surma/rollup-plugin-off-main-thread": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz", - "integrity": "sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", "dependencies": { - "ejs": "^2.6.1", - "magic-string": "^0.25.0" + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" } }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { @@ -4174,19 +4322,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@svgr/webpack/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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -4195,10 +4330,18 @@ "node": ">= 6" } }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", @@ -4225,9 +4368,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dependencies": { "@babel/types": "^7.3.0" } @@ -4236,36 +4379,19 @@ "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" } }, - "node_modules/@types/color": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.2.tgz", - "integrity": "sha512-INiJl6sfNn8iyC5paxVzqiVUEj2boIlFki02uRTAkKwAj++7aAF+ZfEv/XrIeBa0XI/fTZuDHW8rEEcEVnON+Q==", - "dev": true, - "dependencies": { - "@types/color-convert": "*" - } - }, - "node_modules/@types/color-convert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz", - "integrity": "sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==", - "dev": true, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", "dependencies": { - "@types/color-name": "*" + "@types/node": "*" } }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, "node_modules/@types/compression": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.2.tgz", @@ -4279,11 +4405,19 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -4293,24 +4427,32 @@ } }, "node_modules/@types/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", + "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -4328,25 +4470,15 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.27", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", - "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", - "dev": true, + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*" } }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -4364,15 +4496,23 @@ } }, "node_modules/@types/history": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", - "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==", + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", "dev": true }, "node_modules/@types/html-minifier-terser": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz", - "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", @@ -4396,25 +4536,25 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, "node_modules/@types/jstoxml": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/jstoxml/-/jstoxml-2.0.1.tgz", - "integrity": "sha512-BLhCvUm5deaeDJb162gQoWAaPNa0fFdxbUwcWa5Noc6kFMmqfAEPbySaypbltl0H6FiCkyhfvs91UK2uFFCfEQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/jstoxml/-/jstoxml-2.0.2.tgz", + "integrity": "sha512-60VaXPlZbd7tEhloAkE2E0lg+QoWpnGusdy+2pGMGFFpdsyxm/1GKs0o/nLJJKWXci92cnq2utmqaV5L7Zjqxw==", "dev": true }, "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "node_modules/@types/mdast": { "version": "3.0.10", @@ -4424,21 +4564,10 @@ "@types/unist": "*" } }, - "node_modules/@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" - }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "node_modules/@types/minimist": { "version": "1.2.2", @@ -4447,9 +4576,9 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-rADY+HtTOA52l9VZWtgQfn4p+UDVM2eDVkMZT1I6syp0YKxW2F9v+0pbRZLsvskhQv/vMb6ZfCay81GHbz5SHg==", "dev": true }, "node_modules/@types/ms": { @@ -4458,9 +4587,9 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "node_modules/@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" + "version": "18.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz", + "integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==" }, "node_modules/@types/node-ssdp": { "version": "4.0.1", @@ -4474,7 +4603,8 @@ "node_modules/@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -4487,14 +4617,14 @@ "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, "node_modules/@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" }, "node_modules/@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/q": { "version": "1.5.5", @@ -4504,19 +4634,17 @@ "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "node_modules/@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "17.0.37", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.37.tgz", - "integrity": "sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==", + "version": "18.0.21", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz", + "integrity": "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4524,9 +4652,9 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.11", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz", - "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==", + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.6.tgz", + "integrity": "sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==", "dev": true, "dependencies": { "@types/react": "*" @@ -4541,42 +4669,47 @@ } }, "node_modules/@types/react-router": { - "version": "5.1.17", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz", - "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==", + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.19.tgz", + "integrity": "sha512-Fv/5kb2STAEMT3wHzdKQK2z8xKq38EDIGVrutYLmQVVLe+4orDFquU52hQrULnEHinMKv9FSA6lf9+uNT1ITtA==", "dev": true, "dependencies": { - "@types/history": "*", + "@types/history": "^4.7.11", "@types/react": "*" } }, "node_modules/@types/react-router-dom": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz", - "integrity": "sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", "dev": true, "dependencies": { - "@types/history": "*", + "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router": "*" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", - "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", "dependencies": { "@types/react": "*" } }, "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -4588,46 +4721,40 @@ "integrity": "sha512-jmFpMslMtBGOXY2s7x6O8vBebcj6zhkwl0Pd/viZApo1uZaPk733P8doPvaiBbCG+R7201OLOl4QP7l1mFyuyw==", "dev": true }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "dependencies": { - "@types/mime": "^1", + "@types/mime": "*", "@types/node": "*" } }, - "node_modules/@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" + "node_modules/@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, - "node_modules/@types/tapable": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", - "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" - }, - "node_modules/@types/uglify-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", - "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/@types/uglify-js/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, "node_modules/@types/unist": { "version": "2.0.6", @@ -4635,68 +4762,44 @@ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, "node_modules/@types/uuid": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.3.tgz", - "integrity": "sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, - "node_modules/@types/webpack": { - "version": "4.41.32", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", - "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", - "dependencies": { - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "anymatch": "^3.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/@types/webpack-sources": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", - "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", "dependencies": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - } - }, - "node_modules/@types/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "@types/node": "*" } }, "node_modules/@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", - "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz", + "integrity": "sha512-FIBZgS3DVJgqPwJzvZTuH4HNsZhHMa9SjxTKAZTlMsPw/UzpEjcf9f4dfgDJEHjK+HboUJo123Eshl6niwEm/Q==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.40.0", + "@typescript-eslint/type-utils": "5.40.0", + "@typescript-eslint/utils": "5.40.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", "regexpp": "^3.2.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -4716,33 +4819,33 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.40.0.tgz", + "integrity": "sha512-wDYn3NYqVOmJI4iSkyWxXUu8Xoa4+OCh97YOXZecMCuXFIgCuxOCOlkR4kZyeXWNrulFyXPcXSbs4USb5IwI8g==", "dependencies": { - "tslib": "^1.8.1" + "@typescript-eslint/utils": "5.40.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", - "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", - "dev": true, + "node_modules/@typescript-eslint/parser": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.0.tgz", + "integrity": "sha512-Ah5gqyX2ySkiuYeOIDg7ap51/b63QgWZA7w6AHtFrag7aH0lRQPbLzUjk0c9o5/KZ6JRkTTDKShL4AUrQa6/hw==", "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@typescript-eslint/scope-manager": "5.40.0", + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/typescript-estree": "5.40.0", + "debug": "^4.3.4" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4752,46 +4855,39 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "*" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.0.tgz", + "integrity": "sha512-d3nPmjUeZtEWRvyReMI4I1MwPGC63E8pDoHy0BnrYjnJgilBD3hv7XOiETKLY/zTwI7kCnBDf2vWTRUVpYw0Uw==", "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/visitor-keys": "5.40.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", - "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", - "dev": true, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.0.tgz", + "integrity": "sha512-nfuSdKEZY2TpnPz5covjJqav+g5qeBqwSHKBvz7Vm1SAfy93SwKk/JeSTymruDGItTwNijSsno5LhOHRS1pcfw==", "dependencies": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "debug": "^4.3.2" + "@typescript-eslint/typescript-estree": "5.40.0", + "@typescript-eslint/utils": "5.40.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4801,7 +4897,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "*" }, "peerDependenciesMeta": { "typescript": { @@ -4809,28 +4905,10 @@ } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", - "dev": true, + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.0.tgz", + "integrity": "sha512-V1KdQRTXsYpf1Y1fXCeZ+uhjW48Niiw0VGt4V8yzuaDTU8Z1Xl7yQDyQNqyAFcVhpYXIVCEuxSIWTsLDpHgTbw==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4840,17 +4918,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.0.tgz", + "integrity": "sha512-b0GYlDj8TLTOqwX7EGbw2gL5EXS2CPEWhF9nGJiGmEcmlpNBjyHsTwbqpyIEPVpl6br4UcBOYlcI2FJVtJkYhg==", + "dependencies": { + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/visitor-keys": "5.40.0", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -4866,29 +4943,37 @@ } } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, + "node_modules/@typescript-eslint/utils": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.0.tgz", + "integrity": "sha512-MO0y3T5BQ5+tkkuYZJBjePewsY+cQnfkYeRqS6tPh28niiIwPnQ1t59CSRcs1ZwJJNOdWw7rv9pF8aP58IMihA==", "dependencies": { - "tslib": "^1.8.1" + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.40.0", + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/typescript-estree": "5.40.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", - "dev": true, + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.0.tgz", + "integrity": "sha512-ijJ+6yig+x9XplEpG2K6FUdJeQGGj/15U3S56W9IqXKJqleuD7zJ2AX/miLezwxpd7ZxDAqO87zWufKg+RPZyQ==", "dependencies": { - "@typescript-eslint/types": "5.4.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.40.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4898,160 +4983,140 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" - }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "dependencies": { - "@webassemblyjs/ast": "1.9.0" + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", + "@webassemblyjs/ast": "1.11.1", "@xtuc/long": "4.2.2" } }, @@ -5066,26 +5131,26 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" }, "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" } }, "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "bin": { "acorn": "bin/acorn" }, @@ -5102,6 +5167,25 @@ "acorn-walk": "^7.1.1" } }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -5110,6 +5194,27 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/acorn-walk": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", @@ -5119,17 +5224,17 @@ } }, "node_modules/address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", "engines": { - "node": ">= 0.12.0" + "node": ">= 10.0.0" } }, "node_modules/adjust-sourcemap-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", - "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "dependencies": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" @@ -5138,19 +5243,6 @@ "node": ">=8.9" } }, - "node_modules/adjust-sourcemap-loader/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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -5162,18 +5254,6 @@ "node": ">= 6.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -5189,12 +5269,35 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, "peerDependencies": { - "ajv": ">=5.0.0" + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "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==", + "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-keywords": { @@ -5205,15 +5308,16 @@ "ajv": "^6.9.1" } }, - "node_modules/alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + "node_modules/ajv/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==" }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, "engines": { "node": ">=6" } @@ -5243,10 +5347,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "engines": [ "node >= 0.8.0" ], @@ -5289,15 +5393,16 @@ } }, "node_modules/api-schema-builder": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/api-schema-builder/-/api-schema-builder-2.0.10.tgz", - "integrity": "sha512-7XZuKeJScffImVXxiiRYKBA7/LevTlwiVdPwq8MnLig+ZEcpfPV9f4c8iXU2WB2TmZNH73kdN2Xxg+vNXh3qOg==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/api-schema-builder/-/api-schema-builder-2.0.11.tgz", + "integrity": "sha512-85zbwf8MtPWodhfnmQRW5YD/fuGR12FP+8TbcYai5wbRnoUmPYLftLSbp7NB6zQMPb61Gjz+ApPUSyTdcCos7g==", "dependencies": { "ajv": "^6.12.6", "clone-deep": "^4.0.1", "decimal.js": "^10.3.1", "js-yaml": "^3.14.1", "json-schema-deref-sync": "^0.14.0", + "lodash.get": "^4.4.2", "openapi-schema-validator": "^3.0.3", "swagger-parser": "^10.0.3" }, @@ -5305,10 +5410,31 @@ "node": ">=8" } }, + "node_modules/api-schema-builder/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/api-schema-builder/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true }, "node_modules/are-we-there-yet": { "version": "1.1.7", @@ -5344,13 +5470,15 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { "version": "4.2.2", @@ -5364,48 +5492,19 @@ "node": ">=6.0" } }, - "node_modules/arity-n": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", - "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=" - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" }, "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" }, @@ -5424,30 +5523,15 @@ "node": ">=8" } }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5457,13 +5541,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5472,77 +5557,42 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "node_modules/array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, "engines": { - "node": ">=8" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dependencies": { - "inherits": "2.0.1" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "engines": { - "node": ">=8" - } + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, "node_modules/async": { "version": "2.6.4", @@ -5552,28 +5602,18 @@ "lodash": "^4.17.14" } }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "node_modules/async-mqtt": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async-mqtt/-/async-mqtt-2.6.1.tgz", - "integrity": "sha512-EkXAwRzwMaPC6ji0EvNeM5OMe6VjMhEKVJJUN7gu/hGzkcDpZtaI34nUwdwCMbjQB3pnuSOHqQMFKsUpg+D8kA==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async-mqtt/-/async-mqtt-2.6.3.tgz", + "integrity": "sha512-mFGTtlEpOugOoLOf9H5AJyJaZUNtOVXLGGOnPaPZDPQex6W6iIOgtV+fAgam0GQbgnLfgX+Wn/QzS6d+PYfFAQ==", "dependencies": { - "mqtt": "^4.1.0" + "mqtt": "^4.3.7" } }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -5583,17 +5623,6 @@ "node": ">= 4.0.0" } }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", @@ -5605,46 +5634,72 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/auto-changelog": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/auto-changelog/-/auto-changelog-2.4.0.tgz", + "integrity": "sha512-vh17hko1c0ItsEcw6m7qPRf3m45u+XK5QyCrrBFViElZ8jnKrPC1roSznrd1fIB/0vR/zawdECCRJtTuqIXaJw==", + "dev": true, + "dependencies": { + "commander": "^7.2.0", + "handlebars": "^4.7.7", + "node-fetch": "^2.6.1", + "parse-github-url": "^1.0.2", + "semver": "^7.3.5" + }, + "bin": { + "auto-changelog": "src/index.js" + }, + "engines": { + "node": ">=8.3" + } + }, "node_modules/autoprefixer": { - "version": "9.8.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", - "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "version": "10.4.12", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz", + "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], "dependencies": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001407", + "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "picocolors": "^0.2.1", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" }, "bin": { "autoprefixer": "bin/autoprefixer" }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, - "node_modules/autoprefixer/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, "node_modules/axe-core": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", - "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", + "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==", "engines": { "node": ">=4" } }, "node_modules/axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "dependencies": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "node_modules/axobject-query": { @@ -5652,85 +5707,62 @@ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "eslint": ">= 4.12.1" - } - }, - "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "dependencies": { - "babylon": "^6.18.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.8.0" } }, "node_modules/babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", + "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", "dependencies": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, "engines": { - "node": ">= 6.9" + "node": ">= 8.9" }, "peerDependencies": { "@babel/core": "^7.0.0", "webpack": ">=2" } }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -5755,9 +5787,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -5765,40 +5797,21 @@ "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", - "dependencies": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - } - }, - "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-macros/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" + "node": ">=10", + "npm": ">=6" } }, "node_modules/babel-plugin-named-asset-import": { @@ -5810,12 +5823,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "peerDependencies": { @@ -5831,42 +5844,28 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.0" + "@babel/helper-define-polyfill-provider": "^0.3.3" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" - }, - "node_modules/babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "dependencies": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, "node_modules/babel-plugin-transform-react-remove-prop-types": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", @@ -5895,15 +5894,15 @@ } }, "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -5932,49 +5931,6 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, - "node_modules/babel-preset-react-app/node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/babel-runtime/node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", - "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", - "hasInstallScript": true - }, - "node_modules/babel-runtime/node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "bin": { - "babylon": "bin/babylon.js" - } - }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -5989,34 +5945,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -6050,7 +5978,7 @@ "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, "node_modules/bfj": { "version": "7.0.2", @@ -6086,20 +6014,10 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, "engines": { "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -6115,27 +6033,33 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "engines": { "node": ">= 0.8" } @@ -6151,58 +6075,23 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dependencies": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/bonjour-service": { - "version": "1.1.0", - "resolved": "git+https://npm@github.com/Hypfer/bonjour-service.git#113d63c3a07f739001198545d2a9c1043e9a5b0b", - "integrity": "sha512-KWHDLT0jX/3ipbHRYbXOCtKYuxFqQAStx0dDsvsHj5Q82lnoJbAVzCc3OIIuO6OHDi38WhwpNArTWpFS8e8w6g==", - "license": "MIT", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", + "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", "dependencies": { "array-flatten": "^2.1.2", "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.3" - } - }, - "node_modules/bonjour/node_modules/dns-packet": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", - "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", - "dependencies": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/bonjour/node_modules/multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dependencies": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" + "multicast-dns": "^7.2.5" } }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -6239,11 +6128,6 @@ "unload": "2.2.0" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, "node_modules/browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -6255,120 +6139,39 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dependencies": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dependencies": { - "node-int64": "^0.4.0" + "node-int64": "^0.4.0" } }, "node_modules/buffer": { @@ -6399,20 +6202,10 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, "node_modules/builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "engines": { "node": ">=6" }, @@ -6420,85 +6213,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "engines": { "node": ">= 0.8" } }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cacache/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -6514,37 +6236,7 @@ "node_modules/call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } + "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==" }, "node_modules/callsites": { "version": "3.1.0", @@ -6564,14 +6256,14 @@ } }, "node_modules/camel-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "engines": { "node": ">=10" }, @@ -6579,6 +6271,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", @@ -6617,29 +6317,24 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001294", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", - "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } - }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "version": "1.0.30001419", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001419.tgz", + "integrity": "sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", "engines": { "node": ">=4" } @@ -6677,9 +6372,9 @@ } }, "node_modules/character-entities": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.1.tgz", - "integrity": "sha512-OzmutCf2Kmc+6DrFrrPS8/tDh2+DpnrfzdICHWhcVC9eOd0N1PXmQEE1a8iM4IziIAG+8tmTq3K+oo0ubH6RRQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6688,7 +6383,7 @@ "node_modules/charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "engines": { "node": "*" } @@ -6699,45 +6394,47 @@ "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==" }, "node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.1.1" + "fsevents": "~2.3.2" } }, - "node_modules/chokidar/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 6" } }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true }, "node_modules/chrome-trace-event": { "version": "1.0.3", @@ -6748,208 +6445,114 @@ } }, "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==" - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" }, "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "node_modules/clean-css": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", + "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "source-map": "~0.6.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.0" } }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "restore-cursor": "^3.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dependencies": { - "is-buffer": "^1.1.5" - }, + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { - "kind-of": "^3.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "engines": { - "node": ">=0.10.0" + "node": ">=0.8" } }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", - "engines": { - "node": ">=6" + "node": ">=6" } }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" @@ -7003,12 +6606,12 @@ "node_modules/coa/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/coa/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } @@ -7016,7 +6619,7 @@ "node_modules/coa/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } @@ -7035,7 +6638,7 @@ "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -7046,27 +6649,6 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-4.0.1.tgz", - "integrity": "sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.6.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7083,14 +6665,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -7113,14 +6696,17 @@ } }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } }, "node_modules/comment-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", - "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", "dev": true, "engines": { "node": ">= 12.0.0" @@ -7135,13 +6721,10 @@ "minimist": "^1.1.0" } }, - "node_modules/commist/node_modules/leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", - "engines": { - "node": ">=0.10.0" - } + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" }, "node_modules/common-tags": { "version": "1.8.2", @@ -7154,20 +6737,7 @@ "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "node_modules/compose-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", - "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", - "dependencies": { - "arity-n": "^1.0.4" - } + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "node_modules/compressible": { "version": "2.0.18", @@ -7197,14 +6767,6 @@ "node": ">= 0.8.0" } }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -7216,12 +6778,12 @@ "node_modules/compression/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==" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concat-stream": { "version": "2.0.0", @@ -7243,29 +6805,19 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, "node_modules/connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "engines": { "node": ">=0.8" } }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -7305,17 +6857,14 @@ } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "engines": { "node": ">= 0.6" } @@ -7323,44 +6872,12 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "engines": { - "node": ">=0.10.0" - } + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.1.tgz", - "integrity": "sha512-btdpStYFQScnNVQ5slVcr858KP0YWYjV16eGJQw8Gg7CWtu/2qNvIM3qVRIR3n1pK2R9NNOrTevbvAYxajwEjg==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz", + "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -7368,30 +6885,21 @@ } }, "node_modules/core-js-compat": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.1.tgz", - "integrity": "sha512-AVhKZNpqMV3Jz8hU0YEXXE06qoxtQGsAqU0u1neUngz5IusDJRX/ZJ6t3i7mS7QxNyEONbCo14GprkBrxPlTZA==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz", + "integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==", "dependencies": { - "browserslist": "^4.19.1", - "semver": "7.0.0" + "browserslist": "^4.21.4" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" } }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/core-js-pure": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.1.tgz", - "integrity": "sha512-yeNNr3L9cEBwNy6vhhIJ0nko7fE7uFO6PgawcacGt2VWep4WqQx0RiqlkgSP7kqUMC1IKdfO9qPeWXcUheHLVQ==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz", + "integrity": "sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -7426,51 +6934,60 @@ "node": ">= 6" } }, - "node_modules/crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "node_modules/cra-build-watch": { + "version": "5.0.0", + "resolved": "git+https://npm@github.com/Hypfer/cra-build-watch.git#1281e987bb3ad0bc3c0d3d40078a6b5ab6fb67d4", + "dev": true, + "license": "MIT", "dependencies": { - "buffer": "^5.1.0" + "cross-spawn": "7.0.3", + "fs-extra": "9.0.1", + "html-webpack-plugin": "5.5.0", + "import-cwd": "3.0.0", + "meow": "8.0.0", + "ora": "4.0.3", + "semver": "^7.1.1" + }, + "bin": { + "cra-build-watch": "bin/cra-build-watch.js" + }, + "engines": { + "node": ">=16" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "node_modules/cra-build-watch/node_modules/fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "node_modules/cra-build-watch/node_modules/universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true, + "engines": { + "node": ">= 10.0.0" } }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "node_modules/crc": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-4.1.1.tgz", + "integrity": "sha512-2U3ZqJ2phJl9ANuP2q5VS53LMpNmYU9vcpmh6nutJmsqUREhtWpTRh9yYxG7sDg3xkwaEEXytSeffTxw4cgwPg==", + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "buffer": ">=6.0.3" } }, "node_modules/cross-env": { @@ -7507,188 +7024,192 @@ "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "engines": { - "node": "*" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "engines": { "node": "*" } }, "node_modules/crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "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==", "engines": { - "node": ">=4" - } - }, - "node_modules/css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dependencies": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" + "node": ">=8" } }, "node_modules/css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "dependencies": { - "postcss": "^7.0.5" + "postcss-selector-parser": "^6.0.9" }, "bin": { - "css-blank-pseudo": "cli.js" + "css-blank-pseudo": "dist/cli.cjs" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "engines": { - "node": "*" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dependencies": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - }, + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", "engines": { - "node": ">4" + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" } }, "node_modules/css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" - }, - "bin": { - "css-has-pseudo": "cli.js" + "postcss-selector-parser": "^6.0.9" }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-has-pseudo/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", "bin": { - "cssesc": "bin/cssesc" + "css-has-pseudo": "dist/cli.cjs" }, "engines": { - "node": ">=4" - } - }, - "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/css-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", - "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", - "dependencies": { - "camelcase": "^6.0.0", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^2.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.3", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.1", - "semver": "^7.3.2" + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.27.0 || ^5.0.0" + "webpack": "^5.0.0" } }, - "node_modules/css-loader/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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">=8.9.0" - } + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } }, - "node_modules/css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", + "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==", + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "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", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dependencies": { - "postcss": "^7.0.5" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", "bin": { - "css-prefers-color-scheme": "cli.js" + "css-prefers-color-scheme": "dist/cli.cjs" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/css-select": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", - "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "dependencies": { "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" }, @@ -7713,18 +7234,10 @@ "node": ">=8.0.0" } }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "engines": { "node": ">= 6" }, @@ -7732,18 +7245,14 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.0.1.tgz", + "integrity": "sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } }, "node_modules/cssesc": { "version": "3.0.0", @@ -7757,138 +7266,84 @@ } }, "node_modules/cssnano": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", - "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "version": "5.1.13", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.13.tgz", + "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==", "dependencies": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.8", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" + "cssnano-preset-default": "^5.2.12", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "dependencies": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" + "node": "^10 || ^12 || >=14.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dependencies": { - "postcss": "^7.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/cssnano/node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "node_modules/cssnano-preset-default": { + "version": "5.2.12", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz", + "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==", + "dependencies": { + "css-declaration-sorter": "^6.3.0", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.2", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.6", + "postcss-merge-rules": "^5.1.2", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.3", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/cssnano/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "node": "^10 || ^12 || >=14.0" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/cssnano/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "node_modules/cssnano/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "engines": { - "node": ">=4" + "node": ">= 6" } }, "node_modules/csso": { @@ -7919,14 +7374,6 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", @@ -7949,33 +7396,19 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "node_modules/csstype": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", - "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" - }, - "node_modules/cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "node_modules/dag-map": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/dag-map/-/dag-map-1.0.2.tgz", - "integrity": "sha1-6DefBBAA7VYfxRVHXB7SyF7s6Nc=" + "integrity": "sha512-+LSAiGFwQ9dRnRdOeaj7g47ZFJcOUPukAP8J3A3fuZ1g9Y44BG+P1sgApjLXTQPOzC4+7S9Wr8kXsfpINM4jpw==" }, "node_modules/damerau-levenshtein": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", - "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, "node_modules/data-urls": { "version": "2.0.0", @@ -8023,9 +7456,9 @@ } }, "node_modules/date-fns": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.26.0.tgz", - "integrity": "sha512-VQI812dRi3cusdY/fhoBKvc6l2W8BPWU1FNVnFH9Nttjx4AFBRzfSVb/Eyc7jBT6e9sg1XtAGsYpBQ6c/jygbg==", + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", "engines": { "node": ">=0.11" }, @@ -8035,9 +7468,9 @@ } }, "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, @@ -8051,17 +7484,21 @@ } }, "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", "dev": true, "dependencies": { "decamelize": "^1.1.0", @@ -8071,24 +7508,33 @@ "node": ">=0.10.0" } }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decamelize-keys/node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" }, "node_modules/decode-named-character-reference": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.1.tgz", - "integrity": "sha512-YV/0HQHreRwKb7uBopyIkLG17jG6Sv2qUchk9qSoVJ2f+flwRsPNBO0hAnjt6mTNYUT+vw9Gy2ihXg4sUWPi2w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", "dependencies": { "character-entities": "^2.0.0" }, @@ -8097,14 +7543,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "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=", - "engines": { - "node": ">=0.10" - } - }, "node_modules/decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -8120,23 +7558,7 @@ "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "node_modules/deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" }, "node_modules/deep-extend": { "version": "0.6.0", @@ -8161,284 +7583,111 @@ } }, "node_modules/default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dependencies": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" + "execa": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">= 10" } }, - "node_modules/default-gateway/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "clone": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, "engines": { - "node": ">=4.8" + "node": ">=0.8" } }, - "node_modules/default-gateway/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/default-gateway/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dependencies": { - "pump": "^3.0.0" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/default-gateway/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "engines": { - "node": ">=0.10.0" + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/default-gateway/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dependencies": { - "path-key": "^2.0.0" - }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=4" + "node": ">=0.4.0" } }, - "node_modules/default-gateway/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true }, - "node_modules/default-gateway/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" } }, - "node_modules/default-gateway/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/default-gateway/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/default-gateway/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/defaults/node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dependencies": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/dequal": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==", - "engines": { - "node": ">=6" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "bin": { "detect-libc": "bin/detect-libc.js" @@ -8487,40 +7736,45 @@ "node_modules/detect-port-alt/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==" + }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8532,15 +7786,20 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, "node_modules/dns-packet": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", - "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -8548,14 +7807,6 @@ "node": ">=6" } }, - "node_modules/dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dependencies": { - "buffer-indexof": "^1.0.0" - } - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -8585,9 +7836,9 @@ } }, "node_modules/dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -8597,19 +7848,10 @@ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, "node_modules/domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", @@ -8637,9 +7879,9 @@ } }, "node_modules/domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "dependencies": { "domelementtype": "^2.2.0" }, @@ -8673,35 +7915,16 @@ } }, "node_modules/dot-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "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==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dot-prop/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==", - "engines": { - "node": ">=8" - } + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/dotenv-expand": { @@ -8728,45 +7951,31 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "hasInstallScript": true, + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, "engines": { "node": ">=0.10.0" } }, "node_modules/electron-to-chromium": { - "version": "1.4.29", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.29.tgz", - "integrity": "sha512-N2Jbwxo5Rum8G2YXeUxycs1sv4Qme/ry71HG73bv8BvZl+I/4JtRgK/En+ST/Wh/yF1fqvVCY4jZBgMxnhjtBA==" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "version": "1.4.281", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.281.tgz", + "integrity": "sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==" }, "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "engines": { "node": ">=10" }, @@ -8790,7 +7999,7 @@ "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } @@ -8804,61 +8013,15 @@ } }, "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/enhanced-resolve/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/enhanced-resolve/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "dependencies": { - "ansi-colors": "^4.1.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=8.6" + "node": ">=10.13.0" } }, "node_modules/entities": { @@ -8869,17 +8032,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -8889,38 +8041,42 @@ } }, "node_modules/error-stack-parser": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", - "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "dependencies": { - "stackframe": "^1.1.1" + "stackframe": "^1.3.4" } }, "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -8929,6 +8085,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dependencies": { + "has": "^1.0.3" + } + }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -8945,35 +8119,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8985,7 +8130,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -9022,7 +8167,7 @@ "node_modules/escodegen/node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -9050,24 +8195,15 @@ "node_modules/escodegen/node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "engines": { "node": ">= 0.8.0" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/escodegen/node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dependencies": { "prelude-ls": "~1.1.2" }, @@ -9076,61 +8212,86 @@ } }, "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", + "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", + "find-up": "^5.0.0", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -9149,16 +8310,19 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/eslint-module-utils/node_modules/debug": { @@ -9169,100 +8333,84 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, "dependencies": { - "locate-path": "^2.0.0" + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "node": ">=8.10.0" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dependencies": { - "p-try": "^1.0.0" + "funding": { + "url": "https://github.com/sponsors/mysticatea" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "eslint": ">=4.19.1" } }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "eslint-visitor-keys": "^1.1.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "engines": { - "node": ">=4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, "engines": { "node": ">=4" } }, "node_modules/eslint-plugin-flowtype": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz", - "integrity": "sha512-vcz32f+7TP+kvTUyMXZmCnNujBQZDNmcqPImw8b9PZ+16w1Qdm6ryRuYZYVaG9xRqqmAPr2Cs9FAX5gN+x/bjw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", "dependencies": { - "lodash": "^4.17.15", + "lodash": "^4.17.21", "string-natural-compare": "^3.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=12.0.0" }, "peerDependencies": { - "eslint": "^7.1.0" + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" } }, "node_modules/eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dependencies": { "array-includes": "^3.1.4", "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "engines": { "node": ">=4" @@ -9293,48 +8441,70 @@ "node_modules/eslint-plugin-import/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==" + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } }, "node_modules/eslint-plugin-jsdoc": { - "version": "37.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.0.3.tgz", - "integrity": "sha512-Qg/gIZAfcrM4Qu/JzcnxPGD45Je6wPLFzMZQboeqit/CL4aY6wuzBTkgUMiWXfw/PaPl+sb0GF1XdBlV23ReDA==", + "version": "39.3.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", + "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "0.12.0", - "comment-parser": "1.2.4", - "debug": "^4.3.2", + "@es-joy/jsdoccomment": "~0.31.0", + "comment-parser": "1.3.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "^2.0.0", - "lodash": "^4.17.21", - "regextras": "^0.8.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "spdx-expression-parse": "^3.0.1" }, "engines": { - "node": "^12 || ^14 || ^16 || ^17" + "node": "^14 || ^16 || ^17 || ^18" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", - "integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", "dependencies": { - "@babel/runtime": "^7.16.3", + "@babel/runtime": "^7.18.9", "aria-query": "^4.2.2", - "array-includes": "^3.1.4", + "array-includes": "^3.1.5", "ast-types-flow": "^0.0.7", - "axe-core": "^4.3.5", + "axe-core": "^4.4.3", "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.7", + "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "has": "^1.0.3", - "jsx-ast-utils": "^3.2.1", + "jsx-ast-utils": "^3.3.2", "language-tags": "^1.0.5", - "minimatch": "^3.0.4" + "minimatch": "^3.1.2", + "semver": "^6.3.0" }, "engines": { "node": ">=4.0" @@ -9348,6 +8518,14 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-plugin-node": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", @@ -9368,23 +8546,28 @@ "eslint": ">=5.16.0" } }, - "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "eslint-visitor-keys": "^1.1.0" }, "engines": { - "node": ">=8.10.0" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/eslint-plugin-node/node_modules/semver": { @@ -9397,24 +8580,24 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.27.1.tgz", - "integrity": "sha512-meyunDjMMYeWr/4EBLTV1op3iSG3mjT/pz5gti38UzfM4OPpNc2m0t2xvKCOMU5D6FSdd34BIMFOvQbW+i8GAA==", + "version": "7.31.10", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz", + "integrity": "sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==", "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.entries": "^1.1.5", "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", + "object.hasown": "^1.1.1", "object.values": "^1.1.5", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" + "string.prototype.matchall": "^4.0.7" }, "engines": { "node": ">=4" @@ -9424,9 +8607,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz", - "integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "engines": { "node": ">=10" }, @@ -9446,12 +8629,16 @@ } }, "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9466,9 +8653,9 @@ } }, "node_modules/eslint-plugin-regexp": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.5.1.tgz", - "integrity": "sha512-5v0rQIi54m2KycQHqmOAHrZhvI56GHmI2acr6zEffAqfeifTtobAEapv9Uf4o8//lGvwVkHKyjLoSbBNEFcfOA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.9.0.tgz", + "integrity": "sha512-Che49IZ07w9KcKvrMiqfwBYv44VBunA4NqUo+UTLluYbCos9Du3+pnhkPTLTAx6ZoZ1Rmz7u7o2iC6g6qCuvxw==", "dev": true, "dependencies": { "comment-parser": "^1.1.2", @@ -9476,7 +8663,7 @@ "grapheme-splitter": "^1.0.4", "jsdoctypeparser": "^9.0.0", "refa": "^0.9.0", - "regexp-ast-analysis": "^0.3.0", + "regexp-ast-analysis": "^0.5.1", "regexpp": "^3.2.0", "scslre": "^0.1.6" }, @@ -9487,33 +8674,6 @@ "eslint": ">=6.0.0" } }, - "node_modules/eslint-plugin-regexp/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-plugin-regexp/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-plugin-sort-keys-fix": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/eslint-plugin-sort-keys-fix/-/eslint-plugin-sort-keys-fix-1.1.2.tgz", @@ -9529,6 +8689,18 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-sort-keys-fix/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/eslint-plugin-sort-keys-fix/node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", @@ -9559,245 +8731,193 @@ "license": "MIT" }, "node_modules/eslint-plugin-testing-library": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz", - "integrity": "sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.7.2.tgz", + "integrity": "sha512-0ZmHeR/DUUgEzW8rwUBRWxuqntipDtpvxK0hymdHnLlABryJkzd+CAHr+XnISaVsTisZ5MLHp6nQF+8COHLLTA==", "dependencies": { - "@typescript-eslint/experimental-utils": "^3.10.1" + "@typescript-eslint/utils": "^5.13.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0", + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", "npm": ">=6" }, "peerDependencies": { - "eslint": "^5 || ^6 || ^7" + "eslint": "^7.5.0 || ^8.0.0" } }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/experimental-utils": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz", - "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.10.1", - "@typescript-eslint/typescript-estree": "3.10.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" + "node": ">=8.0.0" } }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/types": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz", - "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==", + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=4.0" } }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/typescript-estree": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz", - "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==", + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dependencies": { - "@typescript-eslint/types": "3.10.1", - "@typescript-eslint/visitor-keys": "3.10.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/mysticatea" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/visitor-keys": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz", - "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==", - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=10" } }, - "node_modules/eslint-plugin-testing-library/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint-plugin-testing-library/node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", "dependencies": { - "tslib": "^1.8.1" + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/eslint-webpack-plugin/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "fast-deep-equal": "^3.1.3" }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/eslint-webpack-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.6.0.tgz", - "integrity": "sha512-V+LPY/T3kur5QO3u+1s34VDTcRxjXWPUGM4hlmTb5DwVD0OQz631yGTxJZf4SpAqAjdbBVe978S8BJeHpAdOhQ==", + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dependencies": { - "@types/eslint": "^7.28.2", - "arrify": "^2.0.1", - "jest-worker": "^27.3.1", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "schema-utils": "^3.1.1" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^4.0.0 || ^5.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">= 4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -9858,7 +8978,7 @@ "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } @@ -9876,41 +8996,19 @@ "node": ">=0.8.x" } }, - "node_modules/eventsource": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", - "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==" - }, "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" }, "engines": { @@ -9923,136 +9021,11 @@ "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "engines": { "node": ">= 0.8.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -10063,53 +9036,52 @@ } }, "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -10143,42 +9115,20 @@ } }, "node_modules/express-rate-limit": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz", - "integrity": "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==" + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.6.0.tgz", + "integrity": "sha512-HFN2+4ZGdkQOS8Qli4z6knmJFnw6lZed67o6b7RGplWeb1Z0s8VXaj3dUgPIdm9hrhZXTRpCTHXA0/2Eqex0vA==", + "engines": { + "node": ">= 12.9.0" + }, + "peerDependencies": { + "express": "^4 || ^5" + } }, "node_modules/express/node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/express/node_modules/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", - "dependencies": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", - "engines": { - "node": ">= 0.8" - } + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/express/node_modules/debug": { "version": "2.6.9", @@ -10188,50 +9138,10 @@ "ms": "2.0.0" } }, - "node_modules/express/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/express/node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/express/node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "dependencies": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", @@ -10252,91 +9162,10 @@ } ] }, - "node_modules/express/node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "dependencies": { - "type": "^2.5.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -10344,9 +9173,9 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -10355,7 +9184,18 @@ "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/fast-json-stable-stringify": { @@ -10366,7 +9206,7 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fastq": { "version": "1.13.0", @@ -10388,18 +9228,13 @@ } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dependencies": { "bser": "2.1.1" } }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -10412,9 +9247,9 @@ } }, "node_modules/file-loader": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz", - "integrity": "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -10430,46 +9265,37 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/file-loader/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==", + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" + "minimatch": "^5.0.1" } }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "balanced-match": "^1.0.0" + } + }, + "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==", + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": ">=10" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "node_modules/filesize": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", - "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==", + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", "engines": { "node": ">= 0.4.0" } @@ -10486,16 +9312,16 @@ } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { @@ -10513,72 +9339,22 @@ "node_modules/finalhandler/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==" }, "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dependencies": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/find-cache-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/find-cache-dir/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dependencies": { - "find-up": "^3.0.0" + "node": ">=8" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, "node_modules/find-root": { @@ -10587,25 +9363,25 @@ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dependencies": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, "bin": { "flat": "cli.js" } @@ -10622,70 +9398,10 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat/node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, "node_modules/flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==" - }, - "node_modules/flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash." - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/flush-write-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/flush-write-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "node_modules/follow-redirects": { "version": "1.15.2", @@ -10706,229 +9422,96 @@ } } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz", - "integrity": "sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", + "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", "dependencies": { - "@babel/code-frame": "^7.5.5", - "chalk": "^2.4.1", - "micromatch": "^3.1.10", + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", "minimatch": "^3.0.4", - "semver": "^5.6.0", - "tapable": "^1.0.0", - "worker-rpc": "^0.1.0" + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" }, "engines": { - "node": ">=6.11.5", + "node": ">=10", "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "dependencies": { - "color-convert": "^1.9.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -10946,21 +9529,22 @@ "node": ">= 0.6" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dependencies": { - "map-cache": "^0.2.2" - }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", "engines": { - "node": ">=0.10.0" + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" } }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } @@ -10968,7 +9552,8 @@ "node_modules/from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -10978,6 +9563,7 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10992,6 +9578,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -11016,54 +9603,15 @@ "node": ">=10" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "node_modules/fs-write-stream-atomic/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/fs-write-stream-atomic/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "node_modules/fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.2", @@ -11083,15 +9631,35 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", "dev": true, "dependencies": { "aproba": "^1.0.3", @@ -11107,34 +9675,8 @@ "node_modules/gauge/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, "engines": { "node": ">=0.10.0" } @@ -11142,7 +9684,7 @@ "node_modules/gauge/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" @@ -11168,13 +9710,13 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11194,14 +9736,11 @@ } }, "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -11222,18 +9761,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "dev": true }, "node_modules/glob": { @@ -11256,16 +9787,21 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dependencies": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 6" + "node": ">=10.13.0" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -11302,9 +9838,9 @@ } }, "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dependencies": { "type-fest": "^0.20.2" }, @@ -11316,15 +9852,15 @@ } }, "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { @@ -11335,41 +9871,27 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/grapheme-splitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "optional": true + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" }, "node_modules/gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "dependencies": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" + "duplexer": "^0.1.2" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/handle-thing": { @@ -11377,6 +9899,27 @@ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -11403,9 +9946,9 @@ } }, "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11418,10 +9961,21 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -11446,107 +10000,13 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { + "node_modules/hashlru": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } + "resolved": "git+https://npm@github.com/Hypfer/hashlru.git#fe8e672b925362de984567f2feb3b5db3ec87032", + "license": "MIT" }, "node_modules/hast-to-hyperscript": { "version": "10.0.1", @@ -11598,9 +10058,9 @@ } }, "node_modules/hast-util-raw": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.1.tgz", - "integrity": "sha512-wgtppqXVdXzkDXDFclLLdAyVUJSKMYYi6LWIAbA8oFqEdwksYIcPGM3RkKV1Dfn5GElvxhaOCs0jmCOMayxd3A==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.2.tgz", + "integrity": "sha512-0x3BhhdlBcqRIKyc095lBSDvmQNMY3Eulj2PLsT5XCyKYrxssI5yr3P4Kv/PBo1s/DMkZy2voGkMXECnFCZRLQ==", "dependencies": { "@types/hast": "^2.0.0", "@types/parse5": "^6.0.0", @@ -11646,9 +10106,9 @@ } }, "node_modules/hastscript": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.2.tgz", - "integrity": "sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.1.0.tgz", + "integrity": "sha512-uBjaTTLN0MkCZxY/R2fWUOcu7FRtUVzKRO5P/RAfgsu3yFiMB1JWCO4AjeVkgHxAira1f2UecHK5WfS9QurlWA==", "dependencies": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^2.0.0", @@ -11678,11 +10138,6 @@ "readable-stream": "^3.6.0" } }, - "node_modules/hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" - }, "node_modules/history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -11696,16 +10151,6 @@ "value-equal": "^1.0.1" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -11723,9 +10168,9 @@ } }, "node_modules/hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -11737,7 +10182,7 @@ "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -11767,16 +10212,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" - }, - "node_modules/hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" - }, "node_modules/html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -11789,9 +10224,9 @@ } }, "node_modules/html-entities": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", - "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, "node_modules/html-escaper": { "version": "2.0.2", @@ -11799,31 +10234,31 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "node_modules/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", "dependencies": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", "he": "^1.2.0", - "param-case": "^3.0.3", + "param-case": "^3.0.4", "relateurl": "^0.2.7", - "terser": "^4.6.3" + "terser": "^5.10.0" }, "bin": { "html-minifier-terser": "cli.js" }, "engines": { - "node": ">=6" + "node": ">=12" } }, "node_modules/html-minifier-terser/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "engines": { - "node": ">= 6" + "node": ">= 12" } }, "node_modules/html-void-elements": { @@ -11835,6 +10270,28 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, "node_modules/htmlparser2": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", @@ -11856,37 +10313,27 @@ "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" }, "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/http-errors/node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, "node_modules/http-parser-js": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", - "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==" + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "node_modules/http-proxy": { "version": "1.18.1", @@ -11915,149 +10362,43 @@ } }, "node_modules/http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dependencies": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "dependencies": { - "is-extendable": "^0.1.0" + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "node": ">=12.0.0" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" + "peerDependencies": { + "@types/express": "^4.17.13" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, - "node_modules/http-proxy-middleware/node_modules/is-number": { + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "node": ">=10" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { "agent-base": "6", "debug": "4" @@ -12067,11 +10408,11 @@ } }, "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "engines": { - "node": ">=8.12.0" + "node": ">=10.17.0" } }, "node_modules/iconv-lite": { @@ -12086,20 +10427,25 @@ } }, "node_modules/icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dependencies": { - "postcss": "^7.0.14" - }, + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "engines": { - "node": ">= 6" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, + "node_modules/idb": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.0.tgz", + "integrity": "sha512-Wsk07aAxDsntgYJY4h0knZJuTxM73eQ4reRAO+Z1liOh8eMCJ/MoDS8fCui1vGT9mnjtl1sOu3I2i/W1swPYZg==" + }, "node_modules/identity-obj-proxy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", "dependencies": { "harmony-reflect": "^1.4.6" }, @@ -12126,11 +10472,6 @@ } ] }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -12140,9 +10481,9 @@ } }, "node_modules/immer": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", - "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==", + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -12197,9 +10538,9 @@ } }, "node_modules/import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -12209,23 +10550,15 @@ }, "engines": { "node": ">=8" - } - }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "engines": { "node": ">=0.8.19" } @@ -12234,24 +10567,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -12272,18 +10596,6 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, - "node_modules/internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dependencies": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -12313,19 +10625,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "engines": { - "node": ">=4" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -12334,44 +10633,10 @@ "node": ">= 0.10" } }, - "node_modules/is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-bigint": { "version": "1.0.4", @@ -12388,7 +10653,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -12417,9 +10681,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "engines": { "node": ">= 0.4" }, @@ -12427,52 +10691,17 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dependencies": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dependencies": { - "has": "^1.0.3" + "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -12487,27 +10716,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -12522,31 +10730,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/is-generator-fn": { @@ -12588,7 +10789,7 @@ "node_modules/is-invalid-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", - "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=", + "integrity": "sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==", "dependencies": { "is-glob": "^2.0.0" }, @@ -12599,7 +10800,7 @@ "node_modules/is-invalid-path/node_modules/is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==", "engines": { "node": ">=0.10.0" } @@ -12607,7 +10808,7 @@ "node_modules/is-invalid-path/node_modules/is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", "dependencies": { "is-extglob": "^1.0.0" }, @@ -12618,7 +10819,7 @@ "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" }, "node_modules/is-negative-zero": { "version": "2.0.2", @@ -12640,9 +10841,9 @@ } }, "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -12656,47 +10857,18 @@ "node_modules/is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "engines": { "node": ">=0.10.0" } }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dependencies": { - "is-path-inside": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dependencies": { - "path-is-inside": "^1.0.2" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/is-plain-object": { @@ -12733,16 +10905,11 @@ "node_modules/is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "engines": { "node": ">=0.10.0" } }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" - }, "node_modules/is-root": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", @@ -12752,9 +10919,12 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12801,12 +10971,24 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/is-valid-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", - "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=", + "integrity": "sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==", "dependencies": { "is-invalid-path": "^0.1.0" }, @@ -12825,14 +11007,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -12847,17 +11021,17 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -12871,9 +11045,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -12906,28 +11080,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", @@ -12941,18 +11093,10 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/istanbul-reports": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.2.tgz", - "integrity": "sha512-0gHxuT1NNC0aEIL1zbJ+MTgPbbHhU77eJPuU35WKA7TgXiSNlCAx4PENoMrH0Or6M2H80TaZcWKhM0IK6V8gRw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -12961,118 +11105,159 @@ "node": ">=8" } }, + "node_modules/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, "node_modules/jest": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz", - "integrity": "sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "dependencies": { - "@jest/core": "^26.6.0", + "@jest/core": "^27.5.1", "import-local": "^3.0.2", - "jest-cli": "^26.6.0" + "jest-cli": "^27.5.1" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-circus": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.6.0.tgz", - "integrity": "sha512-L2/Y9szN6FJPWFK8kzWXwfp+FOR7xq0cUL4lIsdbIdwz3Vh6P1nrpcqOleSzr28zOtSHQNV9Z7Tl+KkuK7t5Ng==", - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.0", - "@jest/test-result": "^26.6.0", - "@jest/types": "^26.6.0", - "@types/babel__traverse": "^7.0.4", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^26.6.0", + "expect": "^27.5.1", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.0", - "jest-matcher-utils": "^26.6.0", - "jest-message-util": "^26.6.0", - "jest-runner": "^26.6.0", - "jest-runtime": "^26.6.0", - "jest-snapshot": "^26.6.0", - "jest-util": "^26.6.0", - "pretty-format": "^26.6.0", - "stack-utils": "^2.0.2", - "throat": "^5.0.0" + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", "prompts": "^2.0.1", - "yargs": "^15.4.1" + "yargs": "^16.2.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/jest-cli/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { "ts-node": ">=9.0.0" @@ -13083,227 +11268,194 @@ } } }, - "node_modules/jest-cli/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "dependencies": { "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", "walker": "^1.0.7" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/jest-haste-map/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" + "fsevents": "^2.3.2" } }, "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.6.2", + "expect": "^27.5.1", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/node": "*" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-pnp-resolver": { @@ -13323,364 +11475,488 @@ } }, "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-resolve": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.0.tgz", - "integrity": "sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "dependencies": { - "@jest/types": "^26.6.0", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.0", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dependencies": { - "@jest/types": "^26.6.2", + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runner/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dependencies": { + "@jest/types": "^27.5.1", "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 10.13.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" } }, - "node_modules/jest-runtime/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", + "ansi-escapes": "^4.3.1", "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "jest": "^27.0.0 || ^28.0.0" } }, - "node_modules/jest-runtime/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/jest-watch-typeahead/node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^28.1.3", + "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "graceful-fs": "^4.2.4" + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", "engines": { - "node": ">= 10.14.2" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/jest-snapshot/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dependencies": { - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-watch-typeahead": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.6.1.tgz", - "integrity": "sha512-ITVnHhj3Jd/QkqQcTqZfRgjfyRhDFM/auzgVo2RKvSwi18YMvh0WvXDJFoFED6c7jd/5jxtu4kSOb9PTu2cPVg==", + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dependencies": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^26.0.0", - "jest-watcher": "^26.3.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", + "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" }, - "peerDependencies": { - "jest": "^26.0.0" + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "jest-util": "^27.5.1", "string-length": "^4.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -13704,6 +11980,11 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==" + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -13715,21 +11996,20 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsdoc-type-pratt-parser": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.2.tgz", - "integrity": "sha512-gXN5CxeaI9WtYQYzpOO/CtTRfZppQlKxXRTIm73JuAX6kOGTQ7iZ0e+YB+b2m7Fk+gTYYxRtE1nqje7H6dqv8w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", + "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", "dev": true, "engines": { "node": ">=12.0.0" @@ -13792,15 +12072,17 @@ } } }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "bin": { - "acorn": "bin/acorn" + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=0.4.0" + "node": ">= 6" } }, "node_modules/jsdom/node_modules/tr46": { @@ -13835,6 +12117,11 @@ "node": ">=10" } }, + "node_modules/jsencrypt": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.2.1.tgz", + "integrity": "sha512-k1sD5QV0KPn+D8uG9AdGzTQuamt82QZ3A3l6f7TRwMU6Oi2Vg0BsL+wZIQBONcraO1pc78ExMdvmBBJ8WhNYUA==" + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -13846,16 +12133,16 @@ "node": ">=4" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, "node_modules/json-schema-deref-sync": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/json-schema-deref-sync/-/json-schema-deref-sync-0.14.0.tgz", @@ -13875,27 +12162,19 @@ } }, "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==" + "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", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "node_modules/json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "bin": { "json5": "lib/cli.js" }, @@ -13914,28 +12193,31 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jstoxml": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-2.2.7.tgz", - "integrity": "sha512-cvnnvXSwQo1NcgfuNnHFrCPKG3o0JPrqC1gf6NhAM1UejLsEzcGcmn223iF6XdMf+7RCW/GYv12Ako3ivPamBw==" + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-3.2.5.tgz", + "integrity": "sha512-MxJI8rcCTAeYgxW9a61i/jfK9KjVKpqbStoAf4QADXJ9jTLbh9KMM9A0qxcIRxxkopr6Ba6Wm68pxA6zBZpe+Q==" }, "node_modules/jsx-ast-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", - "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", "dependencies": { - "array-includes": "^3.1.3", - "object.assign": "^4.1.2" + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" }, "engines": { "node": ">=4.0" } }, - "node_modules/killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -13961,33 +12243,24 @@ } }, "node_modules/language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==" + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" }, "node_modules/language-tags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "dependencies": { "language-subtag-registry": "~0.3.2" } }, - "node_modules/last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "dependencies": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, "node_modules/levn": { @@ -14002,52 +12275,52 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "engines": { + "node": ">=10" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" + "node": ">=6.11.5" } }, "node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", - "json5": "^1.0.1" + "json5": "^2.1.2" }, "engines": { - "node": ">=4.0.0" + "node": ">=8.9.0" } }, - "node_modules/loader-utils/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dependencies": { - "minimist": "^1.2.0" + "p-locate": "^5.0.0" }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -14055,30 +12328,25 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -14091,126 +12359,30 @@ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/log-symbols/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", - "engines": { - "node": ">= 0.6.0" + "node": ">=10" }, "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/loglevel" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/long": { @@ -14247,9 +12419,9 @@ } }, "node_modules/lower-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -14263,31 +12435,33 @@ } }, "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "dependencies": { - "sourcemap-codec": "^1.4.4" + "sourcemap-codec": "^1.4.8" } }, "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/makeerror": { @@ -14298,14 +12472,6 @@ "tmpl": "1.0.5" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -14318,17 +12484,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/markdown-table": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz", @@ -14350,45 +12505,21 @@ "node_modules/md5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", - "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "integrity": "sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==", "dependencies": { "charenc": "~0.0.1", "crypt": "~0.0.1", "is-buffer": "~1.1.1" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/mdast-util-definitions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.0.tgz", - "integrity": "sha512-5hcR7FL2EuZ4q6lLMUK5w4lHT2H3vqL9quPvYZ/Ku5iifrirfMHiGdhxdXMUbUkDmz5I+TYMd7nbaxUhbQkfpQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz", + "integrity": "sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "unist-util-visit": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" + "unist-util-visit": "^4.0.0" }, "funding": { "type": "opencollective", @@ -14396,13 +12527,13 @@ } }, "node_modules/mdast-util-find-and-replace": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.1.0.tgz", - "integrity": "sha512-1w1jbqAd13oU78QPBf5223+xB+37ecNtQ1JElq2feWols5oEYAl+SgNDnOZipe7NfLemoEt362yUS15/wip4mw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.1.tgz", + "integrity": "sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==", "dependencies": { "escape-string-regexp": "^5.0.0", "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" + "unist-util-visit-parents": "^5.0.0" }, "funding": { "type": "opencollective", @@ -14444,15 +12575,17 @@ } }, "node_modules/mdast-util-gfm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.0.tgz", - "integrity": "sha512-wMwejlTN3EQADPFuvxe8lmGsay3+f6gSJKdAHR6KBJzpcxvsjJSILB9K6u6G7eQLC7iOTyVIHYGui9uBc9r1Tg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.1.tgz", + "integrity": "sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==", "dependencies": { + "mdast-util-from-markdown": "^1.0.0", "mdast-util-gfm-autolink-literal": "^1.0.0", "mdast-util-gfm-footnote": "^1.0.0", "mdast-util-gfm-strikethrough": "^1.0.0", "mdast-util-gfm-table": "^1.0.0", - "mdast-util-gfm-task-list-item": "^1.0.0" + "mdast-util-gfm-task-list-item": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" }, "funding": { "type": "opencollective", @@ -14475,14 +12608,13 @@ } }, "node_modules/mdast-util-gfm-footnote": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.0.tgz", - "integrity": "sha512-qeg9YoS2YYP6OBmMyUFxKXb6BLwAsbGidIxgwDAXHIMYZQhIwe52L9BSJs+zP29Jp5nSERPkmG3tSwAN23/ZbQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.1.tgz", + "integrity": "sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==", "dependencies": { "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "unist-util-visit": "^4.0.0" + "mdast-util-to-markdown": "^1.3.0", + "micromark-util-normalize-identifier": "^1.0.0" }, "funding": { "type": "opencollective", @@ -14490,12 +12622,12 @@ } }, "node_modules/mdast-util-gfm-strikethrough": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.0.tgz", - "integrity": "sha512-gM9ipBUdRxYa6Yq1Hd8Otg6jEn/dRxFZ1F9ZX4QHosHOexLGqNZO2dh0A+YFbUEd10RcKjnjb4jOfJJzoXXUew==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.1.tgz", + "integrity": "sha512-zKJbEPe+JP6EUv0mZ0tQUyLQOC+FADt0bARldONot/nefuISkaZFlmVK4tU6JgfyZGrky02m/I6PmehgAgZgqg==", "dependencies": { - "@types/mdast": "^3.0.3", - "mdast-util-to-markdown": "^1.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" }, "funding": { "type": "opencollective", @@ -14503,12 +12635,14 @@ } }, "node_modules/mdast-util-gfm-table": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.2.tgz", - "integrity": "sha512-pPekvCTChFBF8uCq8bVyQwar8NBU/TaXIy44jj/UzmjMgPBHIa1B1ge8a0JVgzhqgXQAMvGT+PgiKlicdLGfDQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.6.tgz", + "integrity": "sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==", "dependencies": { + "@types/mdast": "^3.0.0", "markdown-table": "^3.0.0", - "mdast-util-to-markdown": "^1.0.0" + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.3.0" }, "funding": { "type": "opencollective", @@ -14516,12 +12650,12 @@ } }, "node_modules/mdast-util-gfm-task-list-item": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.0.tgz", - "integrity": "sha512-dwkzOTjQe8JCCHVE3Cb0pLHTYLudf7t9WCAnb20jI8/dW+VHjgWhjtIUVA3oigNkssgjEwX+i+3XesUdCnXGyA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.1.tgz", + "integrity": "sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==", "dependencies": { - "@types/mdast": "^3.0.3", - "mdast-util-to-markdown": "^1.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" }, "funding": { "type": "opencollective", @@ -14529,15 +12663,15 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-11.3.0.tgz", - "integrity": "sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw==", + "version": "12.2.4", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.4.tgz", + "integrity": "sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg==", "dependencies": { "@types/hast": "^2.0.0", "@types/mdast": "^3.0.0", - "@types/mdurl": "^1.0.0", "mdast-util-definitions": "^5.0.0", - "mdurl": "^1.0.0", + "micromark-util-sanitize-uri": "^1.1.0", + "trim-lines": "^3.0.0", "unist-builder": "^3.0.0", "unist-util-generated": "^2.0.0", "unist-util-position": "^4.0.0", @@ -14549,9 +12683,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.6.tgz", - "integrity": "sha512-doJZmTEGagHypWvJ8ltinmwUsT9ZaNgNIQW6Gl7jNdsI1QZkTHTimYW561Niy2s8AEPAqEgV0dIh2UOVlSXUJA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz", + "integrity": "sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -14580,54 +12714,29 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } }, - "node_modules/memory-cache": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", - "integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo=" - }, - "node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/memory-fs/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/memfs": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", + "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "fs-monkey": "^1.0.3" + }, + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/memory-fs/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "node_modules/memory-cache": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", + "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" }, "node_modules/meow": { "version": "8.0.0", @@ -14669,7 +12778,7 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/merge-stream": { "version": "2.0.0", @@ -14687,20 +12796,15 @@ "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } }, - "node_modules/microevent.ts": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", - "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" - }, "node_modules/micromark": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.10.tgz", - "integrity": "sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", + "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", "funding": [ { "type": "GitHub Sponsors", @@ -14800,9 +12904,9 @@ } }, "node_modules/micromark-extension-gfm-footnote": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.3.tgz", - "integrity": "sha512-bn62pC5y39rIo2g1RqZk1NhF7T7cJLuJlbevunQz41U0iPVCdVOFASe5/L1kke+DFKSgfCRhv24+o42cZ1+ADw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.4.tgz", + "integrity": "sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==", "dependencies": { "micromark-core-commonmark": "^1.0.0", "micromark-factory-space": "^1.0.0", @@ -14810,6 +12914,7 @@ "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-sanitize-uri": "^1.0.0", "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", "uvu": "^0.5.0" }, "funding": { @@ -15112,9 +13217,9 @@ ] }, "node_modules/micromark-util-html-tag-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.0.0.tgz", - "integrity": "sha512-NenEKIshW2ZI/ERv9HtFNsrn3llSPZtY337LID/24WeLqMzeZhBEE6BQ0vS2ZBjshm5n40chKtJ3qjAbVV8S0g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz", + "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==", "funding": [ { "type": "GitHub Sponsors", @@ -15163,9 +13268,9 @@ } }, "node_modules/micromark-util-sanitize-uri": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz", - "integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", + "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", "funding": [ { "type": "GitHub Sponsors", @@ -15234,12 +13339,12 @@ ] }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" @@ -15250,23 +13355,6 @@ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -15279,19 +13367,19 @@ } }, "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -15330,6 +13418,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dependencies": { "@babel/runtime": "^7.12.1", "tiny-warning": "^1.0.3" @@ -15340,37 +13429,65 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", - "integrity": "sha512-n9BA8LonkOkW1/zn+IbLPQmovsL0wMb9yx75fMJQZf2X1Zoec9yTZtyMePcyu19wPkmFbzZZA6fLTotpFhQsOA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "dependencies": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 6.9.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.4.0 || ^5.0.0" + "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==", + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 4" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/minimalistic-assert": { @@ -15378,15 +13495,10 @@ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -15416,156 +13528,21 @@ "node": ">= 6" } }, - "node_modules/minimist-options/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mississippi/node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/mississippi/node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/mississippi/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/mississippi/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" @@ -15578,482 +13555,177 @@ "dev": true }, "node_modules/mocha": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz", - "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", "dev": true, "dependencies": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.3", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/mocha/node_modules/minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=4" - } - }, - "node_modules/mocha/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/mocha/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" + "node": ">=10" } }, - "node_modules/mocha/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mocha/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", "dependencies": { - "locate-path": "^3.0.0" + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" }, "engines": { - "node": ">=6" + "node": ">=10.0.0" } }, - "node_modules/mocha/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" } }, - "node_modules/mocha/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "engines": { "node": ">=4" } }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "multicast-dns": "cli.js" } }, - "node_modules/mocha/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/multistream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", + "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/mocha/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/mocha/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/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/mocha/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/mocha/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/move-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/mqtt": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz", - "integrity": "sha512-DJYjlXODVXtSDecN8jnNzi6ItX3+ufGsEs9OB3YV24HtkRrh7kpx8L5M1LuyF0KzaiGtWr2PzDcMGAY60KGOSA==", - "dependencies": { - "commist": "^1.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", - "reinterval": "^1.1.0", - "split2": "^3.1.0", - "ws": "^7.5.0", - "xtend": "^4.0.2" - }, - "bin": { - "mqtt": "bin/mqtt.js", - "mqtt_pub": "bin/pub.js", - "mqtt_sub": "bin/sub.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", - "dependencies": { - "bl": "^4.0.2", - "debug": "^4.1.1", - "process-nextick-args": "^2.0.1" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz", - "integrity": "sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" - }, - "node_modules/multistream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", - "integrity": "sha512-J1XDiAmmNpRCBfIWJv+n0ymC4ABcf/Pl+5YvC5B/D2f/2+8PtHvCNxMPKiQcZyi922Hq69J2YOpb1pTywfifyw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "once": "^1.4.0", - "readable-stream": "^3.6.0" + "once": "^1.4.0", + "readable-stream": "^3.6.0" } }, "node_modules/mute-stream": { @@ -16062,29 +13734,24 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, "node_modules/nano-memoize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/nano-memoize/-/nano-memoize-1.2.1.tgz", - "integrity": "sha512-ANfJ0QFhLzv9BZV8tHxwaDClqr+U8yY65hZA+slbgJrx+ePnHtlY92F2ZJInkkQWUUR71NzCEHBshKCHJnNyaQ==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/nano-memoize/-/nano-memoize-1.3.0.tgz", + "integrity": "sha512-yM/gMQHvA5EOtNGfEbJ8tmAveNjbckhzZ1hkNtMjY8zps3ocjPfp1kuJ1++OgtVHAhsGSTJttG3S6UV+FZZzxQ==" }, "node_modules/nano-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", - "integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", "dependencies": { "big-integer": "^1.6.16" } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -16092,50 +13759,21 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", "dev": true }, - "node_modules/native-url": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.2.6.tgz", - "integrity": "sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA==", - "dependencies": { - "querystring": "^0.2.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "engines": { "node": ">= 0.6" } @@ -16155,16 +13793,6 @@ "resolved": "https://registry.npmjs.org/nested-property/-/nested-property-4.0.0.tgz", "integrity": "sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA==" }, - "node_modules/next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -16175,9 +13803,9 @@ } }, "node_modules/no-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/node-abi": { "version": "2.30.1", @@ -16197,25 +13825,6 @@ "semver": "bin/semver" } }, - "node_modules/node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "dependencies": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node_modules/node-environment-flags/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -16237,140 +13846,28 @@ } }, "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", "engines": { - "node": ">= 6.0.0" + "node": ">= 6.13.0" } }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, - "node_modules/node-libs-browser/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, - "node_modules/node-libs-browser/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/node-notifier": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.0.tgz", - "integrity": "sha512-ZTqP90y1eyb2xAZTa7j4AlAayTwh6cL8mn0nlJhLDq8itXGnJUmQGYOnpaMUvqZVfGo0vhU7KZ3HtDW6CT2SiQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.5", - "shellwords": "^0.1.1", - "uuid": "^8.3.2", - "which": "^2.0.2" - } - }, - "node_modules/node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - }, - "node_modules/node-ssdp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/node-ssdp/-/node-ssdp-4.0.1.tgz", - "integrity": "sha512-uJXkLZVuyaMg1qNbMbGQ6YzNzyOD+NLxYyxIJocPTKTVECPDokOiCZA686jTLXHMUnV34uY/lcUSJ+/5fhY43A==", - "dependencies": { - "async": "^2.6.0", - "bluebird": "^3.5.1", - "debug": "^3.1.0", - "extend": "^3.0.1", - "ip": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-ssdp/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", @@ -16392,29 +13889,26 @@ "node_modules/normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dependencies": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - }, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/notistack": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/notistack/-/notistack-2.0.3.tgz", - "integrity": "sha512-krmVFtTO9kEY1Pa4NrbyexrjiRcV6TqBM2xLx8nuDea1g96Z/OZfkvVLmYKkTvoSJ3jyQntWK16z86ssW5kt4A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-2.0.5.tgz", + "integrity": "sha512-Ig2T1Muqkc1PaSQcEDrK7diKv6cBxw02Iq6uv074ySfgq524TV5lK41diAb6OSsaiWfp3aRt+T3+0MF8m2EcJQ==", "dependencies": { "clsx": "^1.1.0", "hoist-non-react-statics": "^3.3.0" @@ -16427,8 +13921,8 @@ "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@mui/material": "^5.0.0", - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@emotion/react": { @@ -16463,9 +13957,9 @@ } }, "node_modules/nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dependencies": { "boolbase": "^1.0.0" }, @@ -16473,130 +13967,54 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + "node_modules/number-allocator": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.12.tgz", + "integrity": "sha512-sGB0qoQGmKimery9JubBQ9pQUr1V/LixJAk3Ygp7obZf6mpSXime8d7XHEobbIimkdZpgjkNlLt6G7LPEWFYWg==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.1.4" + } + }, + "node_modules/number-allocator/node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16609,25 +14027,14 @@ "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -16667,13 +14074,14 @@ } }, "node_modules/object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", "dependencies": { + "array.prototype.reduce": "^1.0.4", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" }, "engines": { "node": ">= 0.8" @@ -16683,28 +14091,17 @@ } }, "node_modules/object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.values": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", @@ -16732,9 +14129,9 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -16753,7 +14150,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } @@ -16773,15 +14170,16 @@ } }, "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -16798,23 +14196,17 @@ "swagger-schema-official": "2.0.0-bab6bed" } }, - "node_modules/openapi-schema-validator/node_modules/openapi-types": { + "node_modules/openapi-types": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.4.tgz", "integrity": "sha512-h8rADpW3k/wepLdERKF0VKMAPdoFYNQCLGPmc/f8sgQ2dxUy+7sY4WAX2XDUDjhKTjbJVbxxofLkzy7f1/tE4g==" }, - "node_modules/openapi-types": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-10.0.0.tgz", - "integrity": "sha512-Y8xOCT2eiKGYDzMW9R4x5cmfc3vGaaI4EL2pwhDmodWw1HlK18YcZ4uJxc7Rdp7/gGzAygzH9SXr6GKYIXbRcQ==", - "peer": true - }, "node_modules/openapi-validator-middleware": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/openapi-validator-middleware/-/openapi-validator-middleware-3.2.4.tgz", - "integrity": "sha512-xcvzR3HtWm3UYiW5w1AuQZ2FJr+JwGQbqEijtRd9uPY4zLVYogs2m2ZsCRUQLNqJGc4CU9evWogeVyD+7wSvMw==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/openapi-validator-middleware/-/openapi-validator-middleware-3.2.6.tgz", + "integrity": "sha512-a4gcn3K88GXSsUbEt1D0oDYsDbpukE8CLJnrAs4Lk0UkNXvf7eMlEHetjFfbqmZkxGAMK+zsyqxfxArDmXyWqw==", "dependencies": { - "api-schema-builder": "^2.0.10", + "api-schema-builder": "^2.0.11", "auto-bind": "^4.0.0", "nano-memoize": "^1.2.1" }, @@ -16830,37 +14222,6 @@ } } }, - "node_modules/opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dependencies": { - "is-wsl": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/opn/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/optimize-css-assets-webpack-plugin": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz", - "integrity": "sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A==", - "dependencies": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -16909,70 +14270,118 @@ "node": ">=8" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + "node_modules/ora/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "node_modules/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/ora/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.8.0" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } }, - "node_modules/p-is-promise": { + "node_modules/ora/node_modules/log-symbols": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, "engines": { "node": ">=8" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/ora/node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "p-try": "^2.0.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=6" + "node": ">=4" + } + }, + "node_modules/ora/node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/ora/node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "has-flag": "^3.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { - "aggregate-error": "^3.0.0" + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" }, "engines": { "node": ">=10" @@ -16982,14 +14391,15 @@ } }, "node_modules/p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dependencies": { - "retry": "^0.12.0" + "@types/retry": "0.12.0", + "retry": "^0.13.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/p-try": { @@ -17000,43 +14410,6 @@ "node": ">=6" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/parallel-transform/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/parallel-transform/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -17047,9 +14420,9 @@ } }, "node_modules/param-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/parent-module": { "version": "1.0.1", @@ -17062,16 +14435,16 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "node_modules/parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true, + "bin": { + "parse-github-url": "cli.js" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/parse-json": { @@ -17114,27 +14487,9 @@ } }, "node_modules/pascal-case/node_modules/tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" }, "node_modules/path-exists": { "version": "4.0.0", @@ -17147,16 +14502,11 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -17173,7 +14523,7 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/path-type": { "version": "4.0.0", @@ -17183,25 +14533,10 @@ "node": ">=8" } }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -17209,9 +14544,9 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { "node": ">=8.6" }, @@ -17220,61 +14555,41 @@ } }, "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dependencies": { - "pinkie": "^2.0.0" - }, + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "engines": { "node": ">=0.10.0" } }, "node_modules/pirates": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", - "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "engines": { "node": ">= 6" } }, "node_modules/pkg": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.3.2.tgz", - "integrity": "sha512-78X8Tt71TI11XjkZm/r9shTdFRooFiiRcT8nfYeeOou5VKCkCysQauwAAkJKb5yjfrUhk3CBNL4zv22/iLpdnw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.7.0.tgz", + "integrity": "sha512-PTiAjNq/CGAtK5qUBR6pjheqnipTFjeecgSgIKEcAOJA4GpmZeOZC8pMOoT0rfes5vHsmcFo7wbSRTAmXQurrg==", "dev": true, "dependencies": { - "@babel/parser": "7.13.13", - "@babel/types": "7.13.12", - "chalk": "^4.1.0", + "@babel/parser": "7.17.10", + "@babel/types": "7.17.10", + "chalk": "^4.1.2", "escodegen": "^2.0.0", "fs-extra": "^9.1.0", - "globby": "^11.0.3", + "globby": "^11.1.0", "into-stream": "^6.0.0", - "minimist": "^1.2.5", + "is-core-module": "2.9.0", + "minimist": "^1.2.6", "multistream": "^4.1.0", - "pkg-fetch": "3.2.3", - "prebuild-install": "6.0.1", - "progress": "^2.0.3", - "resolve": "^1.20.0", - "stream-meter": "^1.0.4", - "tslib": "2.1.0" + "pkg-fetch": "3.4.1", + "prebuild-install": "6.1.4", + "resolve": "^1.22.0", + "stream-meter": "^1.0.4" }, "bin": { "pkg": "lib-es5/bin.js" @@ -17289,150 +14604,83 @@ } }, "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dependencies": { - "find-up": "^2.1.0" + "find-up": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/pkg-dir/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/pkg-dir/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/pkg-dir/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/pkg-dir/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/pkg-fetch": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.2.3.tgz", - "integrity": "sha512-bv9vYANgAZ2Lvxn5Dsq7E0rLqzcqYkV4gnwe2f7oHV9N4SVMfDOIjjFCRuuTltop5EmsOcu7XkQpB5A/pIgC1g==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.4.1.tgz", + "integrity": "sha512-fS4cdayCa1r4jHkOKGPJKnS9PEs6OWZst+s+m0+CmhmPZObMnxoRnf9T9yUWl+lzM2b5aJF7cnQIySCT7Hq8Dg==", "dev": true, "dependencies": { - "chalk": "^4.1.0", + "chalk": "^4.1.2", "fs-extra": "^9.1.0", "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.6", "progress": "^2.0.3", "semver": "^7.3.5", + "tar-fs": "^2.1.1", "yargs": "^16.2.0" }, "bin": { "pkg-fetch": "lib-es5/bin.js" } }, - "node_modules/pkg-fetch/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/pkg-fetch/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/pkg-fetch/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/pkg-fetch/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "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.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pkg-up": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", @@ -17467,6 +14715,20 @@ "node": ">=6" } }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -17481,1261 +14743,1160 @@ "node_modules/pkg-up/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "engines": { "node": ">=4" } }, - "node_modules/pkg/node_modules/@babel/parser": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", - "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" + "node_modules/postcss": { + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "engines": { - "node": ">=6.0.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/pkg/node_modules/@babel/types": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz", - "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==", - "dev": true, + "node_modules/postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/pkg/node_modules/tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" + } }, - "node_modules/pnp-webpack-plugin": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", - "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", "dependencies": { - "ts-pnp": "^1.1.6" + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" }, - "engines": { - "node": ">=6" + "peerDependencies": { + "postcss": "^8.2.2" } }, - "node_modules/portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">= 0.12.0" + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" } }, - "node_modules/portfinder/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" - } - }, - "node_modules/postcss-browser-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", - "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", - "dependencies": { - "postcss": "^7" - }, - "engines": { - "node": ">=8.0.0" + "url": "https://opencollective.com/csstools" }, "peerDependencies": { - "browserslist": "^4" - } - }, - "node_modules/postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", - "dependencies": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" + "postcss": "^8.2" } }, "node_modules/postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", "dependencies": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=6.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", + "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", "dependencies": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-colormin/node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/postcss-colormin/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-colormin/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/postcss-colormin/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", + "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "browserslist": "^4.20.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", "dependencies": { - "postcss": "^7.0.14" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3" } }, "node_modules/postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.9.tgz", + "integrity": "sha512-/E7PRvK8DAVljBbeWrcEQJPG72jaImxF3vvCNFwv9cC8CzigVoNIpeyfnJzphnN3Fd8/auBf5wvkw6W9MfmTyg==", "dependencies": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" + "postcss-selector-parser": "^6.0.4" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-selectors/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.3" } }, "node_modules/postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dependencies": { - "postcss": "^7.0.0" - }, + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dependencies": { - "postcss": "^7.0.0" - }, + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dependencies": { - "postcss": "^7.0.0" - }, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dependencies": { - "postcss": "^7.0.0" - }, + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", "dependencies": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/postcss-flexbugs-fixes": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz", - "integrity": "sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==", - "dependencies": { - "postcss": "^7.0.26" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "peerDependencies": { + "postcss": "^8.1.4" } }, "node_modules/postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", "dependencies": { - "postcss": "^7.0.2" + "postcss-selector-parser": "^6.0.9" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "dependencies": { - "postcss": "^7.0.2" + "postcss-selector-parser": "^6.0.9" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/postcss-font-variant": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", - "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", - "dependencies": { - "postcss": "^7.0.2" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", - "dependencies": { - "postcss": "^7.0.2" - }, + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-initial": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", - "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", - "dependencies": { - "postcss": "^7.0.2" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" }, "engines": { - "node": ">=6.0.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" } }, - "node_modules/postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", "dependencies": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" + "camelcase-css": "^2.0.1" }, "engines": { - "node": ">= 4" + "node": "^12 || ^14 || >= 16" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" } }, - "node_modules/postcss-load-config/node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-load-config/node_modules/import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dependencies": { - "import-from": "^2.1.0" + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-load-config/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/postcss-load-config/node_modules/import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", "dependencies": { - "resolve-from": "^3.0.0" + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" }, "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-load-config/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "node": ">= 10" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/postcss-load-config/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "engines": { - "node": ">=4" + "node": ">= 6" } }, "node_modules/postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", "dependencies": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "node": ">= 12.13.0" }, - "engines": { - "node": ">= 4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" } }, "node_modules/postcss-logical": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "dependencies": { - "postcss": "^7.0.2" - }, + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" } }, "node_modules/postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "dependencies": { - "postcss": "^7.0.2" - }, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", "engines": { - "node": ">=6.0.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz", + "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==", "dependencies": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz", + "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==", "dependencies": { - "browserslist": "^4.0.0", + "browserslist": "^4.16.6", "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node": "^10 || ^12 || >=14.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz", + "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==", "dependencies": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", "dependencies": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" + "postcss-selector-parser": "^6.0.5" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node": "^10 || ^12 || >=14.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dependencies": { - "postcss": "^7.0.5" - }, + "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==", "engines": { - "node": ">= 6" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", "dependencies": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", + "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" }, "engines": { - "node": ">= 6" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" + "postcss-selector-parser": "^6.0.4" }, "engines": { - "node": ">= 6" + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" } }, "node_modules/postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", "dependencies": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" + "postcss-selector-parser": "^6.0.6" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" } }, "node_modules/postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "dependencies": { - "postcss": "^7.0.2" + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-normalize": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", - "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", "dependencies": { - "@csstools/normalize.css": "^10.1.0", - "browserslist": "^4.6.2", - "postcss": "^7.0.17", - "postcss-browser-comments": "^3.0.0", - "sanitize.css": "^10.0.0" + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" }, "engines": { - "node": ">=8.0.0" + "node": ">= 12" + }, + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" } }, "node_modules/postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dependencies": { - "postcss": "^7.0.0" - }, + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", "dependencies": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", + "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", "dependencies": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-url/node_modules/normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "engines": { - "node": ">=6" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + "node_modules/postcss-opacity-percentage": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz", + "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^12 || ^14 || >=16" + } }, "node_modules/postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", "dependencies": { - "postcss": "^7.0.2" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "dependencies": { - "postcss": "^7.0.2" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "peerDependencies": { + "postcss": "^8" } }, "node_modules/postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-preset-env": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", - "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", - "dependencies": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz", + "integrity": "sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==", + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.0", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.11", + "browserslist": "^4.21.3", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.0.1", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.9", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=6.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" + "node": "^12 || ^14 || >=16" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.2" } }, "node_modules/postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", + "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "dependencies": { - "postcss": "^7.0.2" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "peerDependencies": { + "postcss": "^8.0.3" } }, - "node_modules/postcss-safe-parser": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-5.0.2.tgz", - "integrity": "sha512-jDUfCPJbKOABhwpUKcqCVbbXiloe/QXMcbJ6Iipf3sDIihEzTqRCeMBfRaOHxhBuTYqtASrI1KJWxzztZU4qUQ==", + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", "dependencies": { - "postcss": "^8.1.0" + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=10.0" + "node": "^12 || ^14 || >=16" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" } }, - "node_modules/postcss-safe-parser/node_modules/postcss": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz", - "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==", + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dependencies": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.1" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": "^10 || ^12 || >=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-selector-matches": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" + "node": ">=4" } }, - "node_modules/postcss-selector-not": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", - "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, - "node_modules/postcss-selector-parser": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz", - "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==", + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "mdn-data": "2.0.14", + "source-map": "^0.6.1" }, "engines": { - "node": ">=4" + "node": ">=8.0.0" } }, - "node_modules/postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" }, "engines": { - "node": ">=6.9.0" + "node": ">=10.13.0" } }, - "node_modules/postcss-svgo/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, "node_modules/postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", "dependencies": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" + "postcss-selector-parser": "^6.0.5" }, "engines": { - "node": ">=6.9.0" + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/postcss-value-parser": { @@ -18743,36 +15904,21 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, - "node_modules/postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "dependencies": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">=6.14.4" - } - }, - "node_modules/postcss/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "node_modules/postcss/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/prebuild-install": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz", - "integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", "dev": true, "dependencies": { "detect-libc": "^1.0.3", @@ -18781,15 +15927,13 @@ "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", + "node-abi": "^2.21.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" @@ -18806,14 +15950,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -18826,26 +15962,36 @@ } }, "node_modules/pretty-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "dependencies": { "lodash": "^4.17.20", - "renderkid": "^2.0.4" + "renderkid": "^3.0.0" } }, "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "engines": { - "node": ">= 10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/pretty-format/node_modules/react-is": { @@ -18853,14 +15999,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -18870,27 +16008,23 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.2.0.tgz", + "integrity": "sha512-+CMAlLHqwRYwBMXKCP+o8ns7DN+xHDUiI+0nArsiJ9y+kJVPLFxEaSw6Ha9s9H0tftxg2Yzl25wqj9G7m5wLZg==", "dependencies": { "asap": "~2.0.6" } }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, "node_modules/prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -18900,9 +16034,9 @@ } }, "node_modules/prop-types": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.0.tgz", - "integrity": "sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -18955,33 +16089,10 @@ "node": ">= 0.10" } }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "node_modules/pump": { "version": "3.0.0", @@ -18992,58 +16103,6 @@ "once": "^1.3.1" } }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/pumpify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -19055,47 +16114,24 @@ "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "engines": { "node": ">=0.6.0", "teleport": ">=0.2.0" } }, "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "side-channel": "^1.0.4" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "engines": { - "node": ">=0.4.x" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/querystringify": { @@ -19147,15 +16183,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -19165,12 +16192,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -19178,6 +16205,14 @@ "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -19196,221 +16231,79 @@ "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=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-app-polyfill": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz", - "integrity": "sha512-0sF4ny9v/B7s6aoehwze9vJNWcmCemAUYBVasscVr92+UYiEqDXOxfKjXN685mDaMRNF3WdhHQs76oTODMocFA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", "dependencies": { - "core-js": "^3.6.5", + "core-js": "^3.19.2", "object-assign": "^4.1.1", "promise": "^8.1.0", "raf": "^3.4.1", - "regenerator-runtime": "^0.13.7", - "whatwg-fetch": "^3.4.1" + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" }, "engines": { - "node": ">=10" + "node": ">=14" } }, "node_modules/react-dev-utils": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", - "integrity": "sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==", - "dependencies": { - "@babel/code-frame": "7.10.4", - "address": "1.1.2", - "browserslist": "4.14.2", - "chalk": "2.4.2", - "cross-spawn": "7.0.3", - "detect-port-alt": "1.1.6", - "escape-string-regexp": "2.0.0", - "filesize": "6.1.0", - "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "4.1.6", - "global-modules": "2.0.0", - "globby": "11.0.1", - "gzip-size": "5.1.1", - "immer": "8.0.1", - "is-root": "2.1.0", - "loader-utils": "2.0.0", - "open": "^7.0.2", - "pkg-up": "3.1.0", - "prompts": "2.4.0", - "react-error-overlay": "^6.0.9", - "recursive-readdir": "2.2.2", - "shell-quote": "1.7.2", - "strip-ansi": "6.0.0", - "text-table": "0.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/react-dev-utils/node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/react-dev-utils/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/react-dev-utils/node_modules/browserslist": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", - "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", - "dependencies": { - "caniuse-lite": "^1.0.30001125", - "electron-to-chromium": "^1.3.564", - "escalade": "^3.0.2", - "node-releases": "^1.1.61" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/react-dev-utils/node_modules/chalk/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/react-dev-utils/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/react-dev-utils/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "engines": { - "node": ">=4" + "node": ">=14" } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/react-dev-utils/node_modules/node-releases": { - "version": "1.1.77", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", - "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==" - }, - "node_modules/react-dev-utils/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", + "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", "engines": { - "node": ">=4" + "node": ">= 12.13.0" } }, "node_modules/react-div-100vh": { @@ -19422,22 +16315,21 @@ } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.0" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.2.0" } }, "node_modules/react-error-overlay": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.10.tgz", - "integrity": "sha512-mKR90fX7Pm5seCOfz8q9F+66VCc1PGsWSBxKbITjfKVQHMNF2zudxHnMdJiB1fRCb+XsbQV9sO9DCkgsMQgBIA==" + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "node_modules/react-is": { "version": "16.13.1", @@ -19445,19 +16337,20 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-markdown": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-7.1.0.tgz", - "integrity": "sha512-hL8cLLkTydyoKlZWZOjlU6TvMYIw9qKLh1CCzVfnhKt/R/SnKVAqiyugetXY61CkjhBqJl2C5FdU3OwHYo7SrQ==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz", + "integrity": "sha512-We36SfqaKoVNpN1QqsZwWSv/OZt5J15LNgTLWynwAN5b265hrQrsjMtlRNwUvS+YyR3yDM8HpTNc4pK9H/Gc0A==", "dependencies": { "@types/hast": "^2.0.0", + "@types/prop-types": "^15.0.0", "@types/unist": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^2.0.0", "prop-types": "^15.0.0", "property-information": "^6.0.0", - "react-is": "^17.0.0", + "react-is": "^18.0.0", "remark-parse": "^10.0.0", - "remark-rehype": "^9.0.0", + "remark-rehype": "^10.0.0", "space-separated-tokens": "^2.0.0", "style-to-object": "^0.3.0", "unified": "^10.0.0", @@ -19474,14 +16367,14 @@ } }, "node_modules/react-markdown/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-query": { - "version": "3.33.5", - "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.33.5.tgz", - "integrity": "sha512-gNpTzbY9Xw/s0ALeLsXdUGXtzXbXQcRAMa4Ina2JOJHbDr2mdA79O2SMNUwctKJ1/c0vKTdALIdn4taptv+MTQ==", + "version": "3.39.2", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.2.tgz", + "integrity": "sha512-F6hYDKyNgDQfQOuR1Rsp3VRzJnWHx6aRnnIZHMNGGgbL3SBgpZTDg8MQwmxOgpCAoqZJA+JSNCydF1xGJqKOCA==", "dependencies": { "@babel/runtime": "^7.5.5", "broadcast-channel": "^3.4.1", @@ -19492,7 +16385,7 @@ "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "react-dom": { @@ -19504,17 +16397,17 @@ } }, "node_modules/react-refresh": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", - "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "engines": { "node": ">=0.10.0" } }, "node_modules/react-router": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz", - "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.3.tgz", + "integrity": "sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w==", "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -19532,15 +16425,15 @@ } }, "node_modules/react-router-dom": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz", - "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-Ov0tGPMBgqmbu5CDmN++tv2HQ9HlWDuWIIqn4b88gjlAN5IHI+4ZUZRcpz9Hl0azFIwihbLDYw1OiHGRo7ZIng==", "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", "loose-envify": "^1.3.1", "prop-types": "^15.6.2", - "react-router": "5.2.1", + "react-router": "5.3.3", "tiny-invariant": "^1.0.2", "tiny-warning": "^1.0.0" }, @@ -19551,7 +16444,7 @@ "node_modules/react-router/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "node_modules/react-router/node_modules/path-to-regexp": { "version": "1.8.0", @@ -19561,10 +16454,95 @@ "isarray": "0.0.1" } }, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "dependencies": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/react-scripts/node_modules/fs-extra": { + "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==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/react-transition-group": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", - "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -19576,10 +16554,19 @@ "react-dom": ">=16.6.0" } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", @@ -19594,6 +16581,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, "dependencies": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", @@ -19606,10 +16594,63 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/read-pkg-up/node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, "engines": { "node": ">=8" } @@ -19617,12 +16658,14 @@ "node_modules/read-pkg/node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true }, "node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -19634,6 +16677,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, "bin": { "semver": "bin/semver" } @@ -19642,6 +16686,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, "engines": { "node": ">=8" } @@ -19660,15 +16705,22 @@ } }, "node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { - "picomatch": "^2.0.4" + "picomatch": "^2.2.1" }, "engines": { - "node": ">= 8" + "node": ">=8.10.0" + } + }, + "node_modules/reconnecting-eventsource": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/reconnecting-eventsource/-/reconnecting-eventsource-1.5.2.tgz", + "integrity": "sha512-8XQETFzf/W06Pl6njey8Jmw7Zyi6lWOAfZTrSwqBZRhb3+m50DFIap0Hgn4nOHBmh1T6wJpP0M5BYyX7OMf/QA==", + "engines": { + "node": ">=12.0.0" } }, "node_modules/recursive-readdir": { @@ -19682,6 +16734,17 @@ "node": ">=0.10.0" } }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -19710,9 +16773,9 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dependencies": { "regenerate": "^1.4.2" }, @@ -19726,34 +16789,22 @@ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "node_modules/regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", "dependencies": { "@babel/runtime": "^7.8.4" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regex-parser": { "version": "2.2.11", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" }, "node_modules/regexp-ast-analysis": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.3.0.tgz", - "integrity": "sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.5.1.tgz", + "integrity": "sha512-Ca/g9gaTNuMewLuu+mBIq4vCrGRSO8AE9bP32NMQjJ/wBTdWq0g96qLkBb0NbGwEbp7S/q+NQF3o7veeuRfg0g==", "dev": true, "dependencies": { "refa": "^0.9.0", @@ -19761,12 +16812,13 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -19787,14 +16839,14 @@ } }, "node_modules/regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" }, @@ -19802,24 +16854,15 @@ "node": ">=4" } }, - "node_modules/regextras": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", - "dev": true, - "engines": { - "node": ">=0.1.14" - } - }, "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" }, "node_modules/regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dependencies": { "jsesc": "~0.5.0" }, @@ -19830,15 +16873,15 @@ "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "bin": { "jsesc": "bin/jsesc" } }, "node_modules/rehype-raw": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.0.tgz", - "integrity": "sha512-12j2UiiYJgZFdjnHDny77NY5BF3eW4Jsl0vtgL1DWdTzcHjPpbhumU+GtPUdivEWwQc8x9OdEuO0oxaGz7Tvyg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", + "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", "dependencies": { "@types/hast": "^2.0.0", "hast-util-raw": "^7.2.0", @@ -19852,12 +16895,12 @@ "node_modules/reinterval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", - "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "engines": { "node": ">= 0.10" } @@ -19892,13 +16935,13 @@ } }, "node_modules/remark-rehype": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-9.1.0.tgz", - "integrity": "sha512-oLa6YmgAYg19zb0ZrBACh40hpBLteYROaPLhBXzLgjqyHQrN+gVP9N/FJvfzuNNuzCutktkroXEZBrxAxKhh7Q==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", + "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", "dependencies": { "@types/hast": "^2.0.0", "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^11.0.0", + "mdast-util-to-hast": "^12.1.0", "unified": "^10.0.0" }, "funding": { @@ -19909,64 +16952,24 @@ "node_modules/remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" }, "node_modules/renderkid": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", - "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", "htmlparser2": "^6.1.0", "lodash": "^4.17.21", - "strip-ansi": "^3.0.1" - } - }, - "node_modules/renderkid/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/renderkid/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "engines": { - "node": ">=0.10" + "strip-ansi": "^6.0.1" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } @@ -19979,11 +16982,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, "node_modules/requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -19996,15 +16994,19 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -20042,152 +17044,45 @@ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated" - }, "node_modules/resolve-url-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz", - "integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==", - "dependencies": { - "adjust-sourcemap-loader": "3.0.0", - "camelcase": "5.3.1", - "compose-function": "3.0.3", - "convert-source-map": "1.7.0", - "es6-iterator": "2.0.3", - "loader-utils": "1.2.3", - "postcss": "7.0.36", - "rework": "1.0.1", - "rework-visit": "1.0.0", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/resolve-url-loader/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url-loader/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-url-loader/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" }, "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url-loader/node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" + "node": ">=8.9" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url-loader/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/resolve-url-loader/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/resolve-url-loader/node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/resolve-url-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=", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/resolve-url-loader/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/resolve-url-loader/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url-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==", - "dependencies": { - "minimist": "^1.2.0" + "peerDependencies": { + "rework": "1.0.1", + "rework-visit": "1.0.0" }, - "bin": { - "json5": "lib/cli.js" + "peerDependenciesMeta": { + "rework": { + "optional": true + }, + "rework-visit": { + "optional": true + } } }, - "node_modules/resolve-url-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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } + "node_modules/resolve-url-loader/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" }, "node_modules/resolve-url-loader/node_modules/postcss": { - "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "dependencies": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "picocolors": "^0.2.1", + "source-map": "^0.6.1" }, "engines": { "node": ">=6.0.0" @@ -20197,23 +17092,12 @@ "url": "https://opencollective.com/postcss/" } }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-url-loader/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dependencies": { - "has-flag": "^3.0.0" - }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/restore-cursor": { @@ -20229,18 +17113,10 @@ "node": ">=8" } }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "engines": { "node": ">= 4" } @@ -20254,34 +17130,10 @@ "node": ">=0.10.0" } }, - "node_modules/rework": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", - "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", - "dependencies": { - "convert-source-map": "^0.3.3", - "css": "^2.0.0" - } - }, - "node_modules/rework-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", - "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=" - }, - "node_modules/rework/node_modules/convert-source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", - "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" - }, - "node_modules/rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" - }, - "node_modules/rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "node_modules/rifm": { "version": "0.12.1", @@ -20305,75 +17157,45 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", - "dependencies": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" - }, + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "bin": { "rollup": "dist/bin/rollup" - } - }, - "node_modules/rollup-plugin-babel": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz", - "integrity": "sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-babel.", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "rollup-pluginutils": "^2.8.1" }, - "peerDependencies": { - "@babel/core": "7 || ^7.0.0-rc.2", - "rollup": ">=0.60.0 <3" + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, "node_modules/rollup-plugin-terser": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz", - "integrity": "sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", "dependencies": { - "@babel/code-frame": "^7.5.5", - "jest-worker": "^24.9.0", - "rollup-pluginutils": "^2.8.2", + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", "serialize-javascript": "^4.0.0", - "terser": "^4.6.2" + "terser": "^5.0.0" }, "peerDependencies": { - "rollup": ">=0.66.0 <3" - } - }, - "node_modules/rollup-plugin-terser/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" + "rollup": "^2.0.0" } }, "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dependencies": { + "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" + "supports-color": "^7.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 10.13.0" } }, "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { @@ -20384,38 +17206,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "engines": { - "node": "6.* || >= 7.*" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -20438,23 +17228,15 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dependencies": { - "aproba": "^1.1.1" - } - }, "node_modules/sade": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.4.tgz", - "integrity": "sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "dependencies": { "mri": "^1.1.0" }, "engines": { - "node": ">= 6" + "node": ">=6" } }, "node_modules/safe-buffer": { @@ -20462,12 +17244,17 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dependencies": { - "ret": "~0.1.10" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/safer-buffer": { @@ -20475,296 +17262,21 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/sane/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sane/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sane/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } - }, - "node_modules/sane/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/sane/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/sanitize.css": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", - "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" }, "node_modules/sass-loader": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.2.0.tgz", - "integrity": "sha512-kUceLzC1gIHz0zNJPpqRsJyisWatGYNFRmv2CKZK2/ngMJgLqxTbXwe/hJ85luyvZkgqU3VlJ33UVF2T/0g6mw==", + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", "dependencies": { "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "neo-async": "^2.6.2" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -20772,9 +17284,10 @@ }, "peerDependencies": { "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "sass": "^1.3.0", - "webpack": "^4.36.0 || ^5.0.0" + "sass-embedded": "*", + "webpack": "^5.0.0" }, "peerDependenciesMeta": { "fibers": { @@ -20785,39 +17298,12 @@ }, "sass": { "optional": true + }, + "sass-embedded": { + "optional": true } } }, - "node_modules/sass-loader/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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/sass-loader/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", @@ -20835,25 +17321,24 @@ } }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" }, "engines": { - "node": ">= 8.9.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -20884,14 +17369,17 @@ "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" }, "node_modules/selfsigned": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", - "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", "dependencies": { - "node-forge": "^0.10.0" + "node-forge": "^1" + }, + "engines": { + "node": ">=10" } }, "node_modules/semaphore": { @@ -20903,9 +17391,9 @@ } }, "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -20917,23 +17405,23 @@ } }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -20950,40 +17438,17 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/send/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/send/node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dependencies": { "randombytes": "^2.1.0" } @@ -20991,7 +17456,7 @@ "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -21013,10 +17478,18 @@ "ms": "2.0.0" } }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -21030,27 +17503,35 @@ "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "node_modules/serve-index/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==" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -21059,83 +17540,34 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "kind-of": "^6.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dependencies": { - "is-extendable": "^0.1.0" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" + "node": ">=8" } }, "node_modules/shebang-regex": { @@ -21147,15 +17579,9 @@ } }, "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" - }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "optional": true + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" }, "node_modules/should": { "version": "13.2.3", @@ -21182,7 +17608,7 @@ "node_modules/should-format": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, "dependencies": { "should-type": "^1.3.0", @@ -21192,7 +17618,7 @@ "node_modules/should-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "dev": true }, "node_modules/should-type-adaptors": { @@ -21225,9 +17651,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -21260,19 +17686,6 @@ "simple-concat": "^1.0.0" } }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -21286,202 +17699,6 @@ "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -21492,36 +17709,12 @@ "websocket-driver": "^0.7.4" } }, - "node_modules/sockjs-client": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz", - "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==", - "dependencies": { - "debug": "^3.2.6", - "eventsource": "^1.0.7", - "faye-websocket": "^0.11.3", - "inherits": "^2.0.4", - "json3": "^3.3.3", - "url-parse": "^1.5.3" - } - }, - "node_modules/sockjs-client/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/source-list-map": { @@ -21530,31 +17723,50 @@ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, "node_modules/source-map-js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", - "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "node_modules/source-map-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.1.tgz", + "integrity": "sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA==", + "dependencies": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/source-map-support": { @@ -21566,19 +17778,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" - }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -21597,6 +17796,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -21605,21 +17805,24 @@ "node_modules/spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true }, "node_modules/spdy": { "version": "4.0.2", @@ -21649,17 +17852,6 @@ "wbuf": "^1.7.3" } }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -21671,23 +17863,13 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" }, "node_modules/stack-utils": { "version": "2.0.5", @@ -21709,185 +17891,23 @@ } }, "node_modules/stackframe": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", - "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stream-browserify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stream-http/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-meter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", - "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=", - "dev": true, + "node_modules/stream-meter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", + "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==", + "dev": true, "dependencies": { "readable-stream": "^2.1.4" } @@ -21921,14 +17941,6 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -21974,30 +17986,52 @@ "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/string.prototype.matchall": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", - "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", + "regexp.prototype.flags": "^1.4.1", "side-channel": "^1.0.4" }, "funding": { @@ -22005,24 +18039,26 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -22061,23 +18097,11 @@ } }, "node_modules/strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "dependencies": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, "node_modules/strip-final-newline": { @@ -22112,35 +18136,18 @@ } }, "node_modules/style-loader": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", - "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^2.7.0" - }, + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", "engines": { - "node": ">= 8.9.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/style-loader/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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" + "webpack": "^5.0.0" } }, "node_modules/style-to-object": { @@ -22152,29 +18159,18 @@ } }, "node_modules/stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", + "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/stylehacks/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node": "^10 || ^12 || >=14.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "postcss": "^8.2.15" } }, "node_modules/stylis": { @@ -22194,9 +18190,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -22205,6 +18201,17 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/svg-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", @@ -22248,6 +18255,14 @@ "node": ">=4" } }, + "node_modules/svgo/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/svgo/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -22272,7 +18287,7 @@ "node_modules/svgo/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/svgo/node_modules/css-select": { "version": "2.1.0", @@ -22322,7 +18337,7 @@ "node_modules/svgo/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } @@ -22330,11 +18345,23 @@ "node_modules/svgo/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } }, + "node_modules/svgo/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/svgo/node_modules/nth-check": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", @@ -22387,6 +18414,13 @@ "openapi-types": ">=7" } }, + "node_modules/swagger-jsdoc/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true + }, "node_modules/swagger-jsdoc/node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -22453,19 +18487,19 @@ "node_modules/swagger-schema-official": { "version": "2.0.0-bab6bed", "resolved": "https://registry.npmjs.org/swagger-schema-official/-/swagger-schema-official-2.0.0-bab6bed.tgz", - "integrity": "sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0=" + "integrity": "sha512-rCC0NWGKr/IJhtRuPq/t37qvZHI/mH4I4sxflVM+qgVe5Z2uOCivzWaVbuioJaB61kvm5UvB7b49E+oBY0M8jA==" }, "node_modules/swagger-ui-dist": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.1.3.tgz", - "integrity": "sha512-WvfPSfAAMlE/sKS6YkW47nX/hA7StmhYnAHc6wWCXNL0oclwLj6UXv0hQCkLnDgvebi0MEV40SJJpVjKUgH1IQ==" + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.3.tgz", + "integrity": "sha512-Y7Sta24I9r+G6dX3ZTIq9Psr55cDC3myCB0E00ZnVkB0Wn3cO77NdLXSM0f90WZh9VpgTetKpMPR3n2VqKr+lQ==" }, "node_modules/swagger-ui-express": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.3.0.tgz", - "integrity": "sha512-jN46SEEe9EoXa3ZgZoKgnSF6z0w3tnM1yqhO4Y+Q4iZVc8JOQB960EZpIAz6rNROrDApVDwcMHR0mhlnc/5Omw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.5.0.tgz", + "integrity": "sha512-DHk3zFvsxrkcnurGvQlAcLuTDacAVN1JHKDgcba/gr2NFRE4HGwP1YeHIXMiGznkWR4AeS7X5vEblNn4QljuNA==", "dependencies": { - "swagger-ui-dist": ">=4.1.3" + "swagger-ui-dist": ">=4.11.0" }, "engines": { "node": ">= v0.10.32" @@ -22479,65 +18513,64 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, - "node_modules/table": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", - "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "node_modules/tailwindcss": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", + "integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==", + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.14", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "5.0.6", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" }, "engines": { - "node": ">=10.0.0" + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", - "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "node_modules/tailwindcss/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/table/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==" - }, "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "engines": { "node": ">=6" } }, - "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -22566,52 +18599,40 @@ "node": ">=6" } }, - "node_modules/tar/node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/tempy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", - "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", "dependencies": { - "temp-dir": "^1.0.0", - "type-fest": "^0.3.1", - "unique-string": "^1.0.0" + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/tempy/node_modules/type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/terminal-link": { @@ -22630,35 +18651,32 @@ } }, "node_modules/terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" + "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" }, "engines": { - "node": ">=6.0.0" + "node": ">=10" } }, "node_modules/terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", + "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", "dependencies": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" }, "engines": { "node": ">= 10.13.0" @@ -22668,145 +18686,24 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/terser-webpack-plugin/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser-webpack-plugin/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" + "webpack": "^5.1.0" }, - "engines": { - "node": ">=10" + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } } }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "node_modules/test-exclude": { "version": "6.0.0", @@ -22824,69 +18721,22 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" - }, "node_modules/tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "node_modules/tiny-typed-emitter": { "version": "2.1.0", @@ -22903,55 +18753,14 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "engines": { "node": ">=4" } }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -22964,38 +18773,31 @@ } }, "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { "node": ">=0.6" } }, - "node_modules/totalist": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-2.0.0.tgz", - "integrity": "sha512-+Y17F0YzxfACxTyjfhnJQEe7afPA0GSpYlFkl2VFMxYP7jshQf9gXV7cH47EfToBumFThfKBvfAcoUn6fdNeRQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "engines": { "node": ">=6" } }, "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "engines": { "node": ">= 4.0.0" } @@ -23003,13 +18805,25 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, "node_modules/traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/trim-newlines": { "version": "3.0.1", @@ -23021,9 +18835,9 @@ } }, "node_modules/trough": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", - "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -23034,27 +18848,14 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, - "node_modules/ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", - "engines": { - "node": ">=6" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", - "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.1", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, @@ -23072,7 +18873,7 @@ "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "engines": { "node": ">=4" } @@ -23082,15 +18883,24 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -23099,11 +18909,6 @@ "node": "*" } }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -23149,7 +18954,7 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", @@ -23160,9 +18965,10 @@ } }, "node_modules/typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -23171,14 +18977,27 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz", + "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { @@ -23214,17 +19033,17 @@ } }, "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "engines": { "node": ">=4" } }, "node_modules/unified": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.1.tgz", - "integrity": "sha512-v4ky1+6BN9X3pQrOdkFIPWAaeDsHPE1svRDxq7YpTc2plkIqFMwukfqM+l0ewpP9EfwARlt9pPFAeWYhHm8X9w==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", "dependencies": { "@types/unist": "^2.0.0", "bail": "^2.0.0", @@ -23262,9 +19081,9 @@ } }, "node_modules/unified/node_modules/is-plain-obj": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", - "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "engines": { "node": ">=12" }, @@ -23272,63 +19091,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "node_modules/uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, "node_modules/unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dependencies": { - "crypto-random-string": "^1.0.0" + "crypto-random-string": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/unist-builder": { @@ -23362,18 +19133,21 @@ } }, "node_modules/unist-util-position": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", - "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.3.tgz", + "integrity": "sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==", + "dependencies": { + "@types/unist": "^2.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-stringify-position": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", - "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", + "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", "dependencies": { "@types/unist": "^2.0.0" }, @@ -23383,13 +19157,13 @@ } }, "node_modules/unist-util-visit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.0.tgz", - "integrity": "sha512-n7lyhFKJfVZ9MnKtqbsqkQEk5P1KShj0+//V7mAcoI6bpbUjh3C/OG8HVD+pBihfh6Ovl01m8dkcv9HNqYajmQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.1.tgz", + "integrity": "sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" + "unist-util-visit-parents": "^5.1.1" }, "funding": { "type": "opencollective", @@ -23397,22 +19171,9 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz", - "integrity": "sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz", + "integrity": "sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -23442,7 +19203,7 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } @@ -23450,51 +19211,7 @@ "node_modules/unquote": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "engines": { - "node": ">=0.10.0" - } + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" }, "node_modules/upath": { "version": "1.2.0", @@ -23505,9 +19222,34 @@ "yarn": "*" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/upx": { - "version": "1.0.7", - "resolved": "git+https://npm@github.com/Hypfer/upx.git#b63b801e430b1a37f8d43c3bc738c6d8ea2e37ff", + "version": "1.0.11", + "resolved": "git+https://npm@github.com/Hypfer/upx.git#677da177d9bcf6e0172adfbf00f4563e943fade2", "dev": true, "license": "MIT", "dependencies": { @@ -23522,77 +19264,6 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated" - }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/url-loader/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==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -23602,86 +19273,75 @@ "requires-port": "^1.0.0" } }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "node_modules/url/node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "node_modules/use-long-press": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/use-long-press/-/use-long-press-2.0.2.tgz", + "integrity": "sha512-zQ4sujilCykA7fSZ+m2gDuGw5aW3Gm3M4pulRH4e8c4mGXw8MDQIMthCsHiolxpt/hCe/BbIvd/iDn9XNDzkYg==", "engines": { - "node": ">=0.10.0" + "node": ">=10", + "npm": ">=5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dependencies": { - "inherits": "2.0.3" + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", "dependencies": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, "node_modules/utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/uvu": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.2.tgz", - "integrity": "sha512-m2hLe7I2eROhh+tm3WE5cTo/Cv3WQA7Oc9f7JB6uWv+/zVKvfAm53bMyOoGOSZeQ7Ov2Fu9pLhFr7p07bnT20w==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", "dependencies": { "dequal": "^2.0.0", "diff": "^5.0.0", "kleur": "^4.0.3", - "sade": "^1.7.3", - "totalist": "^2.0.0" + "sade": "^1.7.3" }, "bin": { "uvu": "bin.js" @@ -23690,38 +19350,33 @@ "node": ">=8" } }, - "node_modules/uvu/node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/uvu/node_modules/kleur": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz", - "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "engines": { "node": ">=6" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, "node_modules/v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0", "source-map": "^0.7.3" }, "engines": { - "node": ">=10.10.0" + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" } }, "node_modules/valetudo-backend": { @@ -23735,12 +19390,13 @@ "node_modules/valid-url": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -23762,24 +19418,15 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } }, - "node_modules/vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/vfile": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.2.0.tgz", - "integrity": "sha512-ftCpb6pU8Jrzcqku8zE6N3Gi4/RkDhRwEXSWudzZzA2eEOn/cBpsfk9aulCUR+j1raRSAykYQap9u6j6rhUaCA==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", + "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -23805,9 +19452,9 @@ } }, "node_modules/vfile-message": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.0.tgz", - "integrity": "sha512-4QJbBk+DkPEhBXq3f260xSaWtjE4gPKOfulzfMFF8ZNwaPZieWsg3iVlcmF04+eebzpcpeXOOFMfrYzJHVYg+g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", + "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" @@ -23839,11 +19486,6 @@ "node": ">=4" } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -23872,332 +19514,15 @@ } }, "node_modules/watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" - } - }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", - "optional": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "optional": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "optional": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchpack-chokidar2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "optional": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack/node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "optional": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/watchpack/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "optional": true, + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dependencies": { - "picomatch": "^2.2.1" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": ">=8.10.0" + "node": ">=10.13.0" } }, "node_modules/wbuf": { @@ -24211,7 +19536,7 @@ "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "dependencies": { "defaults": "^1.0.3" @@ -24229,43 +19554,44 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, "node_modules/webpack": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", - "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", + "version": "5.74.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", + "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" }, "bin": { "webpack": "bin/webpack.js" }, "engines": { - "node": ">=6.11.5" + "node": ">=10.13.0" }, "funding": { "type": "opencollective", @@ -24274,88 +19600,122 @@ "peerDependenciesMeta": { "webpack-cli": { "optional": true - }, - "webpack-command": { - "optional": true } } }, "node_modules/webpack-dev-middleware": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", - "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dependencies": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" + "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==", + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "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", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/webpack-dev-server": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", - "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", - "dependencies": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", + "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.8", - "semver": "^6.3.0", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "sockjs-client": "^1.5.0", + "sockjs": "^0.3.24", "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" }, "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 6.11.5" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^4.37.0 || ^5.0.0" }, "peerDependenciesMeta": { "webpack-cli": { @@ -24363,4955 +19723,4239 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "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==", "dependencies": { - "color-convert": "^1.9.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=4" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/webpack-dev-server/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/webpack-dev-server/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", + "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "engines": { + "node": ">= 10" + } + }, + "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", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dependencies": { - "remove-trailing-separator": "^1.0.1" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/webpack-dev-server/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", + "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/webpack-dev-server/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.22.0" + }, + "peerDependencies": { + "webpack": "^4.44.2 || ^5.47.0" } }, - "node_modules/webpack-dev-server/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", "dependencies": { - "is-extendable": "^0.1.0" + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.13.0" } }, - "node_modules/webpack-dev-server/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "engines": { - "node": ">=6" + "node": ">=10.13.0" } }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } + "node_modules/webpack/node_modules/@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" }, - "node_modules/webpack-dev-server/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/webpack-dev-server/node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, "engines": { - "node": ">=6" + "node": ">=0.8.0" } }, - "node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "engines": { - "node": ">=6" + "node": ">=0.8.0" } }, - "node_modules/webpack-dev-server/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "dependencies": { - "color-name": "1.1.3" + "iconv-lite": "0.4.24" } }, - "node_modules/webpack-dev-server/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "node_modules/whatwg-fetch": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", + "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" }, - "node_modules/webpack-dev-server/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, - "node_modules/webpack-dev-server/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" } }, - "node_modules/webpack-dev-server/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dependencies": { - "is-extendable": "^0.1.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/webpack-dev-server/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dependencies": { - "locate-path": "^3.0.0" + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/webpack-dev-server/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "engines": { - "node": ">= 4.0" + "node": ">=0.10.0" } }, - "node_modules/webpack-dev-server/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/workbox-background-sync": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", + "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "idb": "^7.0.1", + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "node_modules/workbox-broadcast-update": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", + "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/workbox-build": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", + "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.5.4", + "workbox-broadcast-update": "6.5.4", + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-google-analytics": "6.5.4", + "workbox-navigation-preload": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-range-requests": "6.5.4", + "workbox-recipes": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", + "workbox-streams": "6.5.4", + "workbox-sw": "6.5.4", + "workbox-window": "6.5.4" + }, "engines": { - "node": ">=4" + "node": ">=10.0.0" } }, - "node_modules/webpack-dev-server/node_modules/import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dependencies": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/webpack-dev-server/node_modules/is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/webpack-dev-server/node_modules/is-binary-path": { + "node_modules/workbox-build/node_modules/tr46": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "punycode": "^2.1.0" } }, - "node_modules/webpack-dev-server/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, - "node_modules/webpack-dev-server/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" + "node_modules/workbox-cacheable-response": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "dependencies": { + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/workbox-core": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" + }, + "node_modules/workbox-expiration": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", + "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "idb": "^7.0.1", + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/workbox-google-analytics": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", + "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "workbox-background-sync": "6.5.4", + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/workbox-navigation-preload": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", + "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "node_modules/workbox-precaching": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", + "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/workbox-range-requests": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", + "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "node_modules/workbox-recipes": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", + "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "node_modules/workbox-routing": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "node_modules/workbox-strategies": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "node_modules/workbox-streams": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", + "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "engines": { - "node": ">=4" - } + "node_modules/workbox-sw": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", + "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "node_modules/workbox-webpack-plugin": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz", + "integrity": "sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==", "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.5.4" }, "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack-dev-server/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" } }, - "node_modules/webpack-dev-server/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", "dependencies": { - "safe-buffer": "~5.1.0" + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" } }, - "node_modules/webpack-dev-server/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/workbox-window": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", + "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.5.4" } }, - "node_modules/webpack-dev-server/node_modules/string-width/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } + "node_modules/workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true }, - "node_modules/webpack-dev-server/node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dependencies": { - "ansi-regex": "^4.1.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/webpack-dev-server/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/webpack-dev-server/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { - "has-flag": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/webpack-dev-server/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/webpack-dev-server/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "engines": { - "node": ">=6" + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "engines": { - "node": ">=6" + "node": ">=0.4" } }, - "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dependencies": { - "async-limiter": "~1.0.0" + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "2.0.0-1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", + "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==", + "dev": true, + "engines": { + "node": ">= 6" } }, - "node_modules/webpack-dev-server/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, - "node_modules/webpack-dev-server/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "engines": { + "node": ">=10" } }, - "node_modules/webpack-log": { + "node_modules/yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, "dependencies": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, - "node_modules/webpack-log/node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-log/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" + "node": ">=8" } }, - "node_modules/webpack-manifest-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", - "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { - "fs-extra": "^7.0.0", - "lodash": ">=3.5 <5", - "object.entries": "^1.1.0", - "tapable": "^1.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=6.11.5" - }, - "peerDependencies": { - "webpack": "2 || 3 || 4" + "node": ">=8" } }, - "node_modules/webpack-manifest-plugin/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "engines": { - "node": ">=6 <7 || >=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/webpack-manifest-plugin/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "node_modules/z-schema": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.4.tgz", + "integrity": "sha512-gm/lx3hDzJNcLwseIeQVm1UcwhWIKpSB4NqH89pTBtFns4k/HDHudsICtvG05Bvw/Mv3jMyk700y5dadueLHdA==", "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "validator": "^13.7.0" + }, "bin": { - "acorn": "bin/acorn" + "z-schema": "bin/z-schema" }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "node": ">=8.0.0" }, - "engines": { - "node": ">=0.10.0" + "optionalDependencies": { + "commander": "^2.20.3" } }, - "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "node_modules/z-schema/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true }, - "node_modules/webpack/node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "node_modules/zoo-ids": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/zoo-ids/-/zoo-ids-2.0.7.tgz", + "integrity": "sha512-qSyy++XHw9FYfUQQP8lun2Rzoc+YUDYhjCNNXgtuIdKSlHjGZYl4+c9GM3kmYKr7v+ZebuHKzCeOxnKSg+CSuA==" + }, + "node_modules/zustand": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.1.2.tgz", + "integrity": "sha512-gcRaKchcxFPbImrBb/BKgujOhHhik9YhVpIeP87ETT7uokEe2Szu7KkuZ9ghjtD+/KKkcrRNktR2AiLXPIbKIQ==", "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "use-sync-external-store": "1.2.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=12.7.0" + }, + "peerDependencies": { + "immer": ">=9.0", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "immer": { + "optional": true + }, + "react": { + "optional": true + } } }, - "node_modules/webpack/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" + "node_modules/zwitch": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", + "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + }, + "dependencies": { + "@agnoc/core": { + "version": "0.16.0-next.7", + "resolved": "https://registry.npmjs.org/@agnoc/core/-/core-0.16.0-next.7.tgz", + "integrity": "sha512-sA9M8laq+UmYYTMww1s1GPja9JSqVivIoQ/eesXxh0rWo0JPnU/qPEUgyOsShczGGPnNqRUMhE4t8BmZuQLV9Q==", + "requires": { + "debug": "^4.3.1", + "protobufjs": "^6.11.2", + "tiny-typed-emitter": "^2.0.3" } }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" + "@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "requires": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + } } }, - "node_modules/webpack/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" + "@apidevtools/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" } }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==" }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } + "@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" }, - "node_modules/webpack/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "engines": { - "node": ">=4" + "@apidevtools/swagger-parser": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", + "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "requires": { + "@apidevtools/json-schema-ref-parser": "^9.0.6", + "@apidevtools/openapi-schemas": "^2.0.4", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "z-schema": "^5.0.1" } }, - "node_modules/webpack/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "requires": { + "@babel/highlight": "^7.18.6" } }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "@babel/compat-data": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==" }, - "node_modules/webpack/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" + "@babel/core": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" }, - "bin": { - "rimraf": "bin.js" + "dependencies": { + "@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==" + }, + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@babel/eslint-parser": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", + "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "requires": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" }, - "engines": { - "node": ">= 4" + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, - "node_modules/webpack/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "@babel/generator": { + "version": "7.19.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", + "requires": { + "@babel/types": "^7.19.4", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, "dependencies": { - "randombytes": "^2.1.0" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@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==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } } }, - "node_modules/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "requires": { + "@babel/types": "^7.18.6" + }, + "dependencies": { + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/webpack/node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, "dependencies": { - "figgy-pudding": "^3.5.1" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/webpack/node_modules/terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "@babel/helper-compilation-targets": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "requires": { + "@babel/compat-data": "^7.19.3", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, - "node_modules/webpack/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" + "@babel/helper-create-class-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6" } }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" + "@babel/helper-create-regexp-features-plugin": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.1.0" } }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "requires": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, "dependencies": { - "iconv-lite": "0.4.24" + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, - "node_modules/whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, + "@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "requires": { + "@babel/types": "^7.18.6" + }, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "node_modules/which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "requires": { + "@babel/types": "^7.18.6" + }, "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "requires": { + "@babel/types": "^7.18.9" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "engines": { - "node": ">=0.10.0" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-background-sync": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz", - "integrity": "sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA==", + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-broadcast-update": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.1.4.tgz", - "integrity": "sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA==", + "@babel/helper-module-transforms": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-build": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-5.1.4.tgz", - "integrity": "sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow==", - "dependencies": { - "@babel/core": "^7.8.4", - "@babel/preset-env": "^7.8.4", - "@babel/runtime": "^7.8.4", - "@hapi/joi": "^15.1.0", - "@rollup/plugin-node-resolve": "^7.1.1", - "@rollup/plugin-replace": "^2.3.1", - "@surma/rollup-plugin-off-main-thread": "^1.1.1", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^8.1.0", - "glob": "^7.1.6", - "lodash.template": "^4.5.0", - "pretty-bytes": "^5.3.0", - "rollup": "^1.31.1", - "rollup-plugin-babel": "^4.3.3", - "rollup-plugin-terser": "^5.3.1", - "source-map": "^0.7.3", - "source-map-url": "^0.4.0", - "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "tempy": "^0.3.0", - "upath": "^1.2.0", - "workbox-background-sync": "^5.1.4", - "workbox-broadcast-update": "^5.1.4", - "workbox-cacheable-response": "^5.1.4", - "workbox-core": "^5.1.4", - "workbox-expiration": "^5.1.4", - "workbox-google-analytics": "^5.1.4", - "workbox-navigation-preload": "^5.1.4", - "workbox-precaching": "^5.1.4", - "workbox-range-requests": "^5.1.4", - "workbox-routing": "^5.1.4", - "workbox-strategies": "^5.1.4", - "workbox-streams": "^5.1.4", - "workbox-sw": "^5.1.4", - "workbox-window": "^5.1.4" + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "requires": { + "@babel/types": "^7.18.6" }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/workbox-build/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-build/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } + "@babel/helper-plugin-utils": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", + "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" }, - "node_modules/workbox-cacheable-response": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.1.4.tgz", - "integrity": "sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA==", + "@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-core": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.1.4.tgz", - "integrity": "sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg==" - }, - "node_modules/workbox-expiration": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.1.4.tgz", - "integrity": "sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ==", + "@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-google-analytics": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-5.1.4.tgz", - "integrity": "sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA==", + "@babel/helper-simple-access": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", + "requires": { + "@babel/types": "^7.19.4" + }, "dependencies": { - "workbox-background-sync": "^5.1.4", - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4", - "workbox-strategies": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-navigation-preload": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-5.1.4.tgz", - "integrity": "sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ==", + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "requires": { + "@babel/types": "^7.18.9" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-precaching": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-5.1.4.tgz", - "integrity": "sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA==", + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "requires": { + "@babel/types": "^7.18.6" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-range-requests": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-5.1.4.tgz", - "integrity": "sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw==", - "dependencies": { - "workbox-core": "^5.1.4" - } + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" }, - "node_modules/workbox-routing": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.1.4.tgz", - "integrity": "sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw==", + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + }, + "@babel/helper-wrap-function": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "requires": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.0", + "@babel/types": "^7.19.0" + }, "dependencies": { - "workbox-core": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-strategies": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.1.4.tgz", - "integrity": "sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA==", + "@babel/helpers": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.4", + "@babel/types": "^7.19.4" + }, "dependencies": { - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4" + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "node_modules/workbox-streams": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-5.1.4.tgz", - "integrity": "sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw==", + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, "dependencies": { - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4" + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "node_modules/workbox-sw": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-5.1.4.tgz", - "integrity": "sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA==" + "@babel/parser": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.10.tgz", + "integrity": "sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==" }, - "node_modules/workbox-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-PZafF4HpugZndqISi3rZ4ZK4A4DxO8rAqt2FwRptgsDx7NF8TVKP86/huHquUsRjMGQllsNdn4FNl8CD/UvKmQ==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "fast-json-stable-stringify": "^2.0.0", - "source-map-url": "^0.4.0", - "upath": "^1.1.2", - "webpack-sources": "^1.3.0", - "workbox-build": "^5.1.4" - }, - "engines": { - "node": ">=8.0.0" - }, - "peerDependencies": { - "webpack": "^4.0.0" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/workbox-window": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-5.1.4.tgz", - "integrity": "sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw==", - "dependencies": { - "workbox-core": "^5.1.4" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" } }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dependencies": { - "errno": "~0.1.7" + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, - "node_modules/worker-rpc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", - "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", - "dependencies": { - "microevent.ts": "~0.1.1" + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" + "@babel/plugin-proposal-class-static-block": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "@babel/plugin-proposal-decorators": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz", + "integrity": "sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/plugin-syntax-decorators": "^7.19.0" } }, - "node_modules/ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yaml": { - "version": "2.0.0-1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", - "integrity": "sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==", - "dev": true, - "engines": { - "node": ">= 6" + "@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, - "node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, - "node_modules/yargs-unparser/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", + "requires": { + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.18.8" } }, - "node_modules/yargs-unparser/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" + "@babel/plugin-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, - "node_modules/yargs-unparser/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/yargs-unparser/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, - "node_modules/yargs-unparser/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/yargs-unparser/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/yargs-unparser/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/yargs-unparser/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/yargs-unparser/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/yargs-unparser/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" } }, - "node_modules/yargs-unparser/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/yargs-unparser/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-syntax-decorators": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", + "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" } }, - "node_modules/yargs-unparser/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/yargs-unparser/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" } }, - "node_modules/yargs-unparser/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/yargs-unparser/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "@babel/plugin-syntax-flow": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", + "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/yargs/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" + "@babel/plugin-syntax-import-assertions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/z-schema": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.2.tgz", - "integrity": "sha512-40TH47ukMHq5HrzkeVE40Ad7eIDKaRV2b+Qpi2prLc9X9eFJFzV7tMe5aH12e6avaSS/u5l653EQOv+J9PirPw==", - "dependencies": { - "lodash.get": "^4.4.2", - "lodash.isequal": "^4.5.0", - "validator": "^13.7.0" - }, - "bin": { - "z-schema": "bin/z-schema" - }, - "engines": { - "node": ">=8.0.0" - }, - "optionalDependencies": { - "commander": "^2.7.1" + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/zoo-ids": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/zoo-ids/-/zoo-ids-2.0.7.tgz", - "integrity": "sha512-qSyy++XHw9FYfUQQP8lun2Rzoc+YUDYhjCNNXgtuIdKSlHjGZYl4+c9GM3kmYKr7v+ZebuHKzCeOxnKSg+CSuA==" - }, - "node_modules/zwitch": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", - "integrity": "sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - }, - "dependencies": { - "@agnoc/core": { - "version": "0.16.0-next.7", - "resolved": "https://registry.npmjs.org/@agnoc/core/-/core-0.16.0-next.7.tgz", - "integrity": "sha512-sA9M8laq+UmYYTMww1s1GPja9JSqVivIoQ/eesXxh0rWo0JPnU/qPEUgyOsShczGGPnNqRUMhE4t8BmZuQLV9Q==", + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "requires": { - "debug": "^4.3.1", - "protobufjs": "^6.11.2", - "tiny-typed-emitter": "^2.0.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@apidevtools/json-schema-ref-parser": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", - "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "requires": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.6", - "call-me-maybe": "^1.0.1", - "js-yaml": "^4.1.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - } + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@apidevtools/openapi-schemas": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", - "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==" - }, - "@apidevtools/swagger-methods": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", - "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==" - }, - "@apidevtools/swagger-parser": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz", - "integrity": "sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==", + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "requires": { - "@apidevtools/json-schema-ref-parser": "^9.0.6", - "@apidevtools/openapi-schemas": "^2.0.4", - "@apidevtools/swagger-methods": "^3.0.2", - "@jsdevtools/ono": "^7.1.3", - "call-me-maybe": "^1.0.1", - "z-schema": "^5.0.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "requires": { - "@babel/highlight": "^7.10.4" + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/compat-data": { - "version": "7.16.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", - "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==" - }, - "@babel/core": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.5.tgz", - "integrity": "sha512-wUcenlLzuWMZ9Zt8S0KmFwGlH6QKRh3vsm/dhDA3CHkiTA45YuG1XkHRcNRl73EFPXDp/d5kVOU0/y7x2w6OaQ==", + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helpers": "^7.16.5", - "@babel/parser": "^7.16.5", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "requires": { - "@babel/highlight": "^7.16.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.5.tgz", - "integrity": "sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==", + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "requires": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } + "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.5.tgz", - "integrity": "sha512-3JEA9G5dmmnIWdzaT9d0NmFRgYnWUThLsDaL7982H0XqqWr56lRrsmwheXFMjR+TMl7QMBb6mzy9kvgr1lRLUA==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "requires": { - "@babel/helper-explode-assignable-expression": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/helper-compilation-targets": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz", - "integrity": "sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA==", + "@babel/plugin-syntax-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.17.5", - "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==" - } + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-create-class-features-plugin": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.5.tgz", - "integrity": "sha512-NEohnYA7mkB8L5JhU7BLwcBdU3j83IziR9aseMueWGeAjblbul3zzb8UvJ3a1zuBiqCMObzCJHFqKIQE6hTVmg==", + "@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz", - "integrity": "sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==", + "@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "regexpu-core": "^4.7.1" + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" } }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz", - "integrity": "sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg==", + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "requires": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-environment-visitor": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.5.tgz", - "integrity": "sha512-ODQyc5AnxmZWm/R2W7fzhamOk1ey8gSguo5SGvF0zcB3uUzRpTRmM/jmLSm9bDMyPlvbyJ+PwPEK0BWIoZ9wjg==", + "@babel/plugin-transform-block-scoping": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz", + "integrity": "sha512-934S2VLLlt2hRJwPf4MczaOr4hYF0z+VKPwqTNxyKX7NthTiPfhuKFWQZHXRM0vh/wo/VyXB3s4bZUNA08l+tQ==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.19.0" } }, - "@babel/helper-explode-assignable-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz", - "integrity": "sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ==", - "requires": { - "@babel/types": "^7.16.0" + "@babel/plugin-transform-classes": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + } } }, - "@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", + "@babel/plugin-transform-computed-properties": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", + "@babel/plugin-transform-destructuring": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.19.4.tgz", + "integrity": "sha512-t0j0Hgidqf0aM86dF8U+vXYReUgJnlv4bZLsyoPnwZNrGY+7/38o8YjaELrvHeVfTZao15kjR0PVv0nju2iduA==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.19.0" } }, - "@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", + "@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.5.tgz", - "integrity": "sha512-7fecSXq7ZrLE+TWshbGT+HyCLkxloWNhTbU2QM1NTI/tDqyf0oZiMcEfYtDuUDCo528EOlt39G1rftea4bRZIw==", + "@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-module-transforms": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.5.tgz", - "integrity": "sha512-CkvMxgV4ZyyioElFwcuWnDCcNIeyqTkCm9BxXZi73RR1ozqlpboqsbGUNvRTflgZtFbbJ1v5Emvm+lkjMYY/LQ==", + "@babel/plugin-transform-flow-strip-types": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", + "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-flow": "^7.18.6" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz", - "integrity": "sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==", + "@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-plugin-utils": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz", - "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.5.tgz", - "integrity": "sha512-X+aAJldyxrOmN9v3FKp+Hu1NO69VWgYgDGq6YDykwRPzxs5f2N+X988CBXS7EQahDU+Vpet5QYMqLk+nsp+Qxw==", + "@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-wrap-function": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/helper-replace-supers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.5.tgz", - "integrity": "sha512-ao3seGVa/FZCMCCNDuBcqnBFSbdr8N2EW35mzojx3TwfIbdPmNK+JV6+2d5bR0Z71W5ocLnQp9en/cTF7pBJiQ==", + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "requires": { - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-member-expression-to-functions": "^7.16.5", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/helper-simple-access": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz", - "integrity": "sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw==", + "@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "@babel/plugin-transform-modules-amd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", + "@babel/plugin-transform-modules-commonjs": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==" - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==" - }, - "@babel/helper-wrap-function": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.5.tgz", - "integrity": "sha512-2J2pmLBqUqVdJw78U0KPNdeE2qeuIyKoG4mKV7wAq3mc4jJG282UgjZw4ZYDnqiWQuS3Y3IYdF/AQ6CpyBV3VA==", - "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/plugin-transform-modules-systemjs": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", + "requires": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.18.6", + "babel-plugin-dynamic-import-node": "^2.3.3" } }, - "@babel/helpers": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.5.tgz", - "integrity": "sha512-TLgi6Lh71vvMZGEkFuIxzaPsyeYCHQ5jJOOX1f0xXn0uciFuE8cEk0wyBquMcCxBXZ5BJhE2aUB7pnWTD150Tw==", + "@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "requires": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.5", - "@babel/types": "^7.16.0" + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/helper-create-regexp-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0" } }, - "@babel/parser": { - "version": "7.16.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz", - "integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==" - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.16.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz", - "integrity": "sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg==", + "@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz", - "integrity": "sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA==", + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" } }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.5.tgz", - "integrity": "sha512-C/FX+3HNLV6sz7AqbTQqEo1L9/kfrKjxcVtgyBCmvIgOjvuBVUWooDoi7trsLxOzCEo5FccjRvKHkfDsJFZlfA==", + "@babel/plugin-transform-parameters": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.5.tgz", - "integrity": "sha512-pJD3HjgRv83s5dv1sTnDbZOaTjghKEz8KUn1Kbh2eAIRhGuyQ1XSeI4xVXU3UlIEVA3DAyIdxqT1eRn7Wcn55A==", + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-class-static-block": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.5.tgz", - "integrity": "sha512-EEFzuLZcm/rNJ8Q5krK+FRKdVkd6FjfzT9tuSZql9sQn64K0hHA2KLJ0DqVot9/iV6+SsuadC5yI39zWnm+nmQ==", + "@babel/plugin-transform-react-constant-elements": { + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.12.tgz", + "integrity": "sha512-Q99U9/ttiu+LMnRU8psd23HhvwXmKWDQIpocm0JKaICcZHnw+mdQbHm6xnSy7dOl8I5PELakYtNBubNQlBXbZw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/plugin-proposal-decorators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.16.5.tgz", - "integrity": "sha512-XAiZll5oCdp2Dd2RbXA3LVPlFyIRhhcQy+G34p9ePpl6mjFkbqHAYHovyw2j5mqUrlBf0/+MtOIJ3JGYtz8qaw==", + "@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-decorators": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.5.tgz", - "integrity": "sha512-P05/SJZTTvHz79LNYTF8ff5xXge0kk5sIIWAypcWgX4BTRUgyHc8wRxJ/Hk+mU0KXldgOOslKaeqnhthcDJCJQ==", + "@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.5.tgz", - "integrity": "sha512-i+sltzEShH1vsVydvNaTRsgvq2vZsfyrd7K7vPLUU/KgS0D5yZMe6uipM0+izminnkKrEfdUnz7CxMRb6oHZWw==", + "@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/plugin-transform-react-jsx": "^7.18.6" } }, - "@babel/plugin-proposal-json-strings": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.5.tgz", - "integrity": "sha512-QQJueTFa0y9E4qHANqIvMsuxM/qcLQmKttBACtPCQzGUEizsXDACGonlPiSwynHfOa3vNw0FPMVvQzbuXwh4SQ==", + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", + "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.5.tgz", - "integrity": "sha512-xqibl7ISO2vjuQM+MzR3rkd0zfNWltk7n9QhaD8ghMmMceVguYrNDt7MikRyj4J4v3QehpnrU8RYLnC7z/gZLA==", + "@babel/plugin-transform-regenerator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.18.6", + "regenerator-transform": "^0.15.0" } }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.5.tgz", - "integrity": "sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==", + "@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.5.tgz", - "integrity": "sha512-DvB9l/TcsCRvsIV9v4jxR/jVP45cslTVC0PMVHvaJhhNuhn2Y1SOhCSFlPK777qLB5wb8rVDaNoqMTyOqtY5Iw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/plugin-transform-runtime": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz", + "integrity": "sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA==", + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "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==" + } } }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.5.tgz", - "integrity": "sha512-UEd6KpChoyPhCoE840KRHOlGhEZFutdPDMGj+0I56yuTTOaT51GzmnEl/0uT41fB/vD2nT+Pci2KjezyE3HmUw==", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.5.tgz", - "integrity": "sha512-ihCMxY1Iljmx4bWy/PIMJGXN4NS4oUj1MKynwO07kiKms23pNvIn1DMB92DNB2R0EA882sw0VXIelYGdtF7xEQ==", + "@babel/plugin-transform-spread": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" } }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.5.tgz", - "integrity": "sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==", + "@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-proposal-private-methods": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.5.tgz", - "integrity": "sha512-+yFMO4BGT3sgzXo+lrq7orX5mAZt57DwUK6seqII6AcJnJOIhBJ8pzKH47/ql/d426uQ7YhN8DpUFirQzqYSUA==", + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.5.tgz", - "integrity": "sha512-+YGh5Wbw0NH3y/E5YMu6ci5qTDmAEVNoZ3I54aB6nVEOZ5BQ7QJlwKq5pYVucQilMByGn/bvX0af+uNaPRCabA==", + "@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-create-class-features-plugin": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.5.tgz", - "integrity": "sha512-s5sKtlKQyFSatt781HQwv1hoM5BQ9qRH30r+dK56OLDsHmV74mzwJNX7R1yMuE7VZKG5O6q/gmOGSAO6ikTudg==", + "@babel/plugin-transform-typescript": { + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", + "integrity": "sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-create-class-features-plugin": "^7.19.0", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-typescript": "^7.18.6" } }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.18.9" } }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/preset-env": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", + "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", + "requires": { + "@babel/compat-data": "^7.19.4", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.19.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.19.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.19.4", + "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.19.4", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.18.6", + "@babel/plugin-transform-modules-commonjs": "^7.18.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.0", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.19.4", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, - "@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" } }, - "@babel/plugin-syntax-decorators": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.16.5.tgz", - "integrity": "sha512-3CbYTXfflvyy8O819uhZcZSMedZG4J8yS/NLTc/8T24M9ke1GssTGvg8VZu3Yn2LU5IyQSv1CmPq0a9JWHXJwg==", + "@babel/preset-react": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", + "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-react-display-name": "^7.18.6", + "@babel/plugin-transform-react-jsx": "^7.18.6", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-pure-annotations": "^7.18.6" } }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "@babel/preset-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" } }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "@babel/runtime": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "regenerator-runtime": "^0.13.4" } }, - "@babel/plugin-syntax-flow": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.5.tgz", - "integrity": "sha512-Nrx+7EAJx1BieBQseZa2pavVH2Rp7hADK2xn7coYqVbWRu9C2OFizYcsKo6TrrqJkJl+qF/+Qqzrk/+XDu4GnA==", + "@babel/runtime-corejs3": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.4.tgz", + "integrity": "sha512-HzjQ8+dzdx7dmZy4DQ8KV8aHi/74AjEbBGTFutBmg/pd3dY5/q1sfuOGPTFGEytlQhWoeVXqcK5BwMgIkRkNDQ==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.4" } }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "dependencies": { + "@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==" + }, + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + } } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/traverse": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.4", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.19.4", + "@babel/types": "^7.19.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz", + "integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==" + }, + "@babel/types": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.4.tgz", + "integrity": "sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + } } }, - "@babel/plugin-syntax-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz", - "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==", + "@babel/types": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.10.tgz", + "integrity": "sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "@csstools/normalize.css": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", + "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" + }, + "@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" } }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.5.tgz", - "integrity": "sha512-/d4//lZ1Vqb4mZ5xTep3dDK888j7BGM/iKqBmndBaoYAFPlPKrGU608VVBz5JeyAb6YQDjRu1UKqj86UhwWVgw==", + "@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.5.tgz", - "integrity": "sha512-8bTHiiZyMOyfZFULjsCnYOWG059FVMes0iljEHSfARhNgFfpsqE92OrCffv3veSw9rwMkYcFe9bj0ZoXU2IGtQ==", + "@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.5.tgz", - "integrity": "sha512-TMXgfioJnkXU+XRoj7P2ED7rUm5jbnDWwlCuFVTpQboMfbSya5WrmubNBAMlk7KXvywpo8rd8WuYZkis1o2H8w==", + "@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-remap-async-to-generator": "^7.16.5" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.5.tgz", - "integrity": "sha512-BxmIyKLjUGksJ99+hJyL/HIxLIGnLKtw772zYDER7UuycDZ+Xvzs98ZQw6NGgM2ss4/hlFAaGiZmMNKvValEjw==", + "@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-transform-block-scoping": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.5.tgz", - "integrity": "sha512-JxjSPNZSiOtmxjX7PBRBeRJTUKTyJ607YUYeT0QJCNdsedOe+/rXITjP08eG8xUpsLfPirgzdCFN+h0w6RI+pQ==", + "@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "postcss-value-parser": "^4.2.0" } }, - "@babel/plugin-transform-classes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.5.tgz", - "integrity": "sha512-DzJ1vYf/7TaCYy57J3SJ9rV+JEuvmlnvvyvYKFbk5u46oQbBvuB9/0w+YsVsxkOv8zVWKpDmUoj4T5ILHoXevA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5", - "@babel/helper-split-export-declaration": "^7.16.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - } - } + "@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==" }, - "@babel/plugin-transform-computed-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.5.tgz", - "integrity": "sha512-n1+O7xtU5lSLraRzX88CNcpl7vtGdPakKzww74bVwpAIRgz9JVLJJpOLb0uYqcOaXVM0TL6X0RVeIJGD2CnCkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@csstools/selector-specificity": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", + "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==" }, - "@babel/plugin-transform-destructuring": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.5.tgz", - "integrity": "sha512-GuRVAsjq+c9YPK6NeTkRLWyQskDC099XkBSVO+6QzbnOnH2d/4mBVXYStaPrZD3dFRfg00I6BFJ9Atsjfs8mlg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@date-io/core": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.16.0.tgz", + "integrity": "sha512-DYmSzkr+jToahwWrsiRA2/pzMEtz9Bq1euJwoOuYwuwIYXnZFtHajY2E6a1VNVDc9jP8YUXK1BvnZH9mmT19Zg==" }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.5.tgz", - "integrity": "sha512-iQiEMt8Q4/5aRGHpGVK2Zc7a6mx7qEAO7qehgSug3SDImnuMzgmm/wtJALXaz25zUj1PmnNHtShjFgk4PDx4nw==", + "@date-io/date-fns": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.16.0.tgz", + "integrity": "sha512-bfm5FJjucqlrnQcXDVU5RD+nlGmL3iWgkHTq3uAZWVIuBu6dDmGa3m8a6zo2VQQpu8ambq9H22UyUpn7590joA==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@date-io/core": "^2.16.0" } }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.5.tgz", - "integrity": "sha512-81tijpDg2a6I1Yhj4aWY1l3O1J4Cg/Pd7LfvuaH2VVInAkXtzibz9+zSPdUM1WvuUi128ksstAP0hM5w48vQgg==", + "@date-io/dayjs": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.16.0.tgz", + "integrity": "sha512-y5qKyX2j/HG3zMvIxTobYZRGnd1FUW2olZLS0vTj7bEkBQkjd2RO7/FEwDY03Z1geVGlXKnzIATEVBVaGzV4Iw==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@date-io/core": "^2.16.0" } }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.5.tgz", - "integrity": "sha512-12rba2HwemQPa7BLIKCzm1pT2/RuQHtSFHdNl41cFiC6oi4tcrp7gjB07pxQvFpcADojQywSjblQth6gJyE6CA==", + "@date-io/luxon": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.16.0.tgz", + "integrity": "sha512-L8UXHa/9VbfRqP4KB7JUZwFgOVxo22rONVod1o7GMN2Oku4PzJ0k1kXc+nLP9lRlF1UAA28oQsQqn85Y/PdBZw==", "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@date-io/core": "^2.16.0" } }, - "@babel/plugin-transform-flow-strip-types": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.5.tgz", - "integrity": "sha512-skE02E/MptkZdBS4HwoRhjWXqeKQj0BWKEAPfPC+8R4/f6bjQqQ9Nftv/+HkxWwnVxh/E2NV9TNfzLN5H/oiBw==", + "@date-io/moment": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.16.0.tgz", + "integrity": "sha512-wvu/40k128kF6P0jPbiyZcPR14VjJAgYEs+mYtsXz/AyWpC2DEJKly7ub+dpevUywbTzzpZysyCxCdzLzxD/uw==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-flow": "^7.16.5" + "@date-io/core": "^2.16.0" } }, - "@babel/plugin-transform-for-of": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.5.tgz", - "integrity": "sha512-+DpCAJFPAvViR17PIMi9x2AE34dll5wNlXO43wagAX2YcRGgEVHCNFC4azG85b4YyyFarvkc/iD5NPrz4Oneqw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@destinationstransfers/ntp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@destinationstransfers/ntp/-/ntp-2.0.0.tgz", + "integrity": "sha512-0gYbtXpyNlk0p+jWy+lftUkB+uJIBjNUWTB2tv7/fxl8zO3pQsaVFDLFDozbQ1wnYw/PrHDeRdYwAg2frY48Tg==" }, - "@babel/plugin-transform-function-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.5.tgz", - "integrity": "sha512-Fuec/KPSpVLbGo6z1RPw4EE1X+z9gZk1uQmnYy7v4xr4TO9p41v1AoUuXEtyqAI7H+xNJYSICzRqZBhDEkd3kQ==", - "requires": { - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" + "@emotion/babel-plugin": { + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", + "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } } }, - "@babel/plugin-transform-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.5.tgz", - "integrity": "sha512-B1j9C/IfvshnPcklsc93AVLTrNVa69iSqztylZH6qnmiAsDDOmmjEYqOm3Ts2lGSgTSywnBNiqC949VdD0/gfw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@emotion/cache": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", + "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "requires": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.0.13" } }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.5.tgz", - "integrity": "sha512-d57i3vPHWgIde/9Y8W/xSFUndhvhZN5Wu2TjRrN1MVz5KzdUihKnfDVlfP1U7mS5DNj/WHHhaE4/tTi4hIyHwQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" }, - "@babel/plugin-transform-modules-amd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.5.tgz", - "integrity": "sha512-oHI15S/hdJuSCfnwIz+4lm6wu/wBn7oJ8+QrkzPPwSFGXk8kgdI/AIKcbR/XnD1nQVMg/i6eNaXpszbGuwYDRQ==", + "@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@emotion/memoize": "^0.8.0" } }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.5.tgz", - "integrity": "sha512-ABhUkxvoQyqhCWyb8xXtfwqNMJD7tx+irIRnUh6lmyFud7Jln1WzONXKlax1fg/ey178EXbs4bSGNd6PngO+SQ==", - "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-simple-access": "^7.16.0", - "babel-plugin-dynamic-import-node": "^2.3.3" - } + "@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.5.tgz", - "integrity": "sha512-53gmLdScNN28XpjEVIm7LbWnD/b/TpbwKbLk6KV4KqC9WyU6rq1jnNmVG6UgAdQZVVGZVoik3DqHNxk4/EvrjA==", - "requires": { - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-identifier": "^7.15.7", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@emotion/react": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", + "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/cache": "^11.10.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" } }, - "@babel/plugin-transform-modules-umd": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.5.tgz", - "integrity": "sha512-qTFnpxHMoenNHkS3VoWRdwrcJ3FhX567GvDA3hRZKF0Dj8Fmg0UzySZp3AP2mShl/bzcywb/UWAMQIjA1bhXvw==", + "@emotion/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", "requires": { - "@babel/helper-module-transforms": "^7.16.5", - "@babel/helper-plugin-utils": "^7.16.5" + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" } }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.5.tgz", - "integrity": "sha512-/wqGDgvFUeKELW6ex6QB7dLVRkd5ehjw34tpXu1nhKC0sFfmaLabIswnpf8JgDyV2NeDmZiwoOb0rAmxciNfjA==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0" - } + "@emotion/sheet": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", + "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" }, - "@babel/plugin-transform-new-target": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.5.tgz", - "integrity": "sha512-ZaIrnXF08ZC8jnKR4/5g7YakGVL6go6V9ql6Jl3ecO8PQaQqFE74CuM384kezju7Z9nGCCA20BqZaR1tJ/WvHg==", + "@emotion/styled": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.4.tgz", + "integrity": "sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/is-prop-valid": "^1.2.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0" } }, - "@babel/plugin-transform-object-super": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.5.tgz", - "integrity": "sha512-tded+yZEXuxt9Jdtkc1RraW1zMF/GalVxaVVxh41IYwirdRgyAxxxCKZ9XB7LxZqmsjfjALxupNE1MIz9KH+Zg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-replace-supers": "^7.16.5" - } + "@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, - "@babel/plugin-transform-parameters": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.5.tgz", - "integrity": "sha512-B3O6AL5oPop1jAVg8CV+haeUte9oFuY85zu0jwnRNZZi3tVAbJriu5tag/oaO2kGaQM/7q7aGPBlTI5/sr9enA==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==" }, - "@babel/plugin-transform-property-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.5.tgz", - "integrity": "sha512-+IRcVW71VdF9pEH/2R/Apab4a19LVvdVsr/gEeotH00vSDVlKD+XgfSIw+cgGWsjDB/ziqGv/pGoQZBIiQVXHg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.16.5.tgz", - "integrity": "sha512-fdc1s5npHMZ9A+w9bYbrZu4499WyYPVaTTsRO8bU0GJcMuK4ejIX4lyjnpvi+YGLK/EhFQxWszqylO0vaMciFw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, - "@babel/plugin-transform-react-display-name": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.5.tgz", - "integrity": "sha512-dHYCOnzSsXFz8UcdNQIHGvg94qPL/teF7CCiCEMRxmA1G2p5Mq4JnKVowCDxYfiQ9D7RstaAp9kwaSI+sXbnhw==", + "@es-joy/jsdoccomment": { + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", + "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", + "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "comment-parser": "1.3.1", + "esquery": "^1.4.0", + "jsdoc-type-pratt-parser": "~3.1.0" } }, - "@babel/plugin-transform-react-jsx": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.5.tgz", - "integrity": "sha512-+arLIz1d7kmwX0fKxTxbnoeG85ONSnLpvdODa4P3pc1sS7CV1hfmtYWufkW/oYsPnkDrEeQFxhUWcFnrXW7jQQ==", + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/plugin-syntax-jsx": "^7.16.5", - "@babel/types": "^7.16.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" } }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.5.tgz", - "integrity": "sha512-uQSLacMZSGLCxOw20dzo1dmLlKkd+DsayoV54q3MHXhbqgPzoiGerZQgNPl/Ro8/OcXV2ugfnkx+rxdS0sN5Uw==", - "requires": { - "@babel/plugin-transform-react-jsx": "^7.16.5" - } + "@fontsource/jetbrains-mono": { + "version": "4.5.11", + "resolved": "https://registry.npmjs.org/@fontsource/jetbrains-mono/-/jetbrains-mono-4.5.11.tgz", + "integrity": "sha512-IW1qgWGkjlN1O6Jf+6LWF9DpcdXhyQEXhTlzfVKrWHX+ProuOT5FcrEAj34AR+19CgAb9Sheda2slORnybBsdw==" }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.5.tgz", - "integrity": "sha512-0nYU30hCxnCVCbRjSy9ahlhWZ2Sn6khbY4FqR91W+2RbSqkWEbVu2gXh45EqNy4Bq7sRU+H4i0/6YKwOSzh16A==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" - } + "@fontsource/roboto": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz", + "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" }, - "@babel/plugin-transform-regenerator": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.5.tgz", - "integrity": "sha512-2z+it2eVWU8TtQQRauvGUqZwLy4+7rTfo6wO4npr+fvvN1SW30ZF3O/ZRCNmTuu4F5MIP8OJhXAhRV5QMJOuYg==", + "@humanwhocodes/config-array": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "requires": { - "regenerator-transform": "^0.14.2" + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" } }, - "@babel/plugin-transform-reserved-words": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.5.tgz", - "integrity": "sha512-aIB16u8lNcf7drkhXJRoggOxSTUAuihTSTfAcpynowGJOZiGf+Yvi7RuTwFzVYSYPmWyARsPqUGoZWWWxLiknw==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" }, - "@babel/plugin-transform-runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.5.tgz", - "integrity": "sha512-gxpfS8XQWDbQ8oP5NcmpXxtEgCJkbO+W9VhZlOhr0xPyVaRjAQPOv7ZDj9fg0d5s9+NiVvMCE6gbkEkcsxwGRw==", - "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "semver": "^6.3.0" + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" } } }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.5.tgz", - "integrity": "sha512-ZbuWVcY+MAXJuuW7qDoCwoxDUNClfZxoo7/4swVbOW1s/qYLOMHlm9YRWMsxMFuLs44eXsv4op1vAaBaBaDMVg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" - } + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" }, - "@babel/plugin-transform-spread": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.5.tgz", - "integrity": "sha512-5d6l/cnG7Lw4tGHEoga4xSkYp1euP7LAtrah1h1PgJ3JY7yNsjybsxQAnVK4JbtReZ/8z6ASVmd3QhYYKLaKZw==", + "@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0" + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" } }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.5.tgz", - "integrity": "sha512-usYsuO1ID2LXxzuUxifgWtJemP7wL2uZtyrTVM4PKqsmJycdS4U4mGovL5xXkfUheds10Dd2PjoQLXw6zCsCbg==", - "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "@babel/plugin-transform-template-literals": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.5.tgz", - "integrity": "sha512-gnyKy9RyFhkovex4BjKWL3BVYzUDG6zC0gba7VMLbQoDuqMfJ1SDXs8k/XK41Mmt1Hyp4qNAvGFb9hKzdCqBRQ==", + "@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" } }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.5.tgz", - "integrity": "sha512-ldxCkW180qbrvyCVDzAUZqB0TAeF8W/vGJoRcaf75awm6By+PxfJKvuqVAnq8N9wz5Xa6mSpM19OfVKKVmGHSQ==", + "@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" } }, - "@babel/plugin-transform-typescript": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz", - "integrity": "sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==", + "@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-typescript": "^7.16.0" + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" } }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.5.tgz", - "integrity": "sha512-shiCBHTIIChGLdyojsKQjoAyB8MBwat25lKM7MJjbe1hE0bgIppD+LX9afr41lLHOhqceqeWl4FkLp+Bgn9o1Q==", + "@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" } }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.5.tgz", - "integrity": "sha512-GTJ4IW012tiPEMMubd7sD07iU9O/LOo8Q/oU4xNhcaq0Xn8+6TcUQaHtC8YxySo1T+ErQ8RaWogIEeFhKGNPzw==", + "@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.16.0", - "@babel/helper-plugin-utils": "^7.16.5" - } - }, - "@babel/preset-env": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.5.tgz", - "integrity": "sha512-MiJJW5pwsktG61NDxpZ4oJ1CKxM1ncam9bzRtx9g40/WkLRkxFP6mhpkYV0/DxcciqoiHicx291+eUQrXb/SfQ==", - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-compilation-targets": "^7.16.3", - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.16.2", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-async-generator-functions": "^7.16.5", - "@babel/plugin-proposal-class-properties": "^7.16.5", - "@babel/plugin-proposal-class-static-block": "^7.16.5", - "@babel/plugin-proposal-dynamic-import": "^7.16.5", - "@babel/plugin-proposal-export-namespace-from": "^7.16.5", - "@babel/plugin-proposal-json-strings": "^7.16.5", - "@babel/plugin-proposal-logical-assignment-operators": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-numeric-separator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-catch-binding": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-proposal-private-methods": "^7.16.5", - "@babel/plugin-proposal-private-property-in-object": "^7.16.5", - "@babel/plugin-proposal-unicode-property-regex": "^7.16.5", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-block-scoped-functions": "^7.16.5", - "@babel/plugin-transform-block-scoping": "^7.16.5", - "@babel/plugin-transform-classes": "^7.16.5", - "@babel/plugin-transform-computed-properties": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-dotall-regex": "^7.16.5", - "@babel/plugin-transform-duplicate-keys": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-function-name": "^7.16.5", - "@babel/plugin-transform-literals": "^7.16.5", - "@babel/plugin-transform-member-expression-literals": "^7.16.5", - "@babel/plugin-transform-modules-amd": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/plugin-transform-modules-systemjs": "^7.16.5", - "@babel/plugin-transform-modules-umd": "^7.16.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.16.5", - "@babel/plugin-transform-new-target": "^7.16.5", - "@babel/plugin-transform-object-super": "^7.16.5", - "@babel/plugin-transform-parameters": "^7.16.5", - "@babel/plugin-transform-property-literals": "^7.16.5", - "@babel/plugin-transform-regenerator": "^7.16.5", - "@babel/plugin-transform-reserved-words": "^7.16.5", - "@babel/plugin-transform-shorthand-properties": "^7.16.5", - "@babel/plugin-transform-spread": "^7.16.5", - "@babel/plugin-transform-sticky-regex": "^7.16.5", - "@babel/plugin-transform-template-literals": "^7.16.5", - "@babel/plugin-transform-typeof-symbol": "^7.16.5", - "@babel/plugin-transform-unicode-escapes": "^7.16.5", - "@babel/plugin-transform-unicode-regex": "^7.16.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.16.0", - "babel-plugin-polyfill-corejs2": "^0.3.0", - "babel-plugin-polyfill-corejs3": "^0.4.0", - "babel-plugin-polyfill-regenerator": "^0.3.0", - "core-js-compat": "^3.19.1", - "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==" - } + "@sinclair/typebox": "^0.24.1" } }, - "@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" } }, - "@babel/preset-react": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.5.tgz", - "integrity": "sha512-3kzUOQeaxY/2vhPDS7CX/KGEGu/1bOYGvdRDJ2U5yjEz5o5jmIeTPLoiQBPGjfhPascLuW5OlMiPzwOOuB6txg==", + "@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-react-display-name": "^7.16.5", - "@babel/plugin-transform-react-jsx": "^7.16.5", - "@babel/plugin-transform-react-jsx-development": "^7.16.5", - "@babel/plugin-transform-react-pure-annotations": "^7.16.5" + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "@babel/preset-typescript": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.5.tgz", - "integrity": "sha512-lmAWRoJ9iOSvs3DqOndQpj8XqXkzaiQs50VG/zESiI9D3eoZhGriU675xNCr0UwvsuXrhMAGvyk1w+EVWF3u8Q==", + "@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", "requires": { - "@babel/helper-plugin-utils": "^7.16.5", - "@babel/helper-validator-option": "^7.14.5", - "@babel/plugin-transform-typescript": "^7.16.1" + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" } }, - "@babel/runtime": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz", - "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==", + "@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "requires": { - "regenerator-runtime": "^0.13.4" + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" } }, - "@babel/runtime-corejs3": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.16.5.tgz", - "integrity": "sha512-F1pMwvTiUNSAM8mc45kccMQxj31x3y3P+tA/X8hKNWp3/hUsxdGxZ3D3H8JIkxtfA8qGkaBTKvcmvStaYseAFw==", + "@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "requires": { - "core-js-pure": "^3.19.0", - "regenerator-runtime": "^0.13.4" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" } }, - "@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "requires": { - "@babel/highlight": "^7.16.0" - } - } + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "@babel/traverse": { - "version": "7.16.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.5.tgz", - "integrity": "sha512-FOCODAzqUMROikDYLYxl4nmwiLlu85rNqBML/A5hKRVXG2LV8d0iMqgPzdYTcIpjZEBB7D6UDU9vxRZiriASdQ==", + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@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==", "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.5", - "@babel/helper-environment-visitor": "^7.16.5", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.5", - "@babel/types": "^7.16.0", - "debug": "^4.1.0", - "globals": "^11.1.0" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "dependencies": { - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", + "@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==", "requires": { - "@babel/highlight": "^7.16.0" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" } } }, - "@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz", + "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==", "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "to-fast-properties": "^2.0.0" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + "@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" + "@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "@mui/base": { + "version": "5.0.0-alpha.81", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.81.tgz", + "integrity": "sha512-KJP+RdKBLSbhiAliy1b5xFuoAezawupfIHc/MRtEZdqAmUW0+UFNDXIUDlBKR9zLCjgjQ7eVJsSe0TwAgd8OMQ==", + "requires": { + "@babel/runtime": "^7.17.2", + "@emotion/is-prop-valid": "^1.1.2", + "@mui/types": "^7.1.3", + "@mui/utils": "^5.8.0", + "@popperjs/core": "^2.11.5", + "clsx": "^1.1.1", + "prop-types": "^15.8.1", + "react-is": "^17.0.2" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } } }, - "@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==" + "@mui/core-downloads-tracker": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.9.tgz", + "integrity": "sha512-rqoFu4qww6KJBbXYhyRd9YXjwBHa3ylnBPSWbGf1bdfG0AYMKmVzg8zxkWvxAWOp97kvx3M2kNPb0xMIDZiogQ==" }, - "@csstools/normalize.css": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", - "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" + "@mui/icons-material": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.9.tgz", + "integrity": "sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg==", + "requires": { + "@babel/runtime": "^7.19.0" + } }, - "@date-io/core": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.11.0.tgz", - "integrity": "sha512-DvPBnNoeuLaoSJZaxgpu54qzRhRKjSYVyQjhznTFrllKuDpm0sDFjHo6lvNLCM/cfMx2gb2PM2zY2kc9C8nmuw==" + "@mui/lab": { + "version": "5.0.0-alpha.82", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.82.tgz", + "integrity": "sha512-SUkHbMUVTmn+tqOjkRBNdX/wKS97rfvoOBMY6+QThJhTyIOym9ELcpKbEN7uf/UEPEnRNuqekLid5wHudS2cLw==", + "requires": { + "@babel/runtime": "^7.17.2", + "@mui/base": "5.0.0-alpha.81", + "@mui/system": "^5.8.0", + "@mui/utils": "^5.8.0", + "@mui/x-date-pickers": "5.0.0-alpha.0", + "clsx": "^1.1.1", + "prop-types": "^15.8.1", + "react-is": "^17.0.2", + "react-transition-group": "^4.4.2", + "rifm": "^0.12.1" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + } + } }, - "@date-io/date-fns": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.11.0.tgz", - "integrity": "sha512-mPQ71plBeFrArvBSHtjWMHXA89IUbZ6kuo2dsjlRC/1uNOybo91spIb+wTu03NxKTl8ut07s0jJ9svF71afpRg==", - "requires": { - "@date-io/core": "^2.11.0" + "@mui/material": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.9.tgz", + "integrity": "sha512-sdOzlgpCmyw48je+E7o9UGGJpgBaF+60FlTRpVpcd/z+LUhnuzzuis891yPI5dPPXLBDL/bO4SsGg51lgNeLBw==", + "requires": { + "@babel/runtime": "^7.19.0", + "@mui/base": "5.0.0-alpha.101", + "@mui/core-downloads-tracker": "^5.10.9", + "@mui/system": "^5.10.9", + "@mui/types": "^7.2.0", + "@mui/utils": "^5.10.9", + "@types/react-transition-group": "^4.4.5", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "dependencies": { + "@mui/base": { + "version": "5.0.0-alpha.101", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.101.tgz", + "integrity": "sha512-a54BcXvArGOKUZ2zyS/7B9GNhAGgfomEQSkfEZ88Nc9jKvXA+Mppenfz5o4JCAnD8c4VlePmz9rKOYvvum1bZw==", + "requires": { + "@babel/runtime": "^7.19.0", + "@emotion/is-prop-valid": "^1.2.0", + "@mui/types": "^7.2.0", + "@mui/utils": "^5.10.9", + "@popperjs/core": "^2.11.6", + "clsx": "^1.2.1", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } } }, - "@date-io/dayjs": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/dayjs/-/dayjs-2.11.0.tgz", - "integrity": "sha512-w67vRK56NZJIKhJM/CrNbfnIcuMvR3ApfxzNZiCZ5w29sxgBDeKuX4M+P7A9r5HXOMGcsOcpgaoTDINNGkdpGQ==", + "@mui/private-theming": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.9.tgz", + "integrity": "sha512-BN7/CnsVPVyBaQpDTij4uV2xGYHHHhOgpdxeYLlIu+TqnsVM7wUeF+37kXvHovxM6xmL5qoaVUD98gDC0IZnHg==", "requires": { - "@date-io/core": "^2.11.0" + "@babel/runtime": "^7.19.0", + "@mui/utils": "^5.10.9", + "prop-types": "^15.8.1" } }, - "@date-io/luxon": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@date-io/luxon/-/luxon-2.11.1.tgz", - "integrity": "sha512-JUXo01kdPQxLORxqdENrgdUhooKgDUggsNRSdi2BcUhASIY2KGwwWXu8ikVHHGkw+DUF4FOEKGfkQd0RHSvX6g==", + "@mui/styled-engine": { + "version": "5.10.8", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.8.tgz", + "integrity": "sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw==", "requires": { - "@date-io/core": "^2.11.0" + "@babel/runtime": "^7.19.0", + "@emotion/cache": "^11.10.3", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" } }, - "@date-io/moment": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@date-io/moment/-/moment-2.11.0.tgz", - "integrity": "sha512-QSL+83qezQ9Ty0dtFgAkk6eC0GMl/lgYfDajeVUDB3zVA2A038hzczRLBg29ifnBGhQMPABxuOafgWwhDjlarg==", + "@mui/system": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.9.tgz", + "integrity": "sha512-B6fFC0sK06hNmqY7fAUfwShQv594+u/DT1YEFHPtK4laouTu7V4vSGQWi1WJT9Bjs9Db5D1bRDJ+Yy+tc3QOYA==", "requires": { - "@date-io/core": "^2.11.0" + "@babel/runtime": "^7.19.0", + "@mui/private-theming": "^5.10.9", + "@mui/styled-engine": "^5.10.8", + "@mui/types": "^7.2.0", + "@mui/utils": "^5.10.9", + "clsx": "^1.2.1", + "csstype": "^3.1.1", + "prop-types": "^15.8.1" } }, - "@destinationstransfers/ntp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@destinationstransfers/ntp/-/ntp-2.0.0.tgz", - "integrity": "sha512-0gYbtXpyNlk0p+jWy+lftUkB+uJIBjNUWTB2tv7/fxl8zO3pQsaVFDLFDozbQ1wnYw/PrHDeRdYwAg2frY48Tg==" + "@mui/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz", + "integrity": "sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==" }, - "@emotion/babel-plugin": { - "version": "11.7.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz", - "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==", - "requires": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/runtime": "^7.13.10", - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.5", - "@emotion/serialize": "^1.0.2", - "babel-plugin-macros": "^2.6.1", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.0.13" + "@mui/utils": { + "version": "5.10.9", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz", + "integrity": "sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA==", + "requires": { + "@babel/runtime": "^7.19.0", + "@types/prop-types": "^15.7.5", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" } } }, - "@emotion/cache": { - "version": "11.7.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", - "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", - "requires": { - "@emotion/memoize": "^0.7.4", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", - "stylis": "4.0.13" - } - }, - "@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" - }, - "@emotion/is-prop-valid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz", - "integrity": "sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==", + "@mui/x-date-pickers": { + "version": "5.0.0-alpha.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-5.0.0-alpha.0.tgz", + "integrity": "sha512-JTzTaNSWbxNi8KDUJjHCH6im0YlIEv88gPoKhGm7s6xCGT1q6FtMp/oQ40nhfwrJ73nkM5G1JXRIzI/yfsHXQQ==", "requires": { - "@emotion/memoize": "^0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", - "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" - }, - "@emotion/react": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.6.0.tgz", - "integrity": "sha512-23MnRZFBN9+D1lHXC5pD6z4X9yhPxxtHr6f+iTGz6Fv6Rda0GdefPrsHL7otsEf+//7uqCdT5QtHeRxHCERzuw==", - "requires": { - "@babel/runtime": "^7.13.10", - "@emotion/cache": "^11.6.0", - "@emotion/serialize": "^1.0.2", - "@emotion/sheet": "^1.1.0", - "@emotion/utils": "^1.0.0", - "@emotion/weak-memoize": "^0.2.5", - "hoist-non-react-statics": "^3.3.1" + "@date-io/date-fns": "^2.11.0", + "@date-io/dayjs": "^2.11.0", + "@date-io/luxon": "^2.11.1", + "@date-io/moment": "^2.11.0", + "@mui/utils": "^5.2.3", + "clsx": "^1.1.1", + "prop-types": "^15.7.2", + "react-transition-group": "^4.4.2", + "rifm": "^0.12.1" } }, - "@emotion/serialize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", - "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "requires": { - "@emotion/hash": "^0.8.0", - "@emotion/memoize": "^0.7.4", - "@emotion/unitless": "^0.7.5", - "@emotion/utils": "^1.0.0", - "csstype": "^3.0.2" + "eslint-scope": "5.1.1" } }, - "@emotion/sheet": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", - "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" - }, - "@emotion/styled": { - "version": "11.6.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.6.0.tgz", - "integrity": "sha512-mxVtVyIOTmCAkFbwIp+nCjTXJNgcz4VWkOYQro87jE2QBTydnkiYusMrRGFtzuruiGK4dDaNORk4gH049iiQuw==", + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "requires": { - "@babel/runtime": "^7.13.10", - "@emotion/babel-plugin": "^11.3.0", - "@emotion/is-prop-valid": "^1.1.1", - "@emotion/serialize": "^1.0.2", - "@emotion/utils": "^1.0.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@emotion/utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz", - "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==" - }, - "@emotion/weak-memoize": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", - "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, - "@es-joy/jsdoccomment": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.12.0.tgz", - "integrity": "sha512-Gw4/j9v36IKY8ET+W0GoOzrRw17xjf21EIFFRL3zx21fF5MnqmeNpNi+PU/LKjqLpPb2Pw2XdlJbYM31VVo/PQ==", - "dev": true, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "requires": { - "comment-parser": "1.2.4", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "2.0.0" - }, - "dependencies": { - "jsdoc-type-pratt-parser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.0.tgz", - "integrity": "sha512-sUuj2j48wxrEpbFjDp1sAesAxPiLT+z0SWVmMafyIINs6Lj5gIPKh3VrkBZu4E/Dv+wHpOot0m6H8zlHQjwqeQ==", - "dev": true - } + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.8.tgz", + "integrity": "sha512-wxXRwf+IQ6zvHSJZ+5T2RQNEsq+kx4jKRXfFvdt3nBIUzJUAvXEFsUeoaohDe/Kr84MTjGwcuIUPNcstNJORsA==", "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" }, "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" } } }, - "@fontsource/roboto": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.1.tgz", - "integrity": "sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg==" + "@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, - "@gar/promisify": { + "@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", - "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==" + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, - "@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" }, - "@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" }, - "@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, - "@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, - "@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", "requires": { - "@hapi/hoek": "^8.3.0" + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" } }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" } }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + "@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "requires": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + } }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" } } }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + "@rushstack/eslint-patch": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", + "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" }, - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "@sinclair/typebox": { + "version": "0.24.46", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.46.tgz", + "integrity": "sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==" + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "type-detect": "4.0.8" } }, - "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - } - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - } + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "requires": { + "@sinonjs/commons": "^1.7.0" } }, - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" } }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==" + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==" + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==" + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==" + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==" + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==" + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==" + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==" + }, + "@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" } }, - "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" } }, - "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "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==" - } - } - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "@babel/types": "^7.12.6" } }, - "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" } }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" } }, - "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", "requires": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" } }, - "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==" + }, + "@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/types": "^7.0.0" } }, - "@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==", + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" - }, - "@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==", + "@types/babel__traverse": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@babel/types": "^7.3.0" } }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz", - "integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==", + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@types/connect": "*", + "@types/node": "*" } }, - "@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", - "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" - }, - "@mui/base": { - "version": "5.0.0-alpha.56", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.56.tgz", - "integrity": "sha512-BlPuRx778JoNIF34m8wOPDZSburwFbH+Y1y97KoAEqC2Qra2UGV3+vII3R9+qkikIKEWJvv1327J7sCfxfpGFQ==", + "@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", "requires": { - "@babel/runtime": "^7.16.3", - "@emotion/is-prop-valid": "^1.1.1", - "@mui/utils": "^5.2.0", - "@popperjs/core": "^2.4.4", - "clsx": "^1.1.1", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "dependencies": { - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - } + "@types/node": "*" } }, - "@mui/core": { - "version": "5.0.0-alpha.48", - "resolved": "https://registry.npmjs.org/@mui/core/-/core-5.0.0-alpha.48.tgz", - "integrity": "sha512-H/QQwKsr2EqPAnP35DGDpWihk5BOFYGhO52rIHb3XKOfoUjDCrCHBy2kvr3dLWJDmJXr/QzYj3AX10n5XzlaMg==", + "@types/compression": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.2.tgz", + "integrity": "sha512-lwEL4M/uAGWngWFLSG87ZDr2kLrbuR8p7X+QZB1OQlT+qkHsCPDVFnHPyXf4Vyl4yDDorNY+mAhosxkCvppatg==", + "dev": true, "requires": { - "@babel/runtime": "^7.15.4", - "@emotion/is-prop-valid": "^1.1.0", - "@mui/utils": "^5.0.1", - "clsx": "^1.1.1", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "dependencies": { - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - } + "@types/express": "*" } }, - "@mui/icons-material": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.2.0.tgz", - "integrity": "sha512-NvyrVaGKpP4R1yFw8BCnE0QcsQ67RtpgxPr4FtH8q60MDYPuPVczLOn5Ash5CFavoDWur/NfM/4DpT54yf3InA==", + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "requires": { - "@babel/runtime": "^7.16.3" - } - }, - "@mui/lab": { - "version": "5.0.0-alpha.48", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.48.tgz", - "integrity": "sha512-ukYcx1ReSy4taQBMIPTkOaSz+CwgxYih3XwTCGTv84atRWMFhfqJO3Ofe8rQ5/innMDbBlSPkjaiMSag8d3QeQ==", - "requires": { - "@babel/runtime": "^7.15.4", - "@date-io/date-fns": "^2.10.6", - "@date-io/dayjs": "^2.10.6", - "@date-io/luxon": "^2.10.6", - "@date-io/moment": "^2.10.6", - "@mui/core": "5.0.0-alpha.48", - "@mui/system": "^5.0.1", - "@mui/utils": "^5.0.1", - "clsx": "^1.1.1", - "prop-types": "^15.7.2", - "react-is": "^17.0.2", - "react-transition-group": "^4.4.2", - "rifm": "^0.12.0" - }, - "dependencies": { - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - } + "@types/node": "*" } }, - "@mui/material": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.2.0.tgz", - "integrity": "sha512-AJehUbf0pWA+X9x+rXM4xHjLdNSf3YZzVt9YP/Pa75HCIDn4Dg2neiZu/Cg57C19WMlUf3nyn4Vkz4nD48DgPA==", + "@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", "requires": { - "@babel/runtime": "^7.16.3", - "@mui/base": "5.0.0-alpha.56", - "@mui/system": "^5.2.0", - "@mui/types": "^7.1.0", - "@mui/utils": "^5.2.0", - "@types/react-transition-group": "^4.4.4", - "clsx": "^1.1.1", - "csstype": "^3.0.10", - "hoist-non-react-statics": "^3.3.2", - "prop-types": "^15.7.2", - "react-is": "^17.0.2", - "react-transition-group": "^4.4.2" - }, - "dependencies": { - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - } + "@types/express-serve-static-core": "*", + "@types/node": "*" } }, - "@mui/private-theming": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.2.3.tgz", - "integrity": "sha512-Lc1Cmu8lSsYZiXADi9PBb17Ho82ZbseHQujUFAcp6bCJ5x/d+87JYCIpCBMagPu/isRlFCwbziuXPmz7WOzJPQ==", + "@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", "requires": { - "@babel/runtime": "^7.16.3", - "@mui/utils": "^5.2.3", - "prop-types": "^15.7.2" + "@types/ms": "*" } }, - "@mui/styled-engine": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.2.6.tgz", - "integrity": "sha512-bqAhli8eGS6v2qxivy2/4K0Ag8o//jsu1G2G6QcieFiT6y7oIF/nd/6Tvw6OSm3roOTifVQWNKwkt1yFWhGS+w==", + "@types/eslint": { + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz", + "integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==", "requires": { - "@babel/runtime": "^7.16.3", - "@emotion/cache": "^11.7.1", - "prop-types": "^15.7.2" + "@types/estree": "*", + "@types/json-schema": "*" } }, - "@mui/system": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.2.6.tgz", - "integrity": "sha512-PZ7bmpWOLikWgqn2zWv9/Xa7lxnRBOmfjoMH7c/IVYJs78W3971brXJ3xV9MEWWQcoqiYQeXzUJaNf4rFbKCBA==", + "@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "requires": { - "@babel/runtime": "^7.16.3", - "@mui/private-theming": "^5.2.3", - "@mui/styled-engine": "^5.2.6", - "@mui/types": "^7.1.0", - "@mui/utils": "^5.2.3", - "clsx": "^1.1.1", - "csstype": "^3.0.10", - "prop-types": "^15.7.2" + "@types/eslint": "*", + "@types/estree": "*" } }, - "@mui/types": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.0.tgz", - "integrity": "sha512-Hh7ALdq/GjfIwLvqH3XftuY3bcKhupktTm+S6qRIDGOtPtRuq2L21VWzOK4p7kblirK0XgGVH5BLwa6u8z/6QQ==", - "requires": {} + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" }, - "@mui/utils": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.2.3.tgz", - "integrity": "sha512-sQujlajIS0zQKcGIS6tZR0L1R+ib26B6UtuEn+cZqwKHsPo3feuS+SkdscYBdcCdMbrZs4gj8WIJHl2z6tbSzQ==", + "@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", "requires": { - "@babel/runtime": "^7.16.3", - "@types/prop-types": "^15.7.4", - "@types/react-is": "^16.7.1 || ^17.0.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "dependencies": { - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - } + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "@types/express-list-endpoints": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/express-list-endpoints/-/express-list-endpoints-6.0.0.tgz", + "integrity": "sha512-TIi9ggtP1HzV8FmFmwZ/NV3B+qnRw9XslEhG8Qb/50iLDOmq/7radpC8SKXSCvI74FaOrD6I4dF+q+ml5AEYag==", + "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@types/express": "*" } }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" } }, - "@npmcli/fs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz", - "integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==", + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" + "@types/node": "*" } }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } + "@types/unist": "*" } }, - "@popperjs/core": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz", - "integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==" + "@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "dev": true }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "requires": { + "@types/node": "*" + } }, - "@protobufjs/codegen": { + "@types/istanbul-lib-coverage": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" + "@types/istanbul-lib-coverage": "*" } }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "requires": { + "@types/istanbul-lib-report": "*" + } }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "@types/jstoxml": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/jstoxml/-/jstoxml-2.0.2.tgz", + "integrity": "sha512-60VaXPlZbd7tEhloAkE2E0lg+QoWpnGusdy+2pGMGFFpdsyxm/1GKs0o/nLJJKWXci92cnq2utmqaV5L7Zjqxw==", + "dev": true }, - "@rollup/plugin-node-resolve": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", - "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", - "requires": { - "@rollup/pluginutils": "^3.0.8", - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.14.2" - } + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, - "@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", "requires": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" + "@types/unist": "*" } }, - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - } - } + "@types/mime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "requires": { - "type-detect": "4.0.8" - } + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true }, - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "requires": { - "@sinonjs/commons": "^1.7.0" - } + "@types/mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-rADY+HtTOA52l9VZWtgQfn4p+UDVM2eDVkMZT1I6syp0YKxW2F9v+0pbRZLsvskhQv/vMb6ZfCay81GHbz5SHg==", + "dev": true }, - "@surma/rollup-plugin-off-main-thread": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz", - "integrity": "sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==", + "@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + }, + "@types/node": { + "version": "18.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz", + "integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==" + }, + "@types/node-ssdp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/node-ssdp/-/node-ssdp-4.0.1.tgz", + "integrity": "sha512-w8NEmUjsAG/lKqUY3NOSMsfHz7orFblujp+LeiyxvFHDCEAKxnBTVsLqLLZShvwVQ0/jN5VwCgFGIGo61lirZQ==", + "dev": true, "requires": { - "ejs": "^2.6.1", - "magic-string": "^0.25.0" + "@types/node": "*" } }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==" + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==" + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==" + "@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==" + "@types/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==" + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==" + "@types/q": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", + "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==" + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==" + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "@types/react": { + "version": "18.0.21", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz", + "integrity": "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==", "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" } }, - "@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "@types/react-dom": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.6.tgz", + "integrity": "sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==", + "dev": true, "requires": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" + "@types/react": "*" } }, - "@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", "requires": { - "@babel/types": "^7.12.6" + "@types/react": "*" } }, - "@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "@types/react-router": { + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.19.tgz", + "integrity": "sha512-Fv/5kb2STAEMT3wHzdKQK2z8xKq38EDIGVrutYLmQVVLe+4orDFquU52hQrULnEHinMKv9FSA6lf9+uNT1ITtA==", + "dev": true, "requires": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" + "@types/history": "^4.7.11", + "@types/react": "*" } }, - "@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dev": true, "requires": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" } }, - "@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "@types/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", "requires": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } + "@types/react": "*" } }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@types/node": "*" } }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "requires": { - "@babel/types": "^7.0.0" - } + "@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "@types/semaphore": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/semaphore/-/semaphore-1.1.1.tgz", + "integrity": "sha512-jmFpMslMtBGOXY2s7x6O8vBebcj6zhkwl0Pd/viZApo1uZaPk733P8doPvaiBbCG+R7201OLOl4QP7l1mFyuyw==", + "dev": true + }, + "@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", "requires": { - "@babel/types": "^7.3.0" + "@types/express": "*" } }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", "requires": { - "@types/connect": "*", + "@types/mime": "*", "@types/node": "*" } }, - "@types/color": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.2.tgz", - "integrity": "sha512-INiJl6sfNn8iyC5paxVzqiVUEj2boIlFki02uRTAkKwAj++7aAF+ZfEv/XrIeBa0XI/fTZuDHW8rEEcEVnON+Q==", - "dev": true, + "@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", "requires": { - "@types/color-convert": "*" + "@types/node": "*" } }, - "@types/color-convert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz", - "integrity": "sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==", - "dev": true, - "requires": { - "@types/color-name": "*" - } + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true + "@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, - "@types/compression": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.7.2.tgz", - "integrity": "sha512-lwEL4M/uAGWngWFLSG87ZDr2kLrbuR8p7X+QZB1OQlT+qkHsCPDVFnHPyXf4Vyl4yDDorNY+mAhosxkCvppatg==", - "dev": true, - "requires": { - "@types/express": "*" - } + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "requires": { - "@types/node": "*" - } + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", + "dev": true }, - "@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", "requires": { - "@types/ms": "*" + "@types/node": "*" } }, - "@types/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "requires": { - "@types/estree": "*", - "@types/json-schema": "*" + "@types/yargs-parser": "*" } }, - "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==" - }, - "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, - "@types/express-list-endpoints": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@types/express-list-endpoints/-/express-list-endpoints-6.0.0.tgz", - "integrity": "sha512-TIi9ggtP1HzV8FmFmwZ/NV3B+qnRw9XslEhG8Qb/50iLDOmq/7radpC8SKXSCvI74FaOrD6I4dF+q+ml5AEYag==", - "dev": true, - "requires": { - "@types/express": "*" + "@typescript-eslint/eslint-plugin": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz", + "integrity": "sha512-FIBZgS3DVJgqPwJzvZTuH4HNsZhHMa9SjxTKAZTlMsPw/UzpEjcf9f4dfgDJEHjK+HboUJo123Eshl6niwEm/Q==", + "requires": { + "@typescript-eslint/scope-manager": "5.40.0", + "@typescript-eslint/type-utils": "5.40.0", + "@typescript-eslint/utils": "5.40.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" } }, - "@types/express-serve-static-core": { - "version": "4.17.27", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", - "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", - "dev": true, + "@typescript-eslint/experimental-utils": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.40.0.tgz", + "integrity": "sha512-wDYn3NYqVOmJI4iSkyWxXUu8Xoa4+OCh97YOXZecMCuXFIgCuxOCOlkR4kZyeXWNrulFyXPcXSbs4USb5IwI8g==", "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" + "@typescript-eslint/utils": "5.40.0" } }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "@typescript-eslint/parser": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.0.tgz", + "integrity": "sha512-Ah5gqyX2ySkiuYeOIDg7ap51/b63QgWZA7w6AHtFrag7aH0lRQPbLzUjk0c9o5/KZ6JRkTTDKShL4AUrQa6/hw==", "requires": { - "@types/minimatch": "*", - "@types/node": "*" + "@typescript-eslint/scope-manager": "5.40.0", + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/typescript-estree": "5.40.0", + "debug": "^4.3.4" } }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "@typescript-eslint/scope-manager": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.0.tgz", + "integrity": "sha512-d3nPmjUeZtEWRvyReMI4I1MwPGC63E8pDoHy0BnrYjnJgilBD3hv7XOiETKLY/zTwI7kCnBDf2vWTRUVpYw0Uw==", "requires": { - "@types/node": "*" + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/visitor-keys": "5.40.0" } }, - "@types/hast": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", - "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "@typescript-eslint/type-utils": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.0.tgz", + "integrity": "sha512-nfuSdKEZY2TpnPz5covjJqav+g5qeBqwSHKBvz7Vm1SAfy93SwKk/JeSTymruDGItTwNijSsno5LhOHRS1pcfw==", "requires": { - "@types/unist": "*" + "@typescript-eslint/typescript-estree": "5.40.0", + "@typescript-eslint/utils": "5.40.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" } }, - "@types/history": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", - "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==", - "dev": true - }, - "@types/html-minifier-terser": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz", - "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" + "@typescript-eslint/types": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.0.tgz", + "integrity": "sha512-V1KdQRTXsYpf1Y1fXCeZ+uhjW48Niiw0VGt4V8yzuaDTU8Z1Xl7yQDyQNqyAFcVhpYXIVCEuxSIWTsLDpHgTbw==" }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + "@typescript-eslint/typescript-estree": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.0.tgz", + "integrity": "sha512-b0GYlDj8TLTOqwX7EGbw2gL5EXS2CPEWhF9nGJiGmEcmlpNBjyHsTwbqpyIEPVpl6br4UcBOYlcI2FJVtJkYhg==", + "requires": { + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/visitor-keys": "5.40.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "@typescript-eslint/utils": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.0.tgz", + "integrity": "sha512-MO0y3T5BQ5+tkkuYZJBjePewsY+cQnfkYeRqS6tPh28niiIwPnQ1t59CSRcs1ZwJJNOdWw7rv9pF8aP58IMihA==", "requires": { - "@types/istanbul-lib-coverage": "*" + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.40.0", + "@typescript-eslint/types": "5.40.0", + "@typescript-eslint/typescript-estree": "5.40.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" } }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "@typescript-eslint/visitor-keys": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.0.tgz", + "integrity": "sha512-ijJ+6yig+x9XplEpG2K6FUdJeQGGj/15U3S56W9IqXKJqleuD7zJ2AX/miLezwxpd7ZxDAqO87zWufKg+RPZyQ==", "requires": { - "@types/istanbul-lib-report": "*" + "@typescript-eslint/types": "5.40.0", + "eslint-visitor-keys": "^3.3.0" } }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "@types/jstoxml": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/jstoxml/-/jstoxml-2.0.1.tgz", - "integrity": "sha512-BLhCvUm5deaeDJb162gQoWAaPNa0fFdxbUwcWa5Noc6kFMmqfAEPbySaypbltl0H6FiCkyhfvs91UK2uFFCfEQ==", + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/mdast": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", - "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", "requires": { - "@types/unist": "*" + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" } }, - "@types/mdurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" - }, - "@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true - }, - "@types/mocha": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", - "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", - "dev": true + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" }, - "@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" }, - "@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" }, - "@types/node-ssdp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/node-ssdp/-/node-ssdp-4.0.1.tgz", - "integrity": "sha512-w8NEmUjsAG/lKqUY3NOSMsfHz7orFblujp+LeiyxvFHDCEAKxnBTVsLqLLZShvwVQ0/jN5VwCgFGIGo61lirZQ==", - "dev": true, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", "requires": { - "@types/node": "*" + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" } }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" - }, - "@types/prettier": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz", - "integrity": "sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==" - }, - "@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" - }, - "@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" }, - "@types/react": { - "version": "17.0.37", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.37.tgz", - "integrity": "sha512-2FS1oTqBGcH/s0E+CjrCCR9+JMpsu9b69RTFO+40ua43ZqP5MmQ4iUde/dMjWR909KxZwmOQIFq6AV6NjEG5xg==", + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" } }, - "@types/react-dom": { - "version": "17.0.11", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz", - "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==", - "dev": true, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", "requires": { - "@types/react": "*" + "@xtuc/ieee754": "^1.2.0" } }, - "@types/react-is": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", - "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", "requires": { - "@types/react": "*" + "@xtuc/long": "4.2.2" } }, - "@types/react-router": { - "version": "5.1.17", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz", - "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==", - "dev": true, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", "requires": { - "@types/history": "*", - "@types/react": "*" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" } }, - "@types/react-router-dom": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz", - "integrity": "sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==", - "dev": true, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", "requires": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, - "@types/react-transition-group": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", - "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", "requires": { - "@types/react": "*" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" } }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", "requires": { - "@types/node": "*" + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" } }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" - }, - "@types/semaphore": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/semaphore/-/semaphore-1.1.1.tgz", - "integrity": "sha512-jmFpMslMtBGOXY2s7x6O8vBebcj6zhkwl0Pd/viZApo1uZaPk733P8doPvaiBbCG+R7201OLOl4QP7l1mFyuyw==", - "dev": true - }, - "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", "requires": { - "@types/mime": "^1", - "@types/node": "*" + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" } }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, - "@types/tapable": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", - "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" }, - "@types/uglify-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", - "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" - }, - "@types/uuid": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.3.tgz", - "integrity": "sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==", - "dev": true - }, - "@types/webpack": { - "version": "4.41.32", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.32.tgz", - "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", - "requires": { - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "anymatch": "^3.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@types/webpack-sources": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.0.tgz", - "integrity": "sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==", - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - } - }, - "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", - "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", - "debug": "^4.3.2", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.2.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", - "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", - "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "debug": "^4.3.2" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" - } - }, - "@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "dependencies": { - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.4.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" - }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "requires": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" }, "acorn-globals": { "version": "6.0.0", @@ -29320,13 +23964,41 @@ "requires": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } } }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==" + }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } }, "acorn-walk": { "version": "7.2.0", @@ -29334,29 +24006,17 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==" }, "adjust-sourcemap-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", - "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", "requires": { "loader-utils": "^2.0.0", "regex-parser": "^2.2.11" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } } }, "agent-base": { @@ -29367,15 +24027,6 @@ "debug": "4" } }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -29385,29 +24036,46 @@ "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "dependencies": { + "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==" + } } }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "requires": {} + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "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==", + "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": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true }, "ansi-escapes": { "version": "4.3.2", @@ -29424,10 +24092,10 @@ } } }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" }, "ansi-regex": { "version": "5.0.1", @@ -29452,23 +24120,44 @@ } }, "api-schema-builder": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/api-schema-builder/-/api-schema-builder-2.0.10.tgz", - "integrity": "sha512-7XZuKeJScffImVXxiiRYKBA7/LevTlwiVdPwq8MnLig+ZEcpfPV9f4c8iXU2WB2TmZNH73kdN2Xxg+vNXh3qOg==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/api-schema-builder/-/api-schema-builder-2.0.11.tgz", + "integrity": "sha512-85zbwf8MtPWodhfnmQRW5YD/fuGR12FP+8TbcYai5wbRnoUmPYLftLSbp7NB6zQMPb61Gjz+ApPUSyTdcCos7g==", "requires": { "ajv": "^6.12.6", "clone-deep": "^4.0.1", "decimal.js": "^10.3.1", "js-yaml": "^3.14.1", "json-schema-deref-sync": "^0.14.0", + "lodash.get": "^4.4.2", "openapi-schema-validator": "^3.0.3", "swagger-parser": "^10.0.3" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true }, "are-we-there-yet": { "version": "1.1.7", @@ -29506,13 +24195,15 @@ } } }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "aria-query": { "version": "4.2.2", @@ -29523,39 +24214,19 @@ "@babel/runtime-corejs3": "^7.10.2" } }, - "arity-n": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", - "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=" - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" }, "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" } @@ -29565,102 +24236,55 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, "array.prototype.flatmap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", - "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" } }, "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, "async": { "version": "2.6.4", @@ -29670,76 +24294,67 @@ "lodash": "^4.17.14" } }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "async-mqtt": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async-mqtt/-/async-mqtt-2.6.1.tgz", - "integrity": "sha512-EkXAwRzwMaPC6ji0EvNeM5OMe6VjMhEKVJJUN7gu/hGzkcDpZtaI34nUwdwCMbjQB3pnuSOHqQMFKsUpg+D8kA==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async-mqtt/-/async-mqtt-2.6.3.tgz", + "integrity": "sha512-mFGTtlEpOugOoLOf9H5AJyJaZUNtOVXLGGOnPaPZDPQex6W6iIOgtV+fAgam0GQbgnLfgX+Wn/QzS6d+PYfFAQ==", "requires": { - "mqtt": "^4.1.0" + "mqtt": "^4.3.7" } }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, "auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==" }, + "auto-changelog": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/auto-changelog/-/auto-changelog-2.4.0.tgz", + "integrity": "sha512-vh17hko1c0ItsEcw6m7qPRf3m45u+XK5QyCrrBFViElZ8jnKrPC1roSznrd1fIB/0vR/zawdECCRJtTuqIXaJw==", + "dev": true, + "requires": { + "commander": "^7.2.0", + "handlebars": "^4.7.7", + "node-fetch": "^2.6.1", + "parse-github-url": "^1.0.2", + "semver": "^7.3.5" + } + }, "autoprefixer": { - "version": "9.8.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", - "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "version": "10.4.12", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.12.tgz", + "integrity": "sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==", "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001407", + "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "picocolors": "^0.2.1", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - } + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" } }, "axe-core": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz", - "integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==" + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz", + "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==" }, "axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "requires": { - "follow-redirects": "^1.14.4" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "axobject-query": { @@ -29747,59 +24362,42 @@ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, - "babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "requires": { - "babylon": "^6.18.0" - } - }, "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" } }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", + "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", "requires": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" + }, + "dependencies": { + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + } } }, "babel-plugin-dynamic-import-node": { @@ -29823,9 +24421,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -29834,47 +24432,27 @@ } }, "babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "requires": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - } + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" } }, "babel-plugin-named-asset-import": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "requires": {} + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==" }, "babel-plugin-polyfill-corejs2": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz", - "integrity": "sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "requires": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.3.0", + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", "semver": "^6.1.1" }, "dependencies": { @@ -29886,34 +24464,20 @@ } }, "babel-plugin-polyfill-corejs3": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz", - "integrity": "sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0", - "core-js-compat": "^3.18.0" + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" } }, "babel-plugin-polyfill-regenerator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz", - "integrity": "sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.3.0" - } - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" + "@babel/helper-define-polyfill-provider": "^0.3.3" } }, "babel-plugin-transform-react-remove-prop-types": { @@ -29941,11 +24505,11 @@ } }, "babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "requires": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -29970,46 +24534,8 @@ "@babel/runtime": "^7.16.3", "babel-plugin-macros": "^3.1.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24" - }, - "dependencies": { - "babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "requires": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - } } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, "bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -30020,30 +24546,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -30060,7 +24562,7 @@ "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" }, "bfj": { "version": "7.0.2", @@ -30086,17 +24588,7 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "bl": { "version": "4.1.0", @@ -30113,28 +24605,30 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -30146,58 +24640,25 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - }, - "dependencies": { - "dns-packet": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", - "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, "bonjour-service": { - "version": "git+https://npm@github.com/Hypfer/bonjour-service.git#113d63c3a07f739001198545d2a9c1043e9a5b0b", - "integrity": "sha512-KWHDLT0jX/3ipbHRYbXOCtKYuxFqQAStx0dDsvsHj5Q82lnoJbAVzCc3OIIuO6OHDi38WhwpNArTWpFS8e8w6g==", - "from": "bonjour-service@git+https://npm@github.com/Hypfer/bonjour-service#113d63c3a07f739001198545d2a9c1043e9a5b0b", + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", + "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", "requires": { "array-flatten": "^2.1.2", "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.3" + "multicast-dns": "^7.2.5" } }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "brace-expansion": { "version": "1.1.11", @@ -30231,11 +24692,6 @@ "unload": "2.2.0" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", @@ -30247,191 +24703,48 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "node-int64": "^0.4.0" } }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "requires": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==" - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==" }, "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==" }, "call-bind": { "version": "1.0.2", @@ -30445,30 +24758,7 @@ "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "requires": { - "caller-callsite": "^2.0.0" - } + "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==" }, "callsites": { "version": "3.1.0", @@ -30485,16 +24775,21 @@ }, "dependencies": { "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, "camelcase": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz", - "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" }, "camelcase-keys": { "version": "6.2.2", @@ -30527,22 +24822,14 @@ } }, "caniuse-lite": { - "version": "1.0.30001294", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz", - "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==" - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "requires": { - "rsvp": "^4.8.4" - } + "version": "1.0.30001419", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001419.tgz", + "integrity": "sha512-aFO1r+g6R7TW+PNQxKzjITwLOyDhVRLjW0LcwS/HCZGUUKTGNp9+IwLC4xyDSZBygVL/mxaFR3HIV6wEKQuSzw==" }, "case-sensitive-paths-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==" }, "ccount": { "version": "2.0.1", @@ -30564,14 +24851,14 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" }, "character-entities": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.1.tgz", - "integrity": "sha512-OzmutCf2Kmc+6DrFrrPS8/tDh2+DpnrfzdICHWhcVC9eOd0N1PXmQEE1a8iM4IziIAG+8tmTq3K+oo0ubH6RRQ==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" }, "check-types": { "version": "11.1.2", @@ -30579,34 +24866,35 @@ "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==" }, "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "readdirp": "~3.6.0" }, "dependencies": { - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } } } }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true }, "chrome-trace-event": { "version": "1.0.3", @@ -30614,116 +24902,23 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" }, "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", + "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" }, "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, "clean-css": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", - "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", + "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", "requires": { "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -30734,25 +24929,42 @@ } }, "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", "dev": true }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } } }, "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" }, "clone-deep": { "version": "4.0.1", @@ -30765,14 +24977,14 @@ } }, "clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==" }, "coa": { "version": "2.0.2", @@ -30813,17 +25025,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", @@ -30838,7 +25050,7 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true }, "collect-v8-coverage": { @@ -30846,24 +25058,6 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-4.0.1.tgz", - "integrity": "sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==", - "requires": { - "color-convert": "^2.0.1", - "color-string": "^1.6.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -30877,14 +25071,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } + "colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "combined-stream": { "version": "1.0.8", @@ -30900,14 +25095,14 @@ "integrity": "sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==" }, "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" }, "comment-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz", - "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", "dev": true }, "commist": { @@ -30917,15 +25112,13 @@ "requires": { "leven": "^2.1.0", "minimist": "^1.1.0" - }, - "dependencies": { - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" - } } }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, "common-tags": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", @@ -30934,20 +25127,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compose-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", - "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", - "requires": { - "arity-n": "^1.0.4" - } + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "compressible": { "version": "2.0.18", @@ -30971,11 +25151,6 @@ "vary": "~1.1.2" }, "dependencies": { - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -30987,14 +25162,14 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "2.0.0", @@ -31013,26 +25188,16 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" }, "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, "content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -31054,76 +25219,37 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.1.tgz", - "integrity": "sha512-btdpStYFQScnNVQ5slVcr858KP0YWYjV16eGJQw8Gg7CWtu/2qNvIM3qVRIR3n1pK2R9NNOrTevbvAYxajwEjg==" + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.5.tgz", + "integrity": "sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw==" }, "core-js-compat": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.1.tgz", - "integrity": "sha512-AVhKZNpqMV3Jz8hU0YEXXE06qoxtQGsAqU0u1neUngz5IusDJRX/ZJ6t3i7mS7QxNyEONbCo14GprkBrxPlTZA==", + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz", + "integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==", "requires": { - "browserslist": "^4.19.1", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" - } + "browserslist": "^4.21.4" } }, "core-js-pure": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.20.1.tgz", - "integrity": "sha512-yeNNr3L9cEBwNy6vhhIJ0nko7fE7uFO6PgawcacGt2VWep4WqQx0RiqlkgSP7kqUMC1IKdfO9qPeWXcUheHLVQ==" + "version": "3.25.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz", + "integrity": "sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg==" }, "core-util-is": { "version": "1.0.3", @@ -31149,54 +25275,44 @@ } } }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "requires": { - "buffer": "^5.1.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "cra-build-watch": { + "version": "git+https://npm@github.com/Hypfer/cra-build-watch.git#1281e987bb3ad0bc3c0d3d40078a6b5ab6fb67d4", + "dev": true, + "from": "cra-build-watch@git+https://npm@github.com/Hypfer/cra-build-watch.git#5.0.0", "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" + "cross-spawn": "7.0.3", + "fs-extra": "9.0.1", + "html-webpack-plugin": "5.5.0", + "import-cwd": "3.0.0", + "meow": "8.0.0", + "ora": "4.0.3", + "semver": "^7.1.1" }, "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true } } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } + "crc": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-4.1.1.tgz", + "integrity": "sha512-2U3ZqJ2phJl9ANuP2q5VS53LMpNmYU9vcpmh6nutJmsqUREhtWpTRh9yYxG7sDg3xkwaEEXytSeffTxw4cgwPg==" }, "cross-env": { "version": "7.0.3", @@ -31220,144 +25336,107 @@ "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" }, "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } + "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==" }, "css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "requires": { - "postcss": "^7.0.5" + "postcss-selector-parser": "^6.0.9" } }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" - }, "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - } + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==" }, "css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "postcss-selector-parser": "^6.0.9" } }, "css-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", - "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", - "requires": { - "camelcase": "^6.0.0", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^2.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.3", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.1", - "semver": "^7.3.2" + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" + } + }, + "css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "requires": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" }, "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } } } }, "css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", - "requires": { - "postcss": "^7.0.5" - } + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==" }, "css-select": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", - "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "requires": { "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } @@ -31374,24 +25453,17 @@ "requires": { "mdn-data": "2.0.4", "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, "css-what": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", - "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" }, "cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.0.1.tgz", + "integrity": "sha512-pT3nzyGM78poCKLAEy2zWIVX2hikq6dIrjuZzLV98MumBg+xMTNYfHx7paUlfiRTgg91O/vR889CIf+qiv79Rw==" }, "cssesc": { "version": "3.0.0", @@ -31399,111 +25471,62 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" }, "cssnano": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", - "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "version": "5.1.13", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.13.tgz", + "integrity": "sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ==", "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.8", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" + "cssnano-preset-default": "^5.2.12", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" }, "dependencies": { - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" } } }, "cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" + "version": "5.2.12", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz", + "integrity": "sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew==", + "requires": { + "css-declaration-sorter": "^6.3.0", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.2", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.6", + "postcss-merge-rules": "^5.1.2", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.3", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + } + }, + "cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==" }, "csso": { "version": "4.2.0", @@ -31526,11 +25549,6 @@ "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -31555,33 +25573,19 @@ } }, "csstype": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz", - "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, "dag-map": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/dag-map/-/dag-map-1.0.2.tgz", - "integrity": "sha1-6DefBBAA7VYfxRVHXB7SyF7s6Nc=" + "integrity": "sha512-+LSAiGFwQ9dRnRdOeaj7g47ZFJcOUPukAP8J3A3fuZ1g9Y44BG+P1sgApjLXTQPOzC4+7S9Wr8kXsfpINM4jpw==" }, "damerau-levenshtein": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz", - "integrity": "sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" }, "data-urls": { "version": "2.0.0", @@ -31619,59 +25623,61 @@ } }, "date-fns": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.26.0.tgz", - "integrity": "sha512-VQI812dRi3cusdY/fhoBKvc6l2W8BPWU1FNVnFH9Nttjx4AFBRzfSVb/Eyc7jBT6e9sg1XtAGsYpBQ6c/jygbg==" + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "requires": { "ms": "2.1.2" } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true }, "decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", "dev": true, "requires": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" }, "dependencies": { + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true } } }, "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" }, "decode-named-character-reference": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.1.tgz", - "integrity": "sha512-YV/0HQHreRwKb7uBopyIkLG17jG6Sv2qUchk9qSoVJ2f+flwRsPNBO0hAnjt6mTNYUT+vw9Gy2ihXg4sUWPi2w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", "requires": { "character-entities": "^2.0.0" } }, - "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=" - }, "decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", @@ -31684,20 +25690,7 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" }, "deep-extend": { "version": "0.6.0", @@ -31716,98 +25709,17 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } + "execa": "^5.0.0" } }, "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, "requires": { "clone": "^1.0.2" @@ -31816,123 +25728,60 @@ "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true } } }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } + "defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==" }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "dev": true }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "dequal": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true }, "detect-newline": { @@ -31965,37 +25814,34 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, + "detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "requires": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" }, "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==" }, "dir-glob": { "version": "3.0.1", @@ -32005,27 +25851,24 @@ "path-type": "^4.0.0" } }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, "dns-packet": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", - "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", "requires": { "@leichtgewicht/ip-codec": "^2.0.1" } }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "requires": { - "buffer-indexof": "^1.0.0" - } - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -32052,24 +25895,19 @@ } }, "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "requires": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" - }, "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" }, "domexception": { "version": "2.0.1", @@ -32087,9 +25925,9 @@ } }, "domhandler": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", - "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "requires": { "domelementtype": "^2.2.0" } @@ -32114,31 +25952,16 @@ }, "dependencies": { "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" - } - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "requires": { - "is-obj": "^2.0.0" - }, - "dependencies": { - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" }, "dotenv-expand": { "version": "5.1.0", @@ -32164,43 +25987,25 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==" - }, - "electron-to-chromium": { - "version": "1.4.29", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.29.tgz", - "integrity": "sha512-N2Jbwxo5Rum8G2YXeUxycs1sv4Qme/ry71HG73bv8BvZl+I/4JtRgK/En+ST/Wh/yF1fqvVCY4jZBgMxnhjtBA==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } + "jake": "^10.8.5" } }, + "electron-to-chromium": { + "version": "1.4.281", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.281.tgz", + "integrity": "sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==" + }, "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==" }, "emoji-regex": { "version": "8.0.0", @@ -32215,7 +26020,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -32226,54 +26031,12 @@ } }, "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "requires": { - "ansi-colors": "^4.1.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" } }, "entities": { @@ -32281,14 +26044,6 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "requires": { - "prr": "~1.0.1" - } - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -32298,38 +26053,60 @@ } }, "error-stack-parser": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", - "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", "requires": { - "stackframe": "^1.1.1" + "stackframe": "^1.3.4" } }, "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "requires": { + "has": "^1.0.3" } }, "es-to-primitive": { @@ -32342,35 +26119,6 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -32379,7 +26127,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "4.0.0", @@ -32401,7 +26149,7 @@ "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -32423,18 +26171,12 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==" }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "requires": { "prelude-ls": "~1.1.2" } @@ -32442,64 +26184,82 @@ } }, "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "version": "8.25.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.25.0.tgz", + "integrity": "sha512-DVlJOZ4Pn50zcKW5bYH7GQK/9MsoQG2d5eDH0ebEkE8PbgzTTmtt/VTH9GGJ4BfeZCpBLqFfvsjX35UacUL83A==", "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.10.5", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", + "find-up": "^5.0.0", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } } } }, + "eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "requires": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + } + }, "eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -32520,13 +26280,11 @@ } }, "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "debug": "^3.2.7" }, "dependencies": { "debug": { @@ -32536,79 +26294,63 @@ "requires": { "ms": "^2.1.1" } - }, - "find-up": { + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "eslint-visitor-keys": "^1.1.0" } }, - "p-limit": { + "eslint-visitor-keys": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true } } }, "eslint-plugin-flowtype": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz", - "integrity": "sha512-vcz32f+7TP+kvTUyMXZmCnNujBQZDNmcqPImw8b9PZ+16w1Qdm6ryRuYZYVaG9xRqqmAPr2Cs9FAX5gN+x/bjw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", "requires": { - "lodash": "^4.17.15", + "lodash": "^4.17.21", "string-natural-compare": "^3.0.1" } }, "eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "requires": { "array-includes": "^3.1.4", "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "dependencies": { "debug": { @@ -32630,50 +26372,62 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, + "eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "requires": { + "@typescript-eslint/experimental-utils": "^5.0.0" + } + }, "eslint-plugin-jsdoc": { - "version": "37.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.0.3.tgz", - "integrity": "sha512-Qg/gIZAfcrM4Qu/JzcnxPGD45Je6wPLFzMZQboeqit/CL4aY6wuzBTkgUMiWXfw/PaPl+sb0GF1XdBlV23ReDA==", + "version": "39.3.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", + "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "0.12.0", - "comment-parser": "1.2.4", - "debug": "^4.3.2", + "@es-joy/jsdoccomment": "~0.31.0", + "comment-parser": "1.3.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "^2.0.0", - "lodash": "^4.17.21", - "regextras": "^0.8.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "spdx-expression-parse": "^3.0.1" } }, "eslint-plugin-jsx-a11y": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz", - "integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", "requires": { - "@babel/runtime": "^7.16.3", + "@babel/runtime": "^7.18.9", "aria-query": "^4.2.2", - "array-includes": "^3.1.4", + "array-includes": "^3.1.5", "ast-types-flow": "^0.0.7", - "axe-core": "^4.3.5", + "axe-core": "^4.4.3", "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.7", + "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "has": "^1.0.3", - "jsx-ast-utils": "^3.2.1", + "jsx-ast-utils": "^3.3.2", "language-tags": "^1.0.5", - "minimatch": "^3.0.4" + "minimatch": "^3.1.2", + "semver": "^6.3.0" }, "dependencies": { "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -32691,16 +26445,21 @@ "semver": "^6.1.0" }, "dependencies": { - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" + "eslint-visitor-keys": "^1.1.0" } }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -32710,24 +26469,24 @@ } }, "eslint-plugin-react": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.27.1.tgz", - "integrity": "sha512-meyunDjMMYeWr/4EBLTV1op3iSG3mjT/pz5gti38UzfM4OPpNc2m0t2xvKCOMU5D6FSdd34BIMFOvQbW+i8GAA==", + "version": "7.31.10", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz", + "integrity": "sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==", "requires": { - "array-includes": "^3.1.4", - "array.prototype.flatmap": "^1.2.5", + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", "doctrine": "^2.1.0", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.entries": "^1.1.5", "object.fromentries": "^2.0.5", - "object.hasown": "^1.1.0", + "object.hasown": "^1.1.1", "object.values": "^1.1.5", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "resolve": "^2.0.0-next.3", "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.6" + "string.prototype.matchall": "^4.0.7" }, "dependencies": { "doctrine": { @@ -32739,12 +26498,13 @@ } }, "resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "semver": { @@ -32755,15 +26515,14 @@ } }, "eslint-plugin-react-hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz", - "integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==", - "requires": {} + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==" }, "eslint-plugin-regexp": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.5.1.tgz", - "integrity": "sha512-5v0rQIi54m2KycQHqmOAHrZhvI56GHmI2acr6zEffAqfeifTtobAEapv9Uf4o8//lGvwVkHKyjLoSbBNEFcfOA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-1.9.0.tgz", + "integrity": "sha512-Che49IZ07w9KcKvrMiqfwBYv44VBunA4NqUo+UTLluYbCos9Du3+pnhkPTLTAx6ZoZ1Rmz7u7o2iC6g6qCuvxw==", "dev": true, "requires": { "comment-parser": "^1.1.2", @@ -32771,26 +26530,9 @@ "grapheme-splitter": "^1.0.4", "jsdoctypeparser": "^9.0.0", "refa": "^0.9.0", - "regexp-ast-analysis": "^0.3.0", + "regexp-ast-analysis": "^0.5.1", "regexpp": "^3.2.0", "scslre": "^0.1.6" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } } }, "eslint-plugin-sort-keys-fix": { @@ -32805,6 +26547,12 @@ "requireindex": "~1.2.0" }, "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", @@ -32830,66 +26578,11 @@ "from": "eslint-plugin-sort-requires@git+https://npm@github.com/Hypfer/eslint-plugin-sort-requires.git#2.1.1" }, "eslint-plugin-testing-library": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz", - "integrity": "sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.7.2.tgz", + "integrity": "sha512-0ZmHeR/DUUgEzW8rwUBRWxuqntipDtpvxK0hymdHnLlABryJkzd+CAHr+XnISaVsTisZ5MLHp6nQF+8COHLLTA==", "requires": { - "@typescript-eslint/experimental-utils": "^3.10.1" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz", - "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==", - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.10.1", - "@typescript-eslint/typescript-estree": "3.10.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/types": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz", - "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==" - }, - "@typescript-eslint/typescript-estree": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz", - "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==", - "requires": { - "@typescript-eslint/types": "3.10.1", - "@typescript-eslint/visitor-keys": "3.10.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz", - "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==", - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - } + "@typescript-eslint/utils": "^5.13.0" } }, "eslint-scope": { @@ -32909,68 +26602,97 @@ } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" } } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", - "dev": true + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" }, "eslint-webpack-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.6.0.tgz", - "integrity": "sha512-V+LPY/T3kur5QO3u+1s34VDTcRxjXWPUGM4hlmTb5DwVD0OQz631yGTxJZf4SpAqAjdbBVe978S8BJeHpAdOhQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", "requires": { - "@types/eslint": "^7.28.2", - "arrify": "^2.0.1", - "jest-worker": "^27.3.1", - "micromatch": "^4.0.4", + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "schema-utils": "^3.1.1" + "schema-utils": "^4.0.0" }, "dependencies": { - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "requires": { + "has-flag": "^4.0.0" } } } }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, + "espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -33010,7 +26732,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "eventemitter3": { "version": "4.0.7", @@ -33022,146 +26744,26 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" }, - "eventsource": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", - "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==" - }, "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==" }, "expand-template": { "version": "2.0.3", @@ -33170,50 +26772,49 @@ "dev": true }, "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" } }, "express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -33222,29 +26823,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", - "requires": { - "bytes": "3.1.1", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" - } - }, - "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "debug": { "version": "2.6.9", @@ -33254,48 +26833,15 @@ "ms": "2.0.0" } }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==" - }, - "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", - "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" } } }, @@ -33321,92 +26867,40 @@ "integrity": "sha512-1I30bSVego+AU/eSsX/bV2xrOXW5tFhsuXZp7wZd9396bAAxH7KHaAwLXQYra0Aw33xA67HmNiceGf2SOvXaLg==" }, "express-rate-limit": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz", - "integrity": "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==" - }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "requires": { - "type": "^2.5.0" - }, - "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" - } - } + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.6.0.tgz", + "integrity": "sha512-HFN2+4ZGdkQOS8Qli4z6knmJFnw6lZed67o6b7RGplWeb1Z0s8VXaj3dUgPIdm9hrhZXTRpCTHXA0/2Eqex0vA==" }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - } - } - }, "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==" }, "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } } }, "fast-json-stable-stringify": { @@ -33417,7 +26911,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "fastq": { "version": "1.13.0", @@ -33436,18 +26930,13 @@ } }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "requires": { "bser": "2.1.1" } }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -33457,46 +26946,44 @@ } }, "file-loader": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz", - "integrity": "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "requires": { + "minimatch": "^5.0.1" }, "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "balanced-match": "^1.0.0" } }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "brace-expansion": "^2.0.1" } } } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "filesize": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", - "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==" + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==" }, "fill-range": { "version": "7.0.1", @@ -33507,16 +26994,16 @@ } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "dependencies": { @@ -33531,58 +27018,18 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "requires": { "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - } - } + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, "find-root": { @@ -33591,30 +27038,19 @@ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "requires": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - } - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "flat-cache": { "version": "3.0.4", @@ -33626,232 +27062,73 @@ } }, "flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==" - }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, "follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, "fork-ts-checker-webpack-plugin": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz", - "integrity": "sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", + "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", "requires": { - "@babel/code-frame": "^7.5.5", - "chalk": "^2.4.1", - "micromatch": "^3.1.10", + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", "minimatch": "^3.0.4", - "semver": "^5.6.0", - "tapable": "^1.0.0", - "worker-rpc": "^0.1.0" + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", "requires": { - "color-name": "1.1.3" + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" } }, - "color-name": { + "tapable": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" } } }, "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -33863,23 +27140,21 @@ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dev": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -33889,6 +27164,7 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -33903,6 +27179,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -33926,53 +27203,15 @@ "universalify": "^2.0.0" } }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.3.2", @@ -33985,15 +27224,26 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", "dev": true, "requires": { "aproba": "^1.0.3", @@ -34009,33 +27259,13 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -34054,13 +27284,13 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-own-enumerable-property-symbols": { @@ -34074,12 +27304,9 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" }, "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" }, "get-symbol-description": { "version": "1.0.0", @@ -34090,15 +27317,10 @@ "get-intrinsic": "^1.1.1" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "dev": true }, "glob": { @@ -34115,13 +27337,18 @@ } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -34151,56 +27378,42 @@ } }, "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "requires": { "type-fest": "^0.20.2" } }, "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "grapheme-splitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "optional": true + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" }, "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" + "duplexer": "^0.1.2" } }, "handle-thing": { @@ -34208,6 +27421,19 @@ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -34228,19 +27454,27 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, "has-tostringtag": { "version": "1.0.0", @@ -34253,81 +27487,12 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } + "hashlru": { + "version": "git+https://npm@github.com/Hypfer/hashlru.git#fe8e672b925362de984567f2feb3b5db3ec87032", + "from": "hashlru@git+https://npm@github.com/Hypfer/hashlru#3.0.0" }, "hast-to-hyperscript": { "version": "10.0.1", @@ -34367,9 +27532,9 @@ } }, "hast-util-raw": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.1.tgz", - "integrity": "sha512-wgtppqXVdXzkDXDFclLLdAyVUJSKMYYi6LWIAbA8oFqEdwksYIcPGM3RkKV1Dfn5GElvxhaOCs0jmCOMayxd3A==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.2.tgz", + "integrity": "sha512-0x3BhhdlBcqRIKyc095lBSDvmQNMY3Eulj2PLsT5XCyKYrxssI5yr3P4Kv/PBo1s/DMkZy2voGkMXECnFCZRLQ==", "requires": { "@types/hast": "^2.0.0", "@types/parse5": "^6.0.0", @@ -34403,9 +27568,9 @@ "integrity": "sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==" }, "hastscript": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.0.2.tgz", - "integrity": "sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.1.0.tgz", + "integrity": "sha512-uBjaTTLN0MkCZxY/R2fWUOcu7FRtUVzKRO5P/RAfgsu3yFiMB1JWCO4AjeVkgHxAira1f2UecHK5WfS9QurlWA==", "requires": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^2.0.0", @@ -34428,11 +27593,6 @@ "readable-stream": "^3.6.0" } }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" - }, "history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -34446,16 +27606,6 @@ "value-equal": "^1.0.1" } }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -34470,9 +27620,9 @@ "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" }, "hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -34481,7 +27631,7 @@ "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "requires": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -34513,16 +27663,6 @@ } } }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" - }, "html-encoding-sniffer": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", @@ -34532,9 +27672,9 @@ } }, "html-entities": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", - "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" }, "html-escaper": { "version": "2.0.2", @@ -34542,23 +27682,23 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", "requires": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", "he": "^1.2.0", - "param-case": "^3.0.3", + "param-case": "^3.0.4", "relateurl": "^0.2.7", - "terser": "^4.6.3" + "terser": "^5.10.0" }, "dependencies": { "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" } } }, @@ -34567,6 +27707,18 @@ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==" }, + "html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, "htmlparser2": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", @@ -34581,36 +27733,24 @@ "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - } + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, "http-parser-js": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", - "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==" + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, "http-proxy": { "version": "1.18.1", @@ -34633,136 +27773,37 @@ } }, "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" }, "dependencies": { - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-number": { + "is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" } } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "requires": { "agent-base": "6", "debug": "4" } }, "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, "iconv-lite": { "version": "0.4.24", @@ -34773,17 +27814,19 @@ } }, "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "requires": { - "postcss": "^7.0.14" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==" + }, + "idb": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.0.tgz", + "integrity": "sha512-Wsk07aAxDsntgYJY4h0knZJuTxM73eQ4reRAO+Z1liOh8eMCJ/MoDS8fCui1vGT9mnjtl1sOu3I2i/W1swPYZg==" }, "identity-obj-proxy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", "requires": { "harmony-reflect": "^1.4.6" } @@ -34793,20 +27836,15 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, "immer": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", - "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==" + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" }, "import-cwd": { "version": "3.0.0", @@ -34844,48 +27882,29 @@ } }, "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - } } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -34906,15 +27925,6 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, "internal-slot": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", @@ -34935,47 +27945,15 @@ "p-is-promise": "^3.0.0" } }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-bigint": { "version": "1.0.4", @@ -34989,7 +27967,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, "requires": { "binary-extensions": "^2.0.0" } @@ -35009,47 +27986,18 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "requires": { "has": "^1.0.3" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -35058,43 +28006,24 @@ "has-tostringtag": "^1.0.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" - }, "is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-generator-fn": { "version": "2.1.0", @@ -35123,7 +28052,7 @@ "is-invalid-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", - "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=", + "integrity": "sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==", "requires": { "is-glob": "^2.0.0" }, @@ -35131,12 +28060,12 @@ "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==" }, "is-glob": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==", "requires": { "is-extglob": "^1.0.0" } @@ -35146,7 +28075,7 @@ "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" }, "is-negative-zero": { "version": "2.0.2", @@ -35159,9 +28088,9 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "requires": { "has-tostringtag": "^1.0.0" } @@ -35169,33 +28098,13 @@ "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "requires": { - "path-is-inside": "^1.0.2" - } + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==" }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true }, "is-plain-object": { "version": "2.0.4", @@ -35222,12 +28131,7 @@ "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==" }, "is-root": { "version": "2.1.0", @@ -35235,9 +28139,12 @@ "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } }, "is-stream": { "version": "2.0.1", @@ -35263,12 +28170,18 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true }, "is-valid-path": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", - "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=", + "integrity": "sha512-+kwPrVDu9Ms03L90Qaml+79+6DZHqHyRoANI6IsZJ/g8frhnfchDOBCa0RbQ6/kdHt5CS5OeIEyrYznNuVN+8A==", "requires": { "is-invalid-path": "^0.1.0" } @@ -35281,11 +28194,6 @@ "call-bind": "^1.0.2" } }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -35297,17 +28205,17 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -35315,9 +28223,9 @@ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" }, "istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "requires": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -35341,21 +28249,6 @@ "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } } }, "istanbul-lib-source-maps": { @@ -35366,598 +28259,671 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, "istanbul-reports": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.2.tgz", - "integrity": "sha512-0gHxuT1NNC0aEIL1zbJ+MTgPbbHhU77eJPuU35WKA7TgXiSNlCAx4PENoMrH0Or6M2H80TaZcWKhM0IK6V8gRw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, + "jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + } + } + }, "jest": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz", - "integrity": "sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "requires": { - "@jest/core": "^26.6.0", + "@jest/core": "^27.5.1", "import-local": "^3.0.2", - "jest-cli": "^26.6.0" + "jest-cli": "^27.5.1" } }, "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" } }, "jest-circus": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.6.0.tgz", - "integrity": "sha512-L2/Y9szN6FJPWFK8kzWXwfp+FOR7xq0cUL4lIsdbIdwz3Vh6P1nrpcqOleSzr28zOtSHQNV9Z7Tl+KkuK7t5Ng==", - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.0", - "@jest/test-result": "^26.6.0", - "@jest/types": "^26.6.0", - "@types/babel__traverse": "^7.0.4", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", - "expect": "^26.6.0", + "expect": "^27.5.1", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.0", - "jest-matcher-utils": "^26.6.0", - "jest-message-util": "^26.6.0", - "jest-runner": "^26.6.0", - "jest-runtime": "^26.6.0", - "jest-snapshot": "^26.6.0", - "jest-util": "^26.6.0", - "pretty-format": "^26.6.0", - "stack-utils": "^2.0.2", - "throat": "^5.0.0" + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" } }, "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "dependencies": { - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - } - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - } + "yargs": "^16.2.0" + } + }, + "jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "requires": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" } }, "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" } }, "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" } }, "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==" + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==" }, "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", "walker": "^1.0.7" - }, - "dependencies": { - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - } } }, "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.6.2", + "expect": "^27.5.1", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" } }, "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" } }, "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/node": "*" } }, "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "requires": {} + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==" }, "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==" + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==" }, "jest-resolve": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.0.tgz", - "integrity": "sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", "requires": { - "@jest/types": "^26.6.0", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.0", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" } }, "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "requires": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "dependencies": { - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - } - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - } + "throat": "^6.0.1" } }, "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", + "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", + "execa": "^5.0.0", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "dependencies": { - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - } - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - } + "strip-bom": "^4.0.0" } }, "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "requires": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" } }, "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "requires": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", + "pretty-format": "^27.5.1", "semver": "^7.3.2" - }, - "dependencies": { - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - } } }, "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" } }, "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", + "jest-get-type": "^27.5.1", "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "pretty-format": "^27.5.1" + }, + "dependencies": { + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + } } }, "jest-watch-typeahead": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.6.1.tgz", - "integrity": "sha512-ITVnHhj3Jd/QkqQcTqZfRgjfyRhDFM/auzgVo2RKvSwi18YMvh0WvXDJFoFED6c7jd/5jxtu4kSOb9PTu2cPVg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", "requires": { "ansi-escapes": "^4.3.1", "chalk": "^4.0.0", - "jest-regex-util": "^26.0.0", - "jest-watcher": "^26.3.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0" + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + } + } + }, + "@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "requires": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "requires": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + }, + "emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==" + }, + "jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + } + } + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==" + }, + "jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "requires": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "dependencies": { + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + }, + "string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "requires": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==" + } + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "requires": { + "ansi-regex": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + } + } + } } }, "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "jest-util": "^27.5.1", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "requires": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -35974,6 +28940,11 @@ } } }, + "js-sdsl": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==" + }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -35985,18 +28956,17 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsdoc-type-pratt-parser": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.2.tgz", - "integrity": "sha512-gXN5CxeaI9WtYQYzpOO/CtTRfZppQlKxXRTIm73JuAX6kOGTQ7iZ0e+YB+b2m7Fk+gTYYxRtE1nqje7H6dqv8w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", + "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", "dev": true }, "jsdoctypeparser": { @@ -36039,10 +29009,15 @@ "xml-name-validator": "^3.0.0" }, "dependencies": { - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } }, "tr46": { "version": "2.1.0", @@ -36069,21 +29044,26 @@ } } }, + "jsencrypt": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.2.1.tgz", + "integrity": "sha512-k1sD5QV0KPn+D8uG9AdGzTQuamt82QZ3A3l6f7TRwMU6Oi2Vg0BsL+wZIQBONcraO1pc78ExMdvmBBJ8WhNYUA==" + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, "json-schema-deref-sync": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/json-schema-deref-sync/-/json-schema-deref-sync-0.14.0.tgz", @@ -36100,27 +29080,19 @@ } }, "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==" + "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", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" }, "jsonfile": { "version": "6.1.0", @@ -36131,25 +29103,25 @@ "universalify": "^2.0.0" } }, + "jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==" + }, "jstoxml": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-2.2.7.tgz", - "integrity": "sha512-cvnnvXSwQo1NcgfuNnHFrCPKG3o0JPrqC1gf6NhAM1UejLsEzcGcmn223iF6XdMf+7RCW/GYv12Ako3ivPamBw==" + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-3.2.5.tgz", + "integrity": "sha512-MxJI8rcCTAeYgxW9a61i/jfK9KjVKpqbStoAf4QADXJ9jTLbh9KMM9A0qxcIRxxkopr6Ba6Wm68pxA6zBZpe+Q==" }, "jsx-ast-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", - "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", "requires": { - "array-includes": "^3.1.3", - "object.assign": "^4.1.2" + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" } }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -36166,31 +29138,22 @@ "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" }, "language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==" + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" }, "language-tags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "requires": { "language-subtag-registry": "~0.3.2" } }, - "last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "requires": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==" }, "levn": { "version": "0.4.1", @@ -36201,42 +29164,37 @@ "type-check": "~0.4.0" } }, + "lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" + }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", + "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - } + "json5": "^2.1.2" } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "requires": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -36244,30 +29202,25 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, "lodash.merge": { "version": "4.6.2", @@ -36280,105 +29233,26 @@ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" } }, - "loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==" - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -36406,9 +29280,9 @@ }, "dependencies": { "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, @@ -36421,26 +29295,25 @@ } }, "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", "requires": { - "sourcemap-codec": "^1.4.4" + "sourcemap-codec": "^1.4.8" } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -36452,25 +29325,12 @@ "tmpl": "1.0.5" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, "map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, "markdown-table": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.2.tgz", @@ -36488,53 +29348,31 @@ "md5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", - "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "integrity": "sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==", "requires": { "charenc": "~0.0.1", "crypt": "~0.0.1", "is-buffer": "~1.1.1" } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "mdast-util-definitions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.0.tgz", - "integrity": "sha512-5hcR7FL2EuZ4q6lLMUK5w4lHT2H3vqL9quPvYZ/Ku5iifrirfMHiGdhxdXMUbUkDmz5I+TYMd7nbaxUhbQkfpQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz", + "integrity": "sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "unist-util-visit": "^3.0.0" - }, - "dependencies": { - "unist-util-visit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", - "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" - } - } + "unist-util-visit": "^4.0.0" } }, "mdast-util-find-and-replace": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.1.0.tgz", - "integrity": "sha512-1w1jbqAd13oU78QPBf5223+xB+37ecNtQ1JElq2feWols5oEYAl+SgNDnOZipe7NfLemoEt362yUS15/wip4mw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.1.tgz", + "integrity": "sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==", "requires": { "escape-string-regexp": "^5.0.0", "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^4.0.0" + "unist-util-visit-parents": "^5.0.0" }, "dependencies": { "escape-string-regexp": { @@ -36564,15 +29402,17 @@ } }, "mdast-util-gfm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.0.tgz", - "integrity": "sha512-wMwejlTN3EQADPFuvxe8lmGsay3+f6gSJKdAHR6KBJzpcxvsjJSILB9K6u6G7eQLC7iOTyVIHYGui9uBc9r1Tg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.1.tgz", + "integrity": "sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==", "requires": { + "mdast-util-from-markdown": "^1.0.0", "mdast-util-gfm-autolink-literal": "^1.0.0", "mdast-util-gfm-footnote": "^1.0.0", "mdast-util-gfm-strikethrough": "^1.0.0", "mdast-util-gfm-table": "^1.0.0", - "mdast-util-gfm-task-list-item": "^1.0.0" + "mdast-util-gfm-task-list-item": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" } }, "mdast-util-gfm-autolink-literal": { @@ -36587,53 +29427,54 @@ } }, "mdast-util-gfm-footnote": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.0.tgz", - "integrity": "sha512-qeg9YoS2YYP6OBmMyUFxKXb6BLwAsbGidIxgwDAXHIMYZQhIwe52L9BSJs+zP29Jp5nSERPkmG3tSwAN23/ZbQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.1.tgz", + "integrity": "sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==", "requires": { "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "unist-util-visit": "^4.0.0" + "mdast-util-to-markdown": "^1.3.0", + "micromark-util-normalize-identifier": "^1.0.0" } }, "mdast-util-gfm-strikethrough": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.0.tgz", - "integrity": "sha512-gM9ipBUdRxYa6Yq1Hd8Otg6jEn/dRxFZ1F9ZX4QHosHOexLGqNZO2dh0A+YFbUEd10RcKjnjb4jOfJJzoXXUew==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.1.tgz", + "integrity": "sha512-zKJbEPe+JP6EUv0mZ0tQUyLQOC+FADt0bARldONot/nefuISkaZFlmVK4tU6JgfyZGrky02m/I6PmehgAgZgqg==", "requires": { - "@types/mdast": "^3.0.3", - "mdast-util-to-markdown": "^1.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" } }, "mdast-util-gfm-table": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.2.tgz", - "integrity": "sha512-pPekvCTChFBF8uCq8bVyQwar8NBU/TaXIy44jj/UzmjMgPBHIa1B1ge8a0JVgzhqgXQAMvGT+PgiKlicdLGfDQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.6.tgz", + "integrity": "sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==", "requires": { + "@types/mdast": "^3.0.0", "markdown-table": "^3.0.0", - "mdast-util-to-markdown": "^1.0.0" + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.3.0" } }, "mdast-util-gfm-task-list-item": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.0.tgz", - "integrity": "sha512-dwkzOTjQe8JCCHVE3Cb0pLHTYLudf7t9WCAnb20jI8/dW+VHjgWhjtIUVA3oigNkssgjEwX+i+3XesUdCnXGyA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.1.tgz", + "integrity": "sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==", "requires": { - "@types/mdast": "^3.0.3", - "mdast-util-to-markdown": "^1.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.3.0" } }, "mdast-util-to-hast": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-11.3.0.tgz", - "integrity": "sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw==", + "version": "12.2.4", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.2.4.tgz", + "integrity": "sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg==", "requires": { "@types/hast": "^2.0.0", "@types/mdast": "^3.0.0", - "@types/mdurl": "^1.0.0", "mdast-util-definitions": "^5.0.0", - "mdurl": "^1.0.0", + "micromark-util-sanitize-uri": "^1.1.0", + "trim-lines": "^3.0.0", "unist-builder": "^3.0.0", "unist-util-generated": "^2.0.0", "unist-util-position": "^4.0.0", @@ -36641,9 +29482,9 @@ } }, "mdast-util-to-markdown": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.6.tgz", - "integrity": "sha512-doJZmTEGagHypWvJ8ltinmwUsT9ZaNgNIQW6Gl7jNdsI1QZkTHTimYW561Niy2s8AEPAqEgV0dIh2UOVlSXUJA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz", + "integrity": "sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -36664,53 +29505,23 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "memfs": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", + "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "requires": { + "fs-monkey": "^1.0.3" + } }, "memory-cache": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", - "integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo=" - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } + "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" }, "meow": { "version": "8.0.0", @@ -36742,7 +29553,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-stream": { "version": "2.0.0", @@ -36757,17 +29568,12 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "microevent.ts": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", - "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "micromark": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.0.10.tgz", - "integrity": "sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.1.0.tgz", + "integrity": "sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==", "requires": { "@types/debug": "^4.0.0", "debug": "^4.0.0", @@ -36839,9 +29645,9 @@ } }, "micromark-extension-gfm-footnote": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.3.tgz", - "integrity": "sha512-bn62pC5y39rIo2g1RqZk1NhF7T7cJLuJlbevunQz41U0iPVCdVOFASe5/L1kke+DFKSgfCRhv24+o42cZ1+ADw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.0.4.tgz", + "integrity": "sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==", "requires": { "micromark-core-commonmark": "^1.0.0", "micromark-factory-space": "^1.0.0", @@ -36849,6 +29655,7 @@ "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-sanitize-uri": "^1.0.0", "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", "uvu": "^0.5.0" } }, @@ -37011,9 +29818,9 @@ "integrity": "sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==" }, "micromark-util-html-tag-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.0.0.tgz", - "integrity": "sha512-NenEKIshW2ZI/ERv9HtFNsrn3llSPZtY337LID/24WeLqMzeZhBEE6BQ0vS2ZBjshm5n40chKtJ3qjAbVV8S0g==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz", + "integrity": "sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==" }, "micromark-util-normalize-identifier": { "version": "1.0.0", @@ -37032,9 +29839,9 @@ } }, "micromark-util-sanitize-uri": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz", - "integrity": "sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz", + "integrity": "sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==", "requires": { "micromark-util-character": "^1.0.0", "micromark-util-encode": "^1.0.0", @@ -37063,12 +29870,12 @@ "integrity": "sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==" }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "microseconds": { @@ -37076,38 +29883,22 @@ "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "requires": { - "mime-db": "1.51.0" + "mime-db": "1.52.0" } }, "mimic-fn": { @@ -37137,24 +29928,41 @@ } }, "mini-css-extract-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", - "integrity": "sha512-n9BA8LonkOkW1/zn+IbLPQmovsL0wMb9yx75fMJQZf2X1Zoec9yTZtyMePcyu19wPkmFbzZZA6fLTotpFhQsOA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", + "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" + "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==", + "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", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } } } @@ -37164,15 +29972,10 @@ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "requires": { "brace-expansion": "^1.1.7" } @@ -37193,477 +29996,121 @@ "kind-of": "^6.0.3" }, "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true } } }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "requires": { - "minipass": "^3.0.0" + "minimist": "^1.2.6" } }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", + "dev": true, "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.4", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "5.0.1", + "ms": "2.1.3", + "nanoid": "3.3.3", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "workerpool": "6.2.1", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "balanced-match": "^1.0.0" } }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "minimatch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "dev": true, "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" + "brace-expansion": "^2.0.1" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "has-flag": "^4.0.0" } } } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "mocha": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz", - "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.3", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "mqtt": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz", - "integrity": "sha512-DJYjlXODVXtSDecN8jnNzi6ItX3+ufGsEs9OB3YV24HtkRrh7kpx8L5M1LuyF0KzaiGtWr2PzDcMGAY60KGOSA==", - "requires": { - "commist": "^1.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.1.1", - "duplexify": "^4.1.1", - "help-me": "^3.0.0", - "inherits": "^2.0.3", - "minimist": "^1.2.5", - "mqtt-packet": "^6.8.0", - "pump": "^3.0.0", - "readable-stream": "^3.6.0", - "reinterval": "^1.1.0", - "split2": "^3.1.0", - "ws": "^7.5.0", - "xtend": "^4.0.2" - } - }, - "mqtt-packet": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", - "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", "requires": { "bl": "^4.0.2", "debug": "^4.1.1", @@ -37681,19 +30128,14 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "multicast-dns": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz", - "integrity": "sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==", + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "requires": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" } }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" - }, "multistream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/multistream/-/multistream-4.1.0.tgz", @@ -37710,47 +30152,24 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, "nano-memoize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/nano-memoize/-/nano-memoize-1.2.1.tgz", - "integrity": "sha512-ANfJ0QFhLzv9BZV8tHxwaDClqr+U8yY65hZA+slbgJrx+ePnHtlY92F2ZJInkkQWUUR71NzCEHBshKCHJnNyaQ==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/nano-memoize/-/nano-memoize-1.3.0.tgz", + "integrity": "sha512-yM/gMQHvA5EOtNGfEbJ8tmAveNjbckhzZ1hkNtMjY8zps3ocjPfp1kuJ1++OgtVHAhsGSTJttG3S6UV+FZZzxQ==" }, "nano-time": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", - "integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", "requires": { "big-integer": "^1.6.16" } }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", + "dev": true }, "napi-build-utils": { "version": "1.0.2", @@ -37758,23 +30177,15 @@ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", "dev": true }, - "native-url": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.2.6.tgz", - "integrity": "sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA==", - "requires": { - "querystring": "^0.2.0" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "neo-async": { "version": "2.6.2", @@ -37791,16 +30202,6 @@ "resolved": "https://registry.npmjs.org/nested-property/-/nested-property-4.0.0.tgz", "integrity": "sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA==" }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -37811,9 +30212,9 @@ }, "dependencies": { "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, @@ -37834,24 +30235,6 @@ } } }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -37862,132 +30245,19 @@ } }, "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==" }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "node-notifier": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.0.tgz", - "integrity": "sha512-ZTqP90y1eyb2xAZTa7j4AlAayTwh6cL8mn0nlJhLDq8itXGnJUmQGYOnpaMUvqZVfGo0vhU7KZ3HtDW6CT2SiQ==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.5", - "shellwords": "^0.1.1", - "uuid": "^8.3.2", - "which": "^2.0.2" - } + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==" - }, - "node-ssdp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/node-ssdp/-/node-ssdp-4.0.1.tgz", - "integrity": "sha512-uJXkLZVuyaMg1qNbMbGQ6YzNzyOD+NLxYyxIJocPTKTVECPDokOiCZA686jTLXHMUnV34uY/lcUSJ+/5fhY43A==", - "requires": { - "async": "^2.6.0", - "bluebird": "^3.5.1", - "debug": "^3.1.0", - "extend": "^3.0.1", - "ip": "^1.1.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", - "dev": true + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "normalize-package-data": { "version": "3.0.3", @@ -38009,23 +30279,17 @@ "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" }, "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "notistack": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/notistack/-/notistack-2.0.3.tgz", - "integrity": "sha512-krmVFtTO9kEY1Pa4NrbyexrjiRcV6TqBM2xLx8nuDea1g96Z/OZfkvVLmYKkTvoSJ3jyQntWK16z86ssW5kt4A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/notistack/-/notistack-2.0.5.tgz", + "integrity": "sha512-Ig2T1Muqkc1PaSQcEDrK7diKv6cBxw02Iq6uv074ySfgq524TV5lK41diAb6OSsaiWfp3aRt+T3+0MF8m2EcJQ==", "requires": { "clsx": "^1.1.0", "hoist-non-react-statics": "^3.3.0" @@ -38052,130 +30316,68 @@ } }, "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "requires": { "boolbase": "^1.0.0" } }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + "number-allocator": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.12.tgz", + "integrity": "sha512-sGB0qoQGmKimery9JubBQ9pQUr1V/LixJAk3Ygp7obZf6mpSXime8d7XHEobbIimkdZpgjkNlLt6G7LPEWFYWg==", + "requires": { + "debug": "^4.3.1", + "js-sdsl": "4.1.4" + }, + "dependencies": { + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" + } + } }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true }, "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, @@ -38200,30 +30402,23 @@ } }, "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", "requires": { + "array.prototype.reduce": "^1.0.4", "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" } }, "object.hasown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz", - "integrity": "sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", "requires": { - "isobject": "^3.0.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "object.values": { @@ -38247,9 +30442,9 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } @@ -38262,7 +30457,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -38276,12 +30471,13 @@ } }, "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" } }, "openapi-schema-validator": { @@ -38293,55 +30489,23 @@ "lodash.merge": "^4.6.1", "openapi-types": "1.3.4", "swagger-schema-official": "2.0.0-bab6bed" - }, - "dependencies": { - "openapi-types": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.4.tgz", - "integrity": "sha512-h8rADpW3k/wepLdERKF0VKMAPdoFYNQCLGPmc/f8sgQ2dxUy+7sY4WAX2XDUDjhKTjbJVbxxofLkzy7f1/tE4g==" - } } }, "openapi-types": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-10.0.0.tgz", - "integrity": "sha512-Y8xOCT2eiKGYDzMW9R4x5cmfc3vGaaI4EL2pwhDmodWw1HlK18YcZ4uJxc7Rdp7/gGzAygzH9SXr6GKYIXbRcQ==", - "peer": true + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.4.tgz", + "integrity": "sha512-h8rADpW3k/wepLdERKF0VKMAPdoFYNQCLGPmc/f8sgQ2dxUy+7sY4WAX2XDUDjhKTjbJVbxxofLkzy7f1/tE4g==" }, "openapi-validator-middleware": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/openapi-validator-middleware/-/openapi-validator-middleware-3.2.4.tgz", - "integrity": "sha512-xcvzR3HtWm3UYiW5w1AuQZ2FJr+JwGQbqEijtRd9uPY4zLVYogs2m2ZsCRUQLNqJGc4CU9evWogeVyD+7wSvMw==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/openapi-validator-middleware/-/openapi-validator-middleware-3.2.6.tgz", + "integrity": "sha512-a4gcn3K88GXSsUbEt1D0oDYsDbpukE8CLJnrAs4Lk0UkNXvf7eMlEHetjFfbqmZkxGAMK+zsyqxfxArDmXyWqw==", "requires": { - "api-schema-builder": "^2.0.10", + "api-schema-builder": "^2.0.11", "auto-bind": "^4.0.0", "nano-memoize": "^1.2.1" } }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "requires": { - "is-wsl": "^1.1.0" - }, - "dependencies": { - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - } - } - }, - "optimize-css-assets-webpack-plugin": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz", - "integrity": "sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A==", - "requires": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - } - }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -38380,24 +30544,76 @@ "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } } } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, "p-is-promise": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", @@ -38405,35 +30621,28 @@ "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "requires": { - "aggregate-error": "^3.0.0" + "p-limit": "^3.0.2" } }, "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "requires": { - "retry": "^0.12.0" + "@types/retry": "0.12.0", + "retry": "^0.13.1" } }, "p-try": { @@ -38441,45 +30650,6 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -38490,9 +30660,9 @@ }, "dependencies": { "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, @@ -38504,17 +30674,11 @@ "callsites": "^3.0.0" } }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } + "parse-github-url": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", + "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", + "dev": true }, "parse-json": { "version": "5.2.0", @@ -38547,27 +30711,12 @@ }, "dependencies": { "tslib": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", - "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -38576,12 +30725,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { "version": "3.1.1", @@ -38596,29 +30740,17 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picocolors": { "version": "1.0.0", @@ -38626,192 +30758,99 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" }, "pirates": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", - "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==" + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==" }, "pkg": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.3.2.tgz", - "integrity": "sha512-78X8Tt71TI11XjkZm/r9shTdFRooFiiRcT8nfYeeOou5VKCkCysQauwAAkJKb5yjfrUhk3CBNL4zv22/iLpdnw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/pkg/-/pkg-5.7.0.tgz", + "integrity": "sha512-PTiAjNq/CGAtK5qUBR6pjheqnipTFjeecgSgIKEcAOJA4GpmZeOZC8pMOoT0rfes5vHsmcFo7wbSRTAmXQurrg==", "dev": true, "requires": { - "@babel/parser": "7.13.13", - "@babel/types": "7.13.12", - "chalk": "^4.1.0", + "@babel/parser": "7.17.10", + "@babel/types": "7.17.10", + "chalk": "^4.1.2", "escodegen": "^2.0.0", "fs-extra": "^9.1.0", - "globby": "^11.0.3", + "globby": "^11.1.0", "into-stream": "^6.0.0", - "minimist": "^1.2.5", + "is-core-module": "2.9.0", + "minimist": "^1.2.6", "multistream": "^4.1.0", - "pkg-fetch": "3.2.3", - "prebuild-install": "6.0.1", - "progress": "^2.0.3", - "resolve": "^1.20.0", - "stream-meter": "^1.0.4", - "tslib": "2.1.0" - }, - "dependencies": { - "@babel/parser": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", - "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", - "dev": true - }, - "@babel/types": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.12.tgz", - "integrity": "sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true - } + "pkg-fetch": "3.4.1", + "prebuild-install": "6.1.4", + "resolve": "^1.22.0", + "stream-meter": "^1.0.4" } }, "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "requires": { - "find-up": "^2.1.0" + "find-up": "^4.0.0" }, "dependencies": { "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.2.0" } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" } } }, "pkg-fetch": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.2.3.tgz", - "integrity": "sha512-bv9vYANgAZ2Lvxn5Dsq7E0rLqzcqYkV4gnwe2f7oHV9N4SVMfDOIjjFCRuuTltop5EmsOcu7XkQpB5A/pIgC1g==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-3.4.1.tgz", + "integrity": "sha512-fS4cdayCa1r4jHkOKGPJKnS9PEs6OWZst+s+m0+CmhmPZObMnxoRnf9T9yUWl+lzM2b5aJF7cnQIySCT7Hq8Dg==", "dev": true, "requires": { - "chalk": "^4.1.0", + "chalk": "^4.1.2", "fs-extra": "^9.1.0", "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.6.1", + "node-fetch": "^2.6.6", "progress": "^2.0.3", "semver": "^7.3.5", + "tar-fs": "^2.1.1", "yargs": "^16.2.0" - }, - "dependencies": { - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "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.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } } }, "pkg-up": { @@ -38839,6 +30878,14 @@ "path-exists": "^3.0.0" } }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -38850,1030 +30897,645 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - } - } - }, - "pnp-webpack-plugin": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", - "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", - "requires": { - "ts-pnp": "^1.1.6" - } - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" } } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "version": "8.4.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", + "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" } } }, "postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" + "postcss-selector-parser": "^6.0.10" } }, "postcss-browser-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", - "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", - "requires": { - "postcss": "^7" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==" }, "postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", "requires": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" } }, - "postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", + "postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" } }, - "postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", + "postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" } }, "postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", - "requires": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" - } - }, - "postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" } }, "postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" } }, "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", + "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" } }, "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz", + "integrity": "sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g==", "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "browserslist": "^4.20.3", + "postcss-value-parser": "^4.2.0" } }, "postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", "requires": { - "postcss": "^7.0.14" + "postcss-value-parser": "^4.2.0" } }, "postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", + "version": "12.1.9", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.9.tgz", + "integrity": "sha512-/E7PRvK8DAVljBbeWrcEQJPG72jaImxF3vvCNFwv9cC8CzigVoNIpeyfnJzphnN3Fd8/auBf5wvkw6W9MfmTyg==", "requires": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" + "postcss-value-parser": "^4.2.0" } }, "postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "postcss-selector-parser": "^6.0.4" } }, "postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "postcss-selector-parser": "^6.0.10" } }, "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "requires": { - "postcss": "^7.0.0" - } + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==" }, "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "requires": { - "postcss": "^7.0.0" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==" }, "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "requires": { - "postcss": "^7.0.0" - } + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==" }, "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "requires": { - "postcss": "^7.0.0" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==" }, "postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", "requires": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" } }, "postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" } }, "postcss-flexbugs-fixes": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz", - "integrity": "sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==", - "requires": { - "postcss": "^7.0.26" - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==" }, "postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", "requires": { - "postcss": "^7.0.2" + "postcss-selector-parser": "^6.0.9" } }, "postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "requires": { - "postcss": "^7.0.2" + "postcss-selector-parser": "^6.0.9" } }, "postcss-font-variant": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", - "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", - "requires": { - "postcss": "^7.0.2" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==" }, "postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==" + }, + "postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", "requires": { - "postcss": "^7.0.2" + "postcss-value-parser": "^4.2.0" } }, - "postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", + "postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" } }, "postcss-initial": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", - "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==" + }, + "postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", "requires": { - "postcss": "^7.0.2" + "camelcase-css": "^2.0.1" } }, "postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", "requires": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" } }, "postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" }, "dependencies": { - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" - } + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + } } }, "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" } }, "postcss-logical": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "requires": { - "postcss": "^7.0.2" - } + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==" }, "postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "requires": { - "postcss": "^7.0.2" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==" }, "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz", + "integrity": "sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw==", "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" } }, "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz", + "integrity": "sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ==", "requires": { - "browserslist": "^4.0.0", + "browserslist": "^4.16.6", "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" } }, "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" } }, "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz", + "integrity": "sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg==", "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" } }, "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "postcss-selector-parser": "^6.0.5" } }, "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "requires": { - "postcss": "^7.0.5" - } + "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==" }, "postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", + "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", "postcss-value-parser": "^4.1.0" } }, "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" + "postcss-selector-parser": "^6.0.4" } }, "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-nested": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" + "postcss-selector-parser": "^6.0.6" } }, "postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", "requires": { - "postcss": "^7.0.2" + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" } }, "postcss-normalize": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", - "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", "requires": { - "@csstools/normalize.css": "^10.1.0", - "browserslist": "^4.6.2", - "postcss": "^7.0.17", - "postcss-browser-comments": "^3.0.0", - "sanitize.css": "^10.0.0" + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" } }, "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "requires": { - "postcss": "^7.0.0" - } + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==" }, "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", + "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, + "postcss-opacity-percentage": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz", + "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==" + }, "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" } }, "postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", "requires": { - "postcss": "^7.0.2" + "postcss-value-parser": "^4.2.0" } }, "postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "requires": { - "postcss": "^7.0.2" - } + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==" }, "postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", "requires": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" + "postcss-value-parser": "^4.2.0" } }, "postcss-preset-env": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", - "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", - "requires": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz", + "integrity": "sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==", + "requires": { + "@csstools/postcss-cascade-layers": "^1.1.0", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.11", + "browserslist": "^4.21.3", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.0.1", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.9", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" } }, "postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", "requires": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "dependencies": { - "cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" - }, - "postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "requires": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "postcss-selector-parser": "^6.0.10" } }, "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", + "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" } }, "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - } + "postcss-value-parser": "^4.2.0" } }, "postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "requires": { - "postcss": "^7.0.2" - } - }, - "postcss-safe-parser": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-5.0.2.tgz", - "integrity": "sha512-jDUfCPJbKOABhwpUKcqCVbbXiloe/QXMcbJ6Iipf3sDIihEzTqRCeMBfRaOHxhBuTYqtASrI1KJWxzztZU4qUQ==", - "requires": { - "postcss": "^8.1.0" - }, - "dependencies": { - "postcss": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz", - "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==", - "requires": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.1" - } - } - } - }, - "postcss-selector-matches": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==" }, "postcss-selector-not": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", - "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", "requires": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" + "postcss-selector-parser": "^6.0.10" } }, "postcss-selector-parser": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz", - "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" }, "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + } } } }, "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" + "postcss-selector-parser": "^6.0.5" } }, "postcss-value-parser": { @@ -39881,20 +31543,10 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, - "postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "requires": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, "prebuild-install": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.1.tgz", - "integrity": "sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", "dev": true, "requires": { "detect-libc": "^1.0.3", @@ -39903,15 +31555,13 @@ "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", + "node-abi": "^2.21.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" } }, "prelude-ls": { @@ -39919,36 +31569,35 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" }, "pretty-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "requires": { "lodash": "^4.17.20", - "renderkid": "^2.0.4" + "renderkid": "^3.0.0" } }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -39956,11 +31605,6 @@ } } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -39969,34 +31613,30 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.2.0.tgz", + "integrity": "sha512-+CMAlLHqwRYwBMXKCP+o8ns7DN+xHDUiI+0nArsiJ9y+kJVPLFxEaSw6Ha9s9H0tftxg2Yzl25wqj9G7m5wLZg==", "requires": { "asap": "~2.0.6" } }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, "prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "requires": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "prop-types": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.0.tgz", - "integrity": "sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -40037,35 +31677,10 @@ "ipaddr.js": "1.9.1" } }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "pump": { "version": "3.0.0", @@ -40076,94 +31691,24 @@ "once": "^1.3.1" } }, - "pumpify": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "side-channel": "^1.0.4" } }, - "querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==" - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" - }, "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -40196,29 +31741,27 @@ "safe-buffer": "^5.1.0" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + } } }, "rc": { @@ -40236,197 +31779,88 @@ "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=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true } } }, "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "react-app-polyfill": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz", - "integrity": "sha512-0sF4ny9v/B7s6aoehwze9vJNWcmCemAUYBVasscVr92+UYiEqDXOxfKjXN685mDaMRNF3WdhHQs76oTODMocFA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", "requires": { - "core-js": "^3.6.5", + "core-js": "^3.19.2", "object-assign": "^4.1.1", "promise": "^8.1.0", "raf": "^3.4.1", - "regenerator-runtime": "^0.13.7", - "whatwg-fetch": "^3.4.1" + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" } }, "react-dev-utils": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", - "integrity": "sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==", - "requires": { - "@babel/code-frame": "7.10.4", - "address": "1.1.2", - "browserslist": "4.14.2", - "chalk": "2.4.2", - "cross-spawn": "7.0.3", - "detect-port-alt": "1.1.6", - "escape-string-regexp": "2.0.0", - "filesize": "6.1.0", - "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "4.1.6", - "global-modules": "2.0.0", - "globby": "11.0.1", - "gzip-size": "5.1.1", - "immer": "8.0.1", - "is-root": "2.1.0", - "loader-utils": "2.0.0", - "open": "^7.0.2", - "pkg-up": "3.1.0", - "prompts": "2.4.0", - "react-error-overlay": "^6.0.9", - "recursive-readdir": "2.2.2", - "shell-quote": "1.7.2", - "strip-ansi": "6.0.0", - "text-table": "0.2.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "browserslist": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", - "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", - "requires": { - "caniuse-lite": "^1.0.30001125", - "electron-to-chromium": "^1.3.564", - "escalade": "^3.0.2", - "node-releases": "^1.1.61" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - }, - "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "requires": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "dependencies": { "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "node-releases": { - "version": "1.1.77", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", - "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==" - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", + "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==" } } }, "react-div-100vh": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/react-div-100vh/-/react-div-100vh-0.7.0.tgz", - "integrity": "sha512-I3d77tQyaSlOx/6vurDDLk7upb5GA2ldEtVXkk7Kn5cy+tLlS0KlqDK14xUxlxh7jz4StjgKcwFyrpymsPpomA==", - "requires": {} + "integrity": "sha512-I3d77tQyaSlOx/6vurDDLk7upb5GA2ldEtVXkk7Kn5cy+tLlS0KlqDK14xUxlxh7jz4StjgKcwFyrpymsPpomA==" }, "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.0" } }, "react-error-overlay": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.10.tgz", - "integrity": "sha512-mKR90fX7Pm5seCOfz8q9F+66VCc1PGsWSBxKbITjfKVQHMNF2zudxHnMdJiB1fRCb+XsbQV9sO9DCkgsMQgBIA==" + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "react-is": { "version": "16.13.1", @@ -40434,19 +31868,20 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-markdown": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-7.1.0.tgz", - "integrity": "sha512-hL8cLLkTydyoKlZWZOjlU6TvMYIw9qKLh1CCzVfnhKt/R/SnKVAqiyugetXY61CkjhBqJl2C5FdU3OwHYo7SrQ==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.3.tgz", + "integrity": "sha512-We36SfqaKoVNpN1QqsZwWSv/OZt5J15LNgTLWynwAN5b265hrQrsjMtlRNwUvS+YyR3yDM8HpTNc4pK9H/Gc0A==", "requires": { "@types/hast": "^2.0.0", + "@types/prop-types": "^15.0.0", "@types/unist": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^2.0.0", "prop-types": "^15.0.0", "property-information": "^6.0.0", - "react-is": "^17.0.0", + "react-is": "^18.0.0", "remark-parse": "^10.0.0", - "remark-rehype": "^9.0.0", + "remark-rehype": "^10.0.0", "space-separated-tokens": "^2.0.0", "style-to-object": "^0.3.0", "unified": "^10.0.0", @@ -40455,16 +31890,16 @@ }, "dependencies": { "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" } } }, "react-query": { - "version": "3.33.5", - "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.33.5.tgz", - "integrity": "sha512-gNpTzbY9Xw/s0ALeLsXdUGXtzXbXQcRAMa4Ina2JOJHbDr2mdA79O2SMNUwctKJ1/c0vKTdALIdn4taptv+MTQ==", + "version": "3.39.2", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.2.tgz", + "integrity": "sha512-F6hYDKyNgDQfQOuR1Rsp3VRzJnWHx6aRnnIZHMNGGgbL3SBgpZTDg8MQwmxOgpCAoqZJA+JSNCydF1xGJqKOCA==", "requires": { "@babel/runtime": "^7.5.5", "broadcast-channel": "^3.4.1", @@ -40472,14 +31907,14 @@ } }, "react-refresh": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", - "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, "react-router": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz", - "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.3.tgz", + "integrity": "sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w==", "requires": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -40496,7 +31931,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" }, "path-to-regexp": { "version": "1.8.0", @@ -40509,23 +31944,90 @@ } }, "react-router-dom": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz", - "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-Ov0tGPMBgqmbu5CDmN++tv2HQ9HlWDuWIIqn4b88gjlAN5IHI+4ZUZRcpz9Hl0azFIwihbLDYw1OiHGRo7ZIng==", "requires": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", "loose-envify": "^1.3.1", "prop-types": "^15.6.2", - "react-router": "5.2.1", + "react-router": "5.3.3", "tiny-invariant": "^1.0.2", "tiny-warning": "^1.0.0" } }, + "react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "requires": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "fsevents": "^2.3.2", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "dependencies": { + "fs-extra": { + "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==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + } + } + }, "react-transition-group": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", - "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", @@ -40533,10 +32035,19 @@ "prop-types": "^15.6.2" } }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "requires": { + "pify": "^2.3.0" + } + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", @@ -40547,12 +32058,14 @@ "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -40563,12 +32076,14 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true } } }, @@ -40576,16 +32091,55 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, "requires": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", "type-fest": "^0.8.1" }, "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -40600,20 +32154,34 @@ } }, "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "requires": { - "picomatch": "^2.0.4" + "picomatch": "^2.2.1" } }, + "reconnecting-eventsource": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/reconnecting-eventsource/-/reconnecting-eventsource-1.5.2.tgz", + "integrity": "sha512-8XQETFzf/W06Pl6njey8Jmw7Zyi6lWOAfZTrSwqBZRhb3+m50DFIap0Hgn4nOHBmh1T6wJpP0M5BYyX7OMf/QA==" + }, "recursive-readdir": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", "requires": { "minimatch": "3.0.4" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "redent": { @@ -40641,9 +32209,9 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "requires": { "regenerate": "^1.4.2" } @@ -40654,31 +32222,22 @@ "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", "requires": { "@babel/runtime": "^7.8.4" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, "regex-parser": { "version": "2.2.11", "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" }, "regexp-ast-analysis": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.3.0.tgz", - "integrity": "sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.5.1.tgz", + "integrity": "sha512-Ca/g9gaTNuMewLuu+mBIq4vCrGRSO8AE9bP32NMQjJ/wBTdWq0g96qLkBb0NbGwEbp7S/q+NQF3o7veeuRfg0g==", "dev": true, "requires": { "refa": "^0.9.0", @@ -40686,12 +32245,13 @@ } }, "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" } }, "regexpp": { @@ -40700,33 +32260,27 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" }, "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", "requires": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" } }, - "regextras": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regextras/-/regextras-0.8.0.tgz", - "integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==", - "dev": true - }, "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" }, "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "requires": { "jsesc": "~0.5.0" }, @@ -40734,14 +32288,14 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" } } }, "rehype-raw": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.0.tgz", - "integrity": "sha512-12j2UiiYJgZFdjnHDny77NY5BF3eW4Jsl0vtgL1DWdTzcHjPpbhumU+GtPUdivEWwQc8x9OdEuO0oxaGz7Tvyg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", + "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", "requires": { "@types/hast": "^2.0.0", "hast-util-raw": "^7.2.0", @@ -40751,12 +32305,12 @@ "reinterval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", - "integrity": "sha1-M2Hs+jymwYKDOA3Qu5VG85D17Oc=" + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==" }, "remark-gfm": { "version": "3.0.1", @@ -40780,78 +32334,43 @@ } }, "remark-rehype": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-9.1.0.tgz", - "integrity": "sha512-oLa6YmgAYg19zb0ZrBACh40hpBLteYROaPLhBXzLgjqyHQrN+gVP9N/FJvfzuNNuzCutktkroXEZBrxAxKhh7Q==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", + "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", "requires": { "@types/hast": "^2.0.0", "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^11.0.0", + "mdast-util-to-hast": "^12.1.0", "unified": "^10.0.0" } }, "remove-accents": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=" - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" }, "renderkid": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", - "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "requires": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", "htmlparser2": "^6.1.0", "lodash": "^4.17.21", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } + "strip-ansi": "^6.0.1" } }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "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==" }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, "requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -40861,15 +32380,16 @@ "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-cwd": { @@ -40897,140 +32417,39 @@ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, "resolve-url-loader": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz", - "integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==", - "requires": { - "adjust-sourcemap-loader": "3.0.0", - "camelcase": "5.3.1", - "compose-function": "3.0.3", - "convert-source-map": "1.7.0", - "es6-iterator": "2.0.3", - "loader-utils": "1.2.3", - "postcss": "7.0.36", - "rework": "1.0.1", - "rework-visit": "1.0.0", - "source-map": "0.6.1" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "requires": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "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==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" }, "postcss": { - "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "requires": { - "has-flag": "^3.0.0" + "picocolors": "^0.2.1", + "source-map": "^0.6.1" } } } }, + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==" + }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -41041,57 +32460,25 @@ "signal-exit": "^3.0.2" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, - "rework": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", - "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", - "requires": { - "convert-source-map": "^0.3.3", - "css": "^2.0.0" - }, - "dependencies": { - "convert-source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", - "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" - } - } - }, - "rework-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", - "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=" - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "rifm": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.12.1.tgz", - "integrity": "sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg==", - "requires": {} + "integrity": "sha512-OGA1Bitg/dSJtI/c4dh90svzaUPt228kzFsUkJbtA2c964IqEAwWXeL9ZJi86xWv3j5SMqRvGULl7bA6cK0Bvg==" }, "rimraf": { "version": "3.0.2", @@ -41101,58 +32488,33 @@ "glob": "^7.1.3" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", - "requires": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" - } - }, - "rollup-plugin-babel": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz", - "integrity": "sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==", + "version": "2.79.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", "requires": { - "@babel/helper-module-imports": "^7.0.0", - "rollup-pluginutils": "^2.8.1" + "fsevents": "~2.3.2" } }, "rollup-plugin-terser": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz", - "integrity": "sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", "requires": { - "@babel/code-frame": "^7.5.5", - "jest-worker": "^24.9.0", - "rollup-pluginutils": "^2.8.2", + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", "serialize-javascript": "^4.0.0", - "terser": "^4.6.2" + "terser": "^5.0.0" }, "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" + "supports-color": "^7.0.0" } }, "serialize-javascript": { @@ -41162,37 +32524,9 @@ "requires": { "randombytes": "^2.1.0" } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "requires": { - "estree-walker": "^0.6.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" } } }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -41201,18 +32535,10 @@ "queue-microtask": "^1.2.2" } }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "requires": { - "aproba": "^1.1.1" - } - }, "sade": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.7.4.tgz", - "integrity": "sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "requires": { "mri": "^1.1.0" } @@ -41222,12 +32548,14 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "requires": { - "ret": "~0.1.10" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" } }, "safer-buffer": { @@ -41235,256 +32563,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "sanitize.css": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", - "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" }, "sass-loader": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.2.0.tgz", - "integrity": "sha512-kUceLzC1gIHz0zNJPpqRsJyisWatGYNFRmv2CKZK2/ngMJgLqxTbXwe/hJ85luyvZkgqU3VlJ33UVF2T/0g6mw==", + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", "requires": { "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } + "neo-async": "^2.6.2" } }, "sax": { @@ -41501,21 +32591,20 @@ } }, "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, @@ -41545,14 +32634,14 @@ "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" }, "selfsigned": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", - "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", + "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", "requires": { - "node-forge": "^0.10.0" + "node-forge": "^1" } }, "semaphore": { @@ -41561,31 +32650,31 @@ "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } }, "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "debug": { @@ -41599,38 +32688,21 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, - "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - } - }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" } } }, "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "requires": { "randombytes": "^2.1.0" } @@ -41638,7 +32710,7 @@ "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "requires": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -41657,10 +32729,15 @@ "ms": "2.0.0" } }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -41671,81 +32748,47 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" } } }, "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" } }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -41768,15 +32811,9 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "optional": true + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" }, "should": { "version": "13.2.3", @@ -41803,7 +32840,7 @@ "should-format": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, "requires": { "should-type": "^1.3.0", @@ -41813,7 +32850,7 @@ "should-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "dev": true }, "should-type-adaptors": { @@ -41843,9 +32880,9 @@ } }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "simple-concat": { "version": "1.0.1", @@ -41864,21 +32901,6 @@ "simple-concat": "^1.0.0" } }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - } - } - }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -41889,161 +32911,6 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -42052,64 +32919,48 @@ "faye-websocket": "^0.11.3", "uuid": "^8.3.2", "websocket-driver": "^0.7.4" - } - }, - "sockjs-client": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz", - "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==", - "requires": { - "debug": "^3.2.6", - "eventsource": "^1.0.7", - "faye-websocket": "^0.11.3", - "inherits": "^2.0.4", - "json3": "^3.3.3", - "url-parse": "^1.5.3" }, "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" } } }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "requires": { - "is-plain-obj": "^1.0.0" - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz", - "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "source-map-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.1.tgz", + "integrity": "sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA==", "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } } }, "source-map-support": { @@ -42119,20 +32970,8 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } } }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" - }, "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -42147,6 +32986,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -42155,21 +32995,24 @@ "spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true }, "spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==" + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true }, "spdy": { "version": "4.0.2", @@ -42196,14 +33039,6 @@ "wbuf": "^1.7.3" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, "split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -42215,15 +33050,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "requires": { - "minipass": "^3.1.1" - } + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "stable": { "version": "0.1.8", @@ -42246,98 +33073,29 @@ } }, "stackframe": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", - "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "stream-meter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", + "integrity": "sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==", + "dev": true, "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" + "readable-stream": "^2.1.4" }, "dependencies": { "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -42352,108 +33110,24 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, "requires": { "safe-buffer": "~5.1.0" } } } }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-meter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", - "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=", - "dev": true, - "requires": { - "readable-stream": "^2.1.4" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" + "safe-buffer": "~5.2.0" }, "dependencies": { "safe-buffer": { @@ -42478,46 +33152,66 @@ "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" }, "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "string.prototype.matchall": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", - "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", + "regexp.prototype.flags": "^1.4.1", "side-channel": "^1.0.4" } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "stringify-object": { @@ -42544,18 +33238,9 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" }, "strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "requires": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==" }, "strip-final-newline": { "version": "2.0.0", @@ -42577,25 +33262,9 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, "style-loader": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", - "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^2.7.0" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==" }, "style-to-object": { "version": "0.3.0", @@ -42606,25 +33275,12 @@ } }, "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", + "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" } }, "stylis": { @@ -42641,14 +33297,19 @@ } }, "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, "svg-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", @@ -42682,6 +33343,14 @@ "color-convert": "^1.9.0" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -42703,7 +33372,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "css-select": { "version": "2.1.0", @@ -42749,12 +33418,21 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } }, "nth-check": { "version": "1.0.2", @@ -42800,6 +33478,13 @@ "z-schema": "^4.2.3" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -42848,19 +33533,19 @@ "swagger-schema-official": { "version": "2.0.0-bab6bed", "resolved": "https://registry.npmjs.org/swagger-schema-official/-/swagger-schema-official-2.0.0-bab6bed.tgz", - "integrity": "sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0=" + "integrity": "sha512-rCC0NWGKr/IJhtRuPq/t37qvZHI/mH4I4sxflVM+qgVe5Z2uOCivzWaVbuioJaB61kvm5UvB7b49E+oBY0M8jA==" }, "swagger-ui-dist": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.1.3.tgz", - "integrity": "sha512-WvfPSfAAMlE/sKS6YkW47nX/hA7StmhYnAHc6wWCXNL0oclwLj6UXv0hQCkLnDgvebi0MEV40SJJpVjKUgH1IQ==" + "version": "4.14.3", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.14.3.tgz", + "integrity": "sha512-Y7Sta24I9r+G6dX3ZTIq9Psr55cDC3myCB0E00ZnVkB0Wn3cO77NdLXSM0f90WZh9VpgTetKpMPR3n2VqKr+lQ==" }, "swagger-ui-express": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.3.0.tgz", - "integrity": "sha512-jN46SEEe9EoXa3ZgZoKgnSF6z0w3tnM1yqhO4Y+Q4iZVc8JOQB960EZpIAz6rNROrDApVDwcMHR0mhlnc/5Omw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.5.0.tgz", + "integrity": "sha512-DHk3zFvsxrkcnurGvQlAcLuTDacAVN1JHKDgcba/gr2NFRE4HGwP1YeHIXMiGznkWR4AeS7X5vEblNn4QljuNA==", "requires": { - "swagger-ui-dist": ">=4.1.3" + "swagger-ui-dist": ">=4.11.0" } }, "symbol-tree": { @@ -42868,65 +33553,46 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, - "table": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz", - "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==", - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "tailwindcss": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", + "integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==", + "requires": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.14", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "5.0.6", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" }, "dependencies": { - "ajv": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", - "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", - "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==" + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" } } }, "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - } - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "tar-fs": { "version": "2.1.1", @@ -42954,24 +33620,25 @@ } }, "temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==" }, "tempy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", - "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", "requires": { - "temp-dir": "^1.0.0", - "type-fest": "^0.3.1", - "unique-string": "^1.0.0" + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" }, "dependencies": { "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==" } } }, @@ -42985,118 +33652,33 @@ } }, "terser": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", - "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", + "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" + "source-map-support": "~0.5.20" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" } } }, "terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", + "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", "requires": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", - "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - } + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" } }, "test-exclude": { @@ -43112,68 +33694,22 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" - }, "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "tiny-typed-emitter": { "version": "2.1.0", @@ -43190,44 +33726,10 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-regex-range": { "version": "5.0.1", @@ -43238,42 +33740,43 @@ } }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "totalist": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-2.0.0.tgz", - "integrity": "sha512-+Y17F0YzxfACxTyjfhnJQEe7afPA0GSpYlFkl2VFMxYP7jshQf9gXV7cH47EfToBumFThfKBvfAcoUn6fdNeRQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", - "universalify": "^0.1.2" + "universalify": "^0.2.0", + "url-parse": "^1.5.3" }, "dependencies": { "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" } } }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", + "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==" + }, + "trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" }, "trim-newlines": { "version": "3.0.1", @@ -43282,28 +33785,23 @@ "dev": true }, "trough": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", - "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", + "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==" }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, - "ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==" - }, "tsconfig-paths": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", - "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { @@ -43318,7 +33816,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" } } }, @@ -43327,25 +33825,23 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + } }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -43376,7 +33872,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -43387,18 +33883,26 @@ } }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==" + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true + }, + "uglify-js": { + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.3.tgz", + "integrity": "sha512-JmMFDME3iufZnBpyKL+uS78LRiC+mK55zWfM5f/pWBJfpOttXAqYfdDGRukYhJuyRinvPVAtUhvy7rlDybNtFg==", + "dev": true, + "optional": true }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, @@ -43422,14 +33926,14 @@ "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" }, "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" }, "unified": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.1.tgz", - "integrity": "sha512-v4ky1+6BN9X3pQrOdkFIPWAaeDsHPE1svRDxq7YpTc2plkIqFMwukfqM+l0ewpP9EfwARlt9pPFAeWYhHm8X9w==", + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", "requires": { "@types/unist": "^2.0.0", "bail": "^2.0.0", @@ -43446,62 +33950,18 @@ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" }, "is-plain-obj": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", - "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==" - } - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" } } }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "requires": { - "crypto-random-string": "^1.0.0" + "crypto-random-string": "^2.0.0" } }, "unist-builder": { @@ -43523,43 +33983,35 @@ "integrity": "sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==" }, "unist-util-position": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.1.tgz", - "integrity": "sha512-mgy/zI9fQ2HlbOtTdr2w9lhVaiFUHWQnZrFF2EUoVOqtAUdzqMtNiD99qA5a1IcjWVR8O6aVYE9u7Z2z1v0SQA==" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.3.tgz", + "integrity": "sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==", + "requires": { + "@types/unist": "^2.0.0" + } }, "unist-util-stringify-position": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", - "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", + "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", "requires": { "@types/unist": "^2.0.0" } }, "unist-util-visit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.0.tgz", - "integrity": "sha512-n7lyhFKJfVZ9MnKtqbsqkQEk5P1KShj0+//V7mAcoI6bpbUjh3C/OG8HVD+pBihfh6Ovl01m8dkcv9HNqYajmQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.1.tgz", + "integrity": "sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" - }, - "dependencies": { - "unist-util-visit-parents": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz", - "integrity": "sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" - } - } + "unist-util-visit-parents": "^5.1.1" } }, "unist-util-visit-parents": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", - "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz", + "integrity": "sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -43582,58 +34034,31 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "unquote": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - } - } + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" }, "upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "upx": { - "version": "git+https://npm@github.com/Hypfer/upx.git#b63b801e430b1a37f8d43c3bc738c6d8ea2e37ff", + "version": "git+https://npm@github.com/Hypfer/upx.git#677da177d9bcf6e0172adfbf00f4563e943fade2", "dev": true, - "from": "upx@git+https://npm@github.com/Hypfer/upx#v1.0.7", + "from": "upx@git+https://npm@github.com/Hypfer/upx#1.0.11", "requires": { "debug": "^4.1.1" } @@ -43646,64 +34071,6 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - } - } - }, - "url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "requires": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, "url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -43713,92 +34080,80 @@ "requires-port": "^1.0.0" } }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + "use-long-press": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/use-long-press/-/use-long-press-2.0.2.tgz", + "integrity": "sha512-zQ4sujilCykA7fSZ+m2gDuGw5aW3Gm3M4pulRH4e8c4mGXw8MDQIMthCsHiolxpt/hCe/BbIvd/iDn9XNDzkYg==" }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" } }, "utila": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "uvu": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.2.tgz", - "integrity": "sha512-m2hLe7I2eROhh+tm3WE5cTo/Cv3WQA7Oc9f7JB6uWv+/zVKvfAm53bMyOoGOSZeQ7Ov2Fu9pLhFr7p07bnT20w==", + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", "requires": { "dequal": "^2.0.0", "diff": "^5.0.0", "kleur": "^4.0.3", - "sade": "^1.7.3", - "totalist": "^2.0.0" + "sade": "^1.7.3" }, "dependencies": { - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" - }, "kleur": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz", - "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==" + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" } } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", "requires": { "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0", "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" + } } }, "valetudo-backend": { @@ -43807,427 +34162,131 @@ "@agnoc/core": "~0.16.0-next.7", "@destinationstransfers/ntp": "2.0.0", "@types/compression": "1.7.2", - "@types/express": "4.17.13", + "@types/express": "4.17.14", "@types/express-list-endpoints": "6.0.0", - "@types/jstoxml": "2.0.1", - "@types/mocha": "7.0.2", - "@types/node": "16.11.1", + "@types/jstoxml": "2.0.2", + "@types/mocha": "10.0.0", + "@types/node": "18.8.4", "@types/node-ssdp": "4.0.1", "@types/semaphore": "1.1.1", - "@types/uuid": "8.3.3", - "ajv": "8.8.2", - "async-mqtt": "2.6.1", - "axios": "0.24.0", - "body-parser": "1.19.0", - "bonjour-service": "git+https://npm@github.com/Hypfer/bonjour-service.git#113d63c3a07f739001198545d2a9c1043e9a5b0b", + "@types/uuid": "8.3.4", + "ajv": "8.11.0", + "async-mqtt": "2.6.3", + "axios": "0.27.2", + "bonjour-service": "1.0.14", "compression": "1.7.4", - "crc": "3.8.0", + "crc": "4.1.1", "cross-env": "7.0.3", - "escape-html": "1.0.3", - "express": "4.17.2", + "express": "4.18.2", "express-basic-auth": "1.2.1", "express-dynamic-middleware": "1.0.0", "express-list-endpoints": "6.0.0", - "express-rate-limit": "5.5.1", + "express-rate-limit": "6.6.0", + "hashlru": "git+https://npm@github.com/Hypfer/hashlru#3.0.0", "is-in-subnet": "4.0.1", - "jstoxml": "2.2.7", - "mocha": "7.1.1", - "mqtt": "4.2.8", + "jstoxml": "3.2.5", + "mocha": "10.0.0", + "mqtt": "4.3.7", "nested-object-assign": "1.0.4", "nested-property": "4.0.0", - "node-ssdp": "4.0.1", - "openapi-validator-middleware": "3.2.4", - "pkg": "5.3.2", - "quick-lru": "5.1.1", + "openapi-validator-middleware": "3.2.6", + "pkg": "5.7.0", "semaphore": "1.1.0", "should": "13.2.3", - "swagger-ui-express": "4.3.0", - "uuid": "8.3.2", + "swagger-ui-express": "4.5.0", + "uuid": "9.0.0", "zoo-ids": "2.0.7" }, "dependencies": { "ajv": { - "version": "8.8.2", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "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==" - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" } } }, "valetudo-frontend": { "version": "file:frontend", "requires": { - "@emotion/react": "11.6.0", - "@emotion/styled": "11.6.0", - "@fontsource/roboto": "4.5.1", - "@mui/icons-material": "5.2.0", - "@mui/lab": "5.0.0-alpha.48", - "@mui/material": "5.2.0", - "@types/color": "3.0.2", - "@types/react": "17.0.37", - "@types/react-dom": "17.0.11", - "@types/react-router-dom": "5.1.8", - "@types/uuid": "8.3.3", - "axios": "0.24.0", - "color": "4.0.1", - "cra-build-watch": "3.4.0", - "date-fns": "2.26.0", - "notistack": "2.0.3", - "react": "17.0.2", + "@emotion/react": "11.10.4", + "@emotion/styled": "11.10.4", + "@fontsource/jetbrains-mono": "4.5.11", + "@fontsource/roboto": "4.5.8", + "@mui/base": "5.0.0-alpha.81", + "@mui/icons-material": "5.10.9", + "@mui/lab": "5.0.0-alpha.82", + "@mui/material": "5.10.9", + "@types/react": "18.0.21", + "@types/react-dom": "18.0.6", + "@types/react-router-dom": "5.3.3", + "@types/uuid": "8.3.4", + "axios": "0.27.2", + "cra-build-watch": "git+https://npm@github.com/Hypfer/cra-build-watch.git#5.0.0", + "date-fns": "2.29.3", + "jsencrypt": "3.2.1", + "notistack": "2.0.5", + "react": "18.2.0", "react-div-100vh": "0.7.0", - "react-dom": "17.0.2", - "react-markdown": "7.1.0", - "react-query": "3.33.5", - "react-router-dom": "5.3.0", - "react-scripts": "4.0.3", - "rehype-raw": "6.1.0", + "react-dom": "18.2.0", + "react-markdown": "8.0.3", + "react-query": "3.39.2", + "react-router-dom": "5.3.3", + "react-scripts": "5.0.1", + "reconnecting-eventsource": "1.5.2", + "rehype-raw": "6.1.1", "remark-gfm": "3.0.1", - "semaphore": "^1.1.0", + "semaphore": "1.1.0", "tsutils": "3.21.0", - "uuid": "8.3.2" - }, - "dependencies": { - "@babel/core": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", - "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.1", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.1", - "@babel/parser": "^7.12.3", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", - "integrity": "sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ==", - "requires": { - "ansi-html": "^0.0.7", - "error-stack-parser": "^2.0.6", - "html-entities": "^1.2.1", - "native-url": "^0.2.6", - "schema-utils": "^2.6.5", - "source-map": "^0.7.3" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } - } - }, - "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "cra-build-watch": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/cra-build-watch/-/cra-build-watch-3.4.0.tgz", - "integrity": "sha512-8PM8WPHtauwNATGi7I5aI2TNrSDA1HdwCYzusqlMCNAHXleaj/R2+RQfNclCyrevqj1YzXG7aF6aiKhVVzNBsg==", - "dev": true, - "requires": { - "cross-spawn": "7.0.3", - "fs-extra": "^9.0.1", - "html-webpack-plugin": "^4.5.0", - "import-cwd": "3.0.0", - "meow": "8.0.0", - "ora": "4.0.3", - "semver": "^7.1.1" - } - }, - "eslint-config-react-app": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz", - "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==", - "requires": { - "confusing-browser-globals": "^1.0.10" - } - }, - "eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", - "requires": { - "@typescript-eslint/experimental-utils": "^4.0.1" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" - }, - "html-webpack-plugin": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz", - "integrity": "sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==", - "requires": { - "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.15", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" - } - }, - "react-scripts": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", - "integrity": "sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A==", - "requires": { - "@babel/core": "7.12.3", - "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", - "@svgr/webpack": "5.5.0", - "@typescript-eslint/eslint-plugin": "^4.5.0", - "@typescript-eslint/parser": "^4.5.0", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.0", - "babel-loader": "8.1.0", - "babel-plugin-named-asset-import": "^0.3.7", - "babel-preset-react-app": "^10.0.0", - "bfj": "^7.0.2", - "camelcase": "^6.1.0", - "case-sensitive-paths-webpack-plugin": "2.3.0", - "css-loader": "4.3.0", - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0", - "eslint": "^7.11.0", - "eslint-config-react-app": "^6.0.0", - "eslint-plugin-flowtype": "^5.2.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jest": "^24.1.0", - "eslint-plugin-jsx-a11y": "^6.3.1", - "eslint-plugin-react": "^7.21.5", - "eslint-plugin-react-hooks": "^4.2.0", - "eslint-plugin-testing-library": "^3.9.2", - "eslint-webpack-plugin": "^2.5.2", - "file-loader": "6.1.1", - "fs-extra": "^9.0.1", - "fsevents": "^2.1.3", - "html-webpack-plugin": "4.5.0", - "identity-obj-proxy": "3.0.0", - "jest": "26.6.0", - "jest-circus": "26.6.0", - "jest-resolve": "26.6.0", - "jest-watch-typeahead": "0.6.1", - "mini-css-extract-plugin": "0.11.3", - "optimize-css-assets-webpack-plugin": "5.0.4", - "pnp-webpack-plugin": "1.6.4", - "postcss-flexbugs-fixes": "4.2.1", - "postcss-loader": "3.0.0", - "postcss-normalize": "8.0.1", - "postcss-preset-env": "6.7.0", - "postcss-safe-parser": "5.0.2", - "prompts": "2.4.0", - "react-app-polyfill": "^2.0.0", - "react-dev-utils": "^11.0.3", - "react-refresh": "^0.8.3", - "resolve": "1.18.1", - "resolve-url-loader": "^3.1.2", - "sass-loader": "^10.0.5", - "semver": "7.3.2", - "style-loader": "1.3.0", - "terser-webpack-plugin": "4.2.3", - "ts-pnp": "1.2.0", - "url-loader": "4.1.1", - "webpack": "4.44.2", - "webpack-dev-server": "3.11.1", - "webpack-manifest-plugin": "2.2.0", - "workbox-webpack-plugin": "5.1.4" - }, - "dependencies": { - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - } - } - }, - "resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", - "requires": { - "is-core-module": "^2.0.0", - "path-parse": "^1.0.6" - } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, - "peer": true - } - } - }, - "valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==" - }, - "vfile": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.2.0.tgz", - "integrity": "sha512-ftCpb6pU8Jrzcqku8zE6N3Gi4/RkDhRwEXSWudzZzA2eEOn/cBpsfk9aulCUR+j1raRSAykYQap9u6j6rhUaCA==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" + "use-long-press": "2.0.2", + "uuid": "9.0.0", + "zustand": "4.1.2" + } + }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "vfile": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.5.tgz", + "integrity": "sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==", + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, "dependencies": { "is-buffer": { @@ -44247,19 +34306,14 @@ } }, "vfile-message": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.0.tgz", - "integrity": "sha512-4QJbBk+DkPEhBXq3f260xSaWtjE4gPKOfulzfMFF8ZNwaPZieWsg3iVlcmF04+eebzpcpeXOOFMfrYzJHVYg+g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", + "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" } }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -44285,283 +34339,12 @@ } }, "watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" - }, - "dependencies": { - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "optional": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "optional": true, - "requires": { - "picomatch": "^2.2.1" - } - } - } - }, - "watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "optional": true, + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "requires": { - "chokidar": "^2.1.8" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "optional": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "optional": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "optional": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "optional": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "optional": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "optional": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "optional": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "optional": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" } }, "wbuf": { @@ -44575,7 +34358,7 @@ "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, "requires": { "defaults": "^1.0.3" @@ -44589,852 +34372,194 @@ "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true }, "webpack": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", - "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", + "version": "5.74.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", + "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" }, "dependencies": { - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + } + } + }, + "webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "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==", "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "fast-deep-equal": "^3.1.3" } }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + } + } + }, + "webpack-dev-server": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", + "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } + "fast-deep-equal": "^3.1.3" } }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } + "ipaddr.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", + "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==" }, "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "webpack-dev-middleware": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", - "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" - } - } - }, - "webpack-dev-server": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", - "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.8", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "sockjs-client": "^1.5.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "fill-range": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "requires": { - "locate-path": "^3.0.0" - } - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } }, "ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } - } - }, - "webpack-manifest-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", - "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", - "requires": { - "fs-extra": "^7.0.0", - "lodash": ">=3.5 <5", - "object.entries": "^1.1.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", + "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==" } } }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "requires": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + } } } }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -45471,7 +34596,7 @@ "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "requires": { "tr46": "~0.0.3", @@ -45498,57 +34623,13 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "string-width": "^1.0.2 || 2 || 3 || 4" } }, "word-wrap": { @@ -45556,228 +34637,288 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "workbox-background-sync": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz", - "integrity": "sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", + "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", "requires": { - "workbox-core": "^5.1.4" + "idb": "^7.0.1", + "workbox-core": "6.5.4" } }, "workbox-broadcast-update": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.1.4.tgz", - "integrity": "sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", + "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", "requires": { - "workbox-core": "^5.1.4" + "workbox-core": "6.5.4" } }, "workbox-build": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-5.1.4.tgz", - "integrity": "sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow==", - "requires": { - "@babel/core": "^7.8.4", - "@babel/preset-env": "^7.8.4", - "@babel/runtime": "^7.8.4", - "@hapi/joi": "^15.1.0", - "@rollup/plugin-node-resolve": "^7.1.1", - "@rollup/plugin-replace": "^2.3.1", - "@surma/rollup-plugin-off-main-thread": "^1.1.1", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", + "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "requires": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", "common-tags": "^1.8.0", "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^8.1.0", + "fs-extra": "^9.0.1", "glob": "^7.1.6", - "lodash.template": "^4.5.0", + "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", - "rollup": "^1.31.1", - "rollup-plugin-babel": "^4.3.3", - "rollup-plugin-terser": "^5.3.1", - "source-map": "^0.7.3", - "source-map-url": "^0.4.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "tempy": "^0.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", "upath": "^1.2.0", - "workbox-background-sync": "^5.1.4", - "workbox-broadcast-update": "^5.1.4", - "workbox-cacheable-response": "^5.1.4", - "workbox-core": "^5.1.4", - "workbox-expiration": "^5.1.4", - "workbox-google-analytics": "^5.1.4", - "workbox-navigation-preload": "^5.1.4", - "workbox-precaching": "^5.1.4", - "workbox-range-requests": "^5.1.4", - "workbox-routing": "^5.1.4", - "workbox-strategies": "^5.1.4", - "workbox-streams": "^5.1.4", - "workbox-sw": "^5.1.4", - "workbox-window": "^5.1.4" + "workbox-background-sync": "6.5.4", + "workbox-broadcast-update": "6.5.4", + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-google-analytics": "6.5.4", + "workbox-navigation-preload": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-range-requests": "6.5.4", + "workbox-recipes": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", + "workbox-streams": "6.5.4", + "workbox-sw": "6.5.4", + "workbox-window": "6.5.4" }, "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", "requires": { - "graceful-fs": "^4.1.6" + "whatwg-url": "^7.0.0" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "requires": { + "punycode": "^2.1.0" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } } } }, "workbox-cacheable-response": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.1.4.tgz", - "integrity": "sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", "requires": { - "workbox-core": "^5.1.4" + "workbox-core": "6.5.4" } }, "workbox-core": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.1.4.tgz", - "integrity": "sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg==" + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" }, "workbox-expiration": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.1.4.tgz", - "integrity": "sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", + "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", "requires": { - "workbox-core": "^5.1.4" + "idb": "^7.0.1", + "workbox-core": "6.5.4" } }, "workbox-google-analytics": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-5.1.4.tgz", - "integrity": "sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", + "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", "requires": { - "workbox-background-sync": "^5.1.4", - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4", - "workbox-strategies": "^5.1.4" + "workbox-background-sync": "6.5.4", + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" } }, "workbox-navigation-preload": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-5.1.4.tgz", - "integrity": "sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", + "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", "requires": { - "workbox-core": "^5.1.4" + "workbox-core": "6.5.4" } }, "workbox-precaching": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-5.1.4.tgz", - "integrity": "sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", + "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", "requires": { - "workbox-core": "^5.1.4" + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" } }, "workbox-range-requests": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-5.1.4.tgz", - "integrity": "sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", + "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", + "requires": { + "workbox-core": "6.5.4" + } + }, + "workbox-recipes": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", + "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", "requires": { - "workbox-core": "^5.1.4" + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" } }, "workbox-routing": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.1.4.tgz", - "integrity": "sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", "requires": { - "workbox-core": "^5.1.4" + "workbox-core": "6.5.4" } }, "workbox-strategies": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.1.4.tgz", - "integrity": "sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", "requires": { - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4" + "workbox-core": "6.5.4" } }, "workbox-streams": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-5.1.4.tgz", - "integrity": "sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", + "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", "requires": { - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4" + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4" } }, "workbox-sw": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-5.1.4.tgz", - "integrity": "sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA==" + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", + "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" }, "workbox-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-PZafF4HpugZndqISi3rZ4ZK4A4DxO8rAqt2FwRptgsDx7NF8TVKP86/huHquUsRjMGQllsNdn4FNl8CD/UvKmQ==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz", + "integrity": "sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==", "requires": { - "@babel/runtime": "^7.5.5", - "fast-json-stable-stringify": "^2.0.0", - "source-map-url": "^0.4.0", - "upath": "^1.1.2", - "webpack-sources": "^1.3.0", - "workbox-build": "^5.1.4" + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.5.4" + }, + "dependencies": { + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } } }, "workbox-window": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-5.1.4.tgz", - "integrity": "sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw==", - "requires": { - "workbox-core": "^5.1.4" - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", + "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", "requires": { - "errno": "~0.1.7" + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.5.4" } }, - "worker-rpc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", - "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", - "requires": { - "microevent.ts": "~0.1.1" - } + "workerpool": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { "version": "3.0.3", @@ -45791,10 +34932,9 @@ } }, "ws": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", - "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==", - "requires": {} + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" }, "xml-name-validator": { "version": "3.0.0", @@ -45812,9 +34952,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -45828,208 +34968,51 @@ "dev": true }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } } } }, "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" } }, "yocto-queue": { @@ -46038,14 +35021,22 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" }, "z-schema": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.2.tgz", - "integrity": "sha512-40TH47ukMHq5HrzkeVE40Ad7eIDKaRV2b+Qpi2prLc9X9eFJFzV7tMe5aH12e6avaSS/u5l653EQOv+J9PirPw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.4.tgz", + "integrity": "sha512-gm/lx3hDzJNcLwseIeQVm1UcwhWIKpSB4NqH89pTBtFns4k/HDHudsICtvG05Bvw/Mv3jMyk700y5dadueLHdA==", "requires": { - "commander": "^2.7.1", + "commander": "^2.20.3", "lodash.get": "^4.4.2", "lodash.isequal": "^4.5.0", "validator": "^13.7.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true + } } }, "zoo-ids": { @@ -46053,6 +35044,14 @@ "resolved": "https://registry.npmjs.org/zoo-ids/-/zoo-ids-2.0.7.tgz", "integrity": "sha512-qSyy++XHw9FYfUQQP8lun2Rzoc+YUDYhjCNNXgtuIdKSlHjGZYl4+c9GM3kmYKr7v+ZebuHKzCeOxnKSg+CSuA==" }, + "zustand": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.1.2.tgz", + "integrity": "sha512-gcRaKchcxFPbImrBb/BKgujOhHhik9YhVpIeP87ETT7uokEe2Szu7KkuZ9ghjtD+/KKkcrRNktR2AiLXPIbKIQ==", + "requires": { + "use-sync-external-store": "1.2.0" + } + }, "zwitch": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.2.tgz", diff --git a/package.json b/package.json index 7a88dffb..4805bbcf 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "valetudo", - "version": "2022.02.0-conga.0", + "version": "2022.09.0-conga.0", "description": "Self-contained control webinterface for vacuum robots", "license": "Apache-2.0", "engines": { - "node": ">=14" + "node": ">=16" }, "author": "", "workspaces": [ @@ -18,23 +18,28 @@ "build_docs": "node ./util/generate_robot_docs.js && node ./util/generate_mqtt_docs.js", "upx": "node ./util/upx_compress_valetudo.js", "build_openapi_schema": "node util/build_openapi_schema.mjs", - "build_release_manifest": "node util/build_release_manifest.js" + "build_release_manifest": "node util/build_release_manifest.js", + "check_dependencies_for_update": "npx check-outdated --ignore-pre-releases --ignore-packages react-router-dom", + "generate_changelog": "npx auto-changelog --commit-limit false --tag-pattern .+ --handlebars-setup ./util/res/auto_changelog_handlebars_helpers.js --template ./util/res/auto_changelog_template.hbs --output ./build/changelog.md", + "generate_nightly_changelog": "npx auto-changelog --commit-limit false --tag-pattern .+ --unreleased-only --handlebars-setup ./util/res/auto_changelog_handlebars_helpers.js --template ./util/res/auto_changelog_template.hbs --output ./build/changelog_nightly.md", + "generate_eslintrc_flavors": "node util/generate_eslintrc_flavors.js" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "5.4.0", - "@typescript-eslint/parser": "5.4.0", - "@typescript-eslint/experimental-utils": "5.4.0", - "eslint": "7.32.0", - "eslint-plugin-react": "7.27.1", - "eslint-plugin-react-hooks": "4.3.0", - "eslint-plugin-jsdoc": "37.0.3", + "@typescript-eslint/eslint-plugin": "5.40.0", + "@typescript-eslint/experimental-utils": "5.40.0", + "@typescript-eslint/parser": "5.40.0", + "auto-changelog": "2.4.0", + "eslint": "8.25.0", + "eslint-plugin-jsdoc": "39.3.6", "eslint-plugin-node": "11.1.0", - "eslint-plugin-regexp": "1.5.1", - "eslint-plugin-sort-keys-fix": "^1.1.1", + "eslint-plugin-react": "7.31.10", + "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-regexp": "1.9.0", + "eslint-plugin-sort-keys-fix": "1.1.2", "eslint-plugin-sort-requires": "git+https://npm@github.com/Hypfer/eslint-plugin-sort-requires.git#2.1.1", "swagger-jsdoc": "git+https://npm@github.com/Hypfer/swagger-jsdoc.git#7.0.0-rc.6-noyaml-monorepo-fix", - "swagger-parser": "^10.0.2", - "typescript": "4.5.2", - "upx": "git+https://npm@github.com/Hypfer/upx#v1.0.7" + "swagger-parser": "10.0.3", + "typescript": "4.8.4", + "upx": "git+https://npm@github.com/Hypfer/upx#1.0.11" } } diff --git a/util/build_openapi_schema.mjs b/util/build_openapi_schema.mjs index 1b55e0ea..d0c57e99 100644 --- a/util/build_openapi_schema.mjs +++ b/util/build_openapi_schema.mjs @@ -1,179 +1,110 @@ import swaggerJsdoc from "swagger-jsdoc"; import SwaggerParser from "swagger-parser"; -import Tools from "../backend/lib/Tools.js"; +import Tools from "../backend/lib/utils/Tools.js"; import * as fs from "fs"; import * as path from "path"; const __dirname = path.resolve(); process.on("uncaughtException", function (err) { - // eslint-disable-next-line no-console - console.log(err); - process.exit(1); + // eslint-disable-next-line no-console + console.log(err); + process.exit(1); }); const options = { - failOnErrors: false, - definition: { - openapi: "3.0.0", - info: { - title: "Valetudo REST API", - version: Tools.GET_VALETUDO_VERSION(), - }, - servers: [{ url: "../" }], - tags: [ - //Swagger UI respects the order of these - { name: "Valetudo", description: "Valetudo management API" }, - { name: "ValetudoEvents", description: "Valetudo Events" }, - { name: "Robot", description: "Robot API" }, - { name: "System", description: "System API" }, - { name: "NTP", description: "NTP Client API" }, - { name: "Timers", description: "Timers API" }, - { name: "Updater", description: "Update Valetudo using Valetudo" }, + failOnErrors: false, + definition: { + openapi: "3.0.0", + info: { + title: "Valetudo REST API", + version: Tools.GET_VALETUDO_VERSION() + }, + tags: [ //Swagger UI respects the order of these + {name: "Valetudo", description: "Valetudo management API"}, + {name: "ValetudoEvents", description: "Valetudo Events"}, + {name: "Robot", description: "Robot API"}, + {name: "System", description: "System API"}, + {name: "MQTT", description: "MQTT Controller API"}, + {name: "NetworkAdvertisement", description: "Network Advertisement Manager API"}, + {name: "NTP", description: "NTP Client API"}, + {name: "Timers", description: "Timers API"}, + {name: "Updater", description: "Update Valetudo using Valetudo"}, - { - name: "BasicControlCapability", - description: "Basic control capability", - }, - { - name: "FanSpeedControlCapability", - description: "Fan speed control capability", - }, - { - name: "WaterUsageControlCapability", - description: "Water usage control capability", - }, - { - name: "WifiConfigurationCapability", - description: "Wi-Fi configuration capability", - }, - { name: "WifiScanCapability", description: "Wi-Fi scan capability" }, - { - name: "ZoneCleaningCapability", - description: "Zone cleaning capability", - }, - { - name: "MapSegmentationCapability", - description: "Map segment cleaning capability", - }, - { - name: "ManualControlCapability", - description: "Manual control capability", - }, - { - name: "DoNotDisturbCapability", - description: "Do-not-disturb configuration capability", - }, - { - name: "ConsumableMonitoringCapability", - description: "Consumable monitoring capability", - }, - { name: "LocateCapability", description: "Robot locate capability" }, - { - name: "GoToLocationCapability", - description: "Go-to location capability", - }, - { - name: "CarpetModeControlCapability", - description: "Carpet mode settings capability", - }, - { name: "MapResetCapability", description: "Map reset capability" }, - { - name: "MapSegmentEditCapability", - description: "Map segment edit capability", - }, - { - name: "MapSegmentRenameCapability", - description: "Map segment rename capability", - }, - { - name: "MapSnapshotCapability", - description: "Map snapshots capability", - }, - { - name: "PersistentMapControlCapability", - description: "Persistent map control capability", - }, - { - name: "SensorCalibrationCapability", - description: "Sensor calibration capability", - }, - { name: "SpeakerTestCapability", description: "Speaker test capability" }, - { - name: "SpeakerVolumeControlCapability", - description: "Speaker volume control capability", - }, - { - name: "VoicePackManagementCapability", - description: "Voice pack management capability", - }, - { - name: "CombinedVirtualRestrictionsCapability", - description: "Combined virtual restrictions capability", - }, - { - name: "PendingMapChangeHandlingCapability", - description: "Pending map change handling capability", - }, - { name: "MappingPassCapability", description: "Mapping pass capability" }, - { name: "KeyLockCapability", description: "Key lock capability" }, - ], - components: { - responses: { - 200: { description: "Ok" }, - 201: { description: "Created" }, - 202: { description: "Accepted" }, - 400: { description: "Bad request" }, - 403: { description: "Forbidden" }, - 404: { description: "Not found" }, - 500: { description: "Internal server error" }, - }, - parameters: {}, - securitySchemes: { - BasicAuth: { - type: "http", - scheme: "basic", + {name: "BasicControlCapability", description: "Basic control capability"}, + {name: "FanSpeedControlCapability", description: "Fan speed control capability"}, + {name: "WaterUsageControlCapability", description: "Water usage control capability"}, + {name: "WifiConfigurationCapability", description: "Wi-Fi configuration capability"}, + {name: "WifiScanCapability", description: "Wi-Fi scan capability"}, + {name: "ZoneCleaningCapability", description: "Zone cleaning capability"}, + {name: "MapSegmentationCapability", description: "Map segment cleaning capability"}, + {name: "ManualControlCapability", description: "Manual control capability"}, + {name: "DoNotDisturbCapability", description: "Do-not-disturb configuration capability"}, + {name: "ConsumableMonitoringCapability", description: "Consumable monitoring capability"}, + {name: "LocateCapability", description: "Robot locate capability"}, + {name: "GoToLocationCapability", description: "Go-to location capability"}, + {name: "CarpetModeControlCapability", description: "Carpet mode settings capability"}, + {name: "MapResetCapability", description: "Map reset capability"}, + {name: "MapSegmentEditCapability", description: "Map segment edit capability"}, + {name: "MapSegmentRenameCapability", description: "Map segment rename capability"}, + {name: "MapSnapshotCapability", description: "Map snapshots capability"}, + {name: "PersistentMapControlCapability", description: "Persistent map control capability"}, + {name: "SpeakerTestCapability", description: "Speaker test capability"}, + {name: "SpeakerVolumeControlCapability", description: "Speaker volume control capability"}, + {name: "VoicePackManagementCapability", description: "Voice pack management capability"}, + {name: "CombinedVirtualRestrictionsCapability", description: "Combined virtual restrictions capability"}, + {name: "PendingMapChangeHandlingCapability", description: "Pending map change handling capability"}, + {name: "MappingPassCapability", description: "Mapping pass capability"}, + {name: "KeyLockCapability", description: "Key lock capability"}, + {name: "MopDockCleanManualTriggerCapability", description: "Mop Dock clean manual trigger capability"}, + {name: "MopDockDryManualTriggerCapability", description: "Mop Dock dry manual trigger capability"}, + ], + components: { + responses: { + "200": {description: "Ok"}, + "201": {description: "Created"}, + "202": {description: "Accepted"}, + "400": {description: "Bad request"}, + "403": {description: "Forbidden"}, + "404": {description: "Not found"}, + "500": {description: "Internal server error"}, + }, + parameters: {}, + securitySchemes: { + BasicAuth: { + type: "http", + scheme: "basic" + } + } }, - }, + security: [ + {BasicAuth: []} + ], }, - security: [{ BasicAuth: [] }], - }, - apis: [ - path.join(__dirname, "./backend/util/openapi_defs/*.openapi.json"), - path.join(__dirname, "./backend/lib/doc/*.openapi.json"), - path.join(__dirname, "./backend/lib/webserver/doc/*.openapi.json"), - path.join( - __dirname, - "./backend/lib/webserver/capabilityRouters/doc/*.openapi.json" - ), - path.join( - __dirname, - "./backend/lib/webserver/middlewares/doc/*.openapi.json" - ), - path.join(__dirname, "./backend/lib/entities/doc/*.openapi.json"), - path.join(__dirname, "./backend/lib/entities/map/doc/*.openapi.json"), - path.join(__dirname, "./backend/lib/entities/core/doc/*.openapi.json"), - path.join( - __dirname, - "./backend/lib/entities/core/ntpClient/doc/*.openapi.json" - ), - path.join( - __dirname, - "./backend/lib/entities/core/updater/doc/*.openapi.json" - ), - path.join(__dirname, "./backend/lib/entities/state/doc/*.openapi.json"), - path.join( - __dirname, - "./backend/lib/entities/state/attributes/doc/*.openapi.json" - ), - path.join(__dirname, "./backend/lib/core/capabilities/doc/*.openapi.json"), - ], + apis: [ + path.join(__dirname, "./backend/util/openapi_defs/*.openapi.json"), + path.join(__dirname, "./backend/lib/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/webserver/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/webserver/capabilityRouters/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/webserver/middlewares/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/map/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/core/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/core/ntpClient/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/core/updater/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/state/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/entities/state/attributes/doc/*.openapi.json"), + path.join(__dirname, "./backend/lib/core/capabilities/doc/*.openapi.json") + ] }; const spec = await swaggerJsdoc(options); await SwaggerParser.validate(spec); + fs.writeFileSync( - path.join(__dirname, "./backend/lib/res/valetudo.openapi.schema.json"), - JSON.stringify(spec) + path.join(__dirname, "./backend/lib/res/valetudo.openapi.schema.json"), + JSON.stringify(spec) ); + + diff --git a/util/build_release_manifest.js b/util/build_release_manifest.js index 1cc2a03c..51ef0ee1 100644 --- a/util/build_release_manifest.js +++ b/util/build_release_manifest.js @@ -38,4 +38,14 @@ Object.values(binaries).forEach((path, i) => { } }) +if (process.argv.length > 2 && process.argv[2] === "nightly") { + manifest.version = "nightly"; + + try { + manifest.changelog = fs.readFileSync("./build/changelog_nightly.md").toString(); + } catch(e) { + //intentional + } +} + fs.writeFileSync("./build/valetudo_release_manifest.json", JSON.stringify(manifest, null, 2)) diff --git a/util/generate_eslintrc_flavors.js b/util/generate_eslintrc_flavors.js new file mode 100644 index 00000000..2788afc4 --- /dev/null +++ b/util/generate_eslintrc_flavors.js @@ -0,0 +1,57 @@ +const fs = require("fs"); + +const backendEslintRc = JSON.parse(fs.readFileSync("./backend/.eslintrc.json").toString()); +const frontendEslintRc = JSON.parse(fs.readFileSync("./frontend/.eslintrc.json").toString()); + +backendEslintRc.rules = backendEslintRc.rules ?? {}; +frontendEslintRc.rules = frontendEslintRc.rules ?? {}; + +/* + This file serves two purposes + + 1) + To avoid constantly seeing red squiggly lines for things that one is currently working on, + all of these useful but not useful in this context rules have been moved to the .automated_overrides.eslintrc.json + and will only be used for the package.json scripts lint and lint_fix instead of IDE annotations + + 2) + Some eslint rules are known to produce a lot of false positive noise. They however also occasionally surface + some issues that other rules don't and help as nudges to revisit old code. + + Thus, it makes sense to run them from time to time but definitely not daily + These rules also extend the automated ones + */ + +const automatedOverrides = JSON.parse(fs.readFileSync("./.automated_overrides.eslintrc.json").toString()); + +const backendAutomatedEslintRc = JSON.parse(JSON.stringify(backendEslintRc)); +const frontendAutomatedEslintRc = JSON.parse(JSON.stringify(frontendEslintRc)); + +Object.keys(automatedOverrides.rules).forEach(ruleName => { + backendAutomatedEslintRc.rules[ruleName] = automatedOverrides.rules[ruleName]; + frontendAutomatedEslintRc.rules[ruleName] = automatedOverrides.rules[ruleName]; +}); + +fs.writeFileSync("./backend/.automated.eslintrc.json", JSON.stringify(backendAutomatedEslintRc, null, 2)); +fs.writeFileSync("./frontend/.automated.eslintrc.json", JSON.stringify(frontendAutomatedEslintRc, null, 2)); + + + + + +const pedanticOverrides = JSON.parse(fs.readFileSync("./.pedantic_overrides.eslintrc.json").toString()); + +const backendPedanticEslintRc = JSON.parse(JSON.stringify(backendAutomatedEslintRc)); +const frontendPedanticEslintRc = JSON.parse(JSON.stringify(frontendAutomatedEslintRc)); + +Object.keys(pedanticOverrides.rules).forEach(ruleName => { + backendPedanticEslintRc.rules[ruleName] = pedanticOverrides.rules[ruleName]; + frontendPedanticEslintRc.rules[ruleName] = pedanticOverrides.rules[ruleName]; +}); + +fs.writeFileSync("./backend/.pedantic.eslintrc.json", JSON.stringify(backendPedanticEslintRc, null, 2)); +fs.writeFileSync("./frontend/.pedantic.eslintrc.json", JSON.stringify(frontendPedanticEslintRc, null, 2)); + + + + diff --git a/util/generate_mqtt_docs.js b/util/generate_mqtt_docs.js index 19663668..9a0c87f7 100644 --- a/util/generate_mqtt_docs.js +++ b/util/generate_mqtt_docs.js @@ -86,28 +86,6 @@ const fakeConfig = { onUpdate: (_) => { }, get: key => fakeConfig[key], - "goToLocationPresets": { - "a9666386-7041-4bd4-a823-ebefa48665eb": { - "__class": "ValetudoGoToLocation", - "metaData": {}, - "name": "SpotA", - "coordinates": { - "x": 2589, - "y": 2364 - }, - "id": "a9666386-7041-4bd4-a823-ebefa48665eb" - }, - "6c74ac84-dfe9-4c4c-8bec-836ff268d630": { - "__class": "ValetudoGoToLocation", - "metaData": {}, - "name": "SpotB", - "coordinates": { - "x": 2186, - "y": 2262 - }, - "id": "6c74ac84-dfe9-4c4c-8bec-836ff268d630" - } - }, }; const eventStore = new ValetudoEventStore() @@ -195,7 +173,8 @@ class FakeMqttController extends MqttController { controller: this, baseTopic: "", topicName: "", - friendlyName: "Robot" + friendlyName: "Robot", + optionalExposedCapabilities: this.getOptionalExposableCapabilities() }); // __.--, @@ -273,6 +252,8 @@ class FakeMqttController extends MqttController { } async generateDocs() { + this.currentConfig.optionalExposedCapabilities = this.getOptionalExposableCapabilities(); + await this.reconfigure(async () => { await this.robotHandle.configure(); }, { @@ -283,7 +264,7 @@ class FakeMqttController extends MqttController { // Give time for the status attributes to propagate setTimeout(() => { - this.setState("sentinel").then(); + this.setState("sentinel").catch(err => {console.error(err)}); }, 500); // Promise resolved/rejected by doGenerateDocs(), in turn called when Homie state == ready by setState(). @@ -370,6 +351,10 @@ class FakeMqttController extends MqttController { attributes.push(`capability: [${handle.capability.getType()}](/pages/general/capabilities-overview.html#${this.generateAnchor(handle.capability.getType())})`); } markdown += `*${attributes.join(", ")}*` + "\n\n"; + + if (handle.constructor.OPTIONAL === true) { + markdown += `**Note:** This is an optional exposed capability handle and thus will only be available via MQTT if enabled in the Valetudo configuration.\n\n`; + } if (handle.helpText) { markdown += handle.helpText + "\n\n"; diff --git a/util/generate_robot_docs.js b/util/generate_robot_docs.js index 1be22652..8cb46970 100644 --- a/util/generate_robot_docs.js +++ b/util/generate_robot_docs.js @@ -92,15 +92,100 @@ const VALETUDO_ARCHITECTURES = { }; const ModelDescriptions = { - Dreame: { - "1C": { - valetudoSupport: VALETUDO_SUPPORT_GRADES.OKAY, - developerSupport: DEVELOPER_SUPPORT_GRADES.BEST_EFFORT, - testedWorking: true, - recommended: BUY_GRADES.OKAY_ISH, - comment: - "vSLAM and a small battery, though there are persistent maps and everything seems to work", - architecture: VALETUDO_ARCHITECTURES.ARM, + "Dreame": { + "1C": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.OKAY, + developerSupport: DEVELOPER_SUPPORT_GRADES.BEST_EFFORT, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: "vSLAM and a small battery, though there are persistent maps and everything seems to work", + architecture: VALETUDO_ARCHITECTURES.ARM, + }, + "1T": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.BEST_EFFORT, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: [ + "vSLAM + ToF offers a huge upgrade over only vSLAM, however it is still inferior to Lidar-based mapping.", + "On initial root, it might be required to do a factory reset so that the device.conf gets regenerated." + ].join("\n"), + architecture: VALETUDO_ARCHITECTURES.AARCH64, + }, + "D9": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.YES, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: "256 MB RAM are problematic when dealing with large floorplans", + architecture: VALETUDO_ARCHITECTURES.ARM_LOWMEM, + }, + "D9 Pro": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.YES, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: "256 MB RAM are problematic when dealing with large floorplans\n\nBasically the same as the D9", + architecture: VALETUDO_ARCHITECTURES.ARM_LOWMEM, + }, + "F9": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.BEST_EFFORT, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: "vSLAM :(", + architecture: VALETUDO_ARCHITECTURES.ARM, + }, + "L10 Pro": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.YES, + testedWorking: true, + recommended: BUY_GRADES.OKAY, + comment: "None", + architecture: VALETUDO_ARCHITECTURES.AARCH64, + }, + "MOVA Z500": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.BEST_EFFORT, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: "vSLAM :(", + architecture: VALETUDO_ARCHITECTURES.ARM, + }, + "Z10 Pro": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.YES, + testedWorking: true, + recommended: BUY_GRADES.GET_IT_RIGHT_NOW, + comment: "The auto-empty-dock is a neat addition", + architecture: VALETUDO_ARCHITECTURES.AARCH64, + }, + "P2148": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.YES, + testedWorking: true, + recommended: BUY_GRADES.OKAY_ISH, + comment: [ + "With its 5.5cm height and 32.3cm diameter, this robot offers a solution for some tricky homes.", + "As it is china exclusive, spare parts may be hard to find in the rest of the world.", + "", + "On initial root, it might be required to do a factory reset so that the device.conf gets regenerated.", + "", + "There is no reset button on this robot. Instead, press and hold the two buttons for", + "- <1s for the UART shell spawn", + "- >3s for Wi-Fi reset", + "- >5s for full factory reset" + ].join("\n"), + architecture: VALETUDO_ARCHITECTURES.AARCH64, + }, + "W10": { + valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, + developerSupport: DEVELOPER_SUPPORT_GRADES.YES, + testedWorking: true, + recommended: BUY_GRADES.OKAY, + comment: "The mopping feature is pretty great, however the missing obstacle avoidance is a bit annoying considering the pricetag", + architecture: VALETUDO_ARCHITECTURES.ARM_LOWMEM, + } }, "1T": { valetudoSupport: VALETUDO_SUPPORT_GRADES.GOOD, @@ -291,8 +376,12 @@ function getModelDescription(vendor, model) { * @type {string[]} */ const HIDDEN_IMPLEMENTATIONS = [ - "RoborockS6MaxVValetudoRobot", - "RoborockS7ValetudoRobot", + "ViomiV7ValetudoRobot", + "RoborockM1SValetudoRobot", + "RoborockS6MaxVValetudoRobot", + "RoborockS7ValetudoRobot", + "DreameP2149ValetudoRobot", + "DreameL10SUltraValetudoRobot", ]; const vendors = {}; @@ -329,7 +418,7 @@ Object.values(Robots).forEach((robotClass) => { const header = `--- title: Supported Robots category: General -order: 8 +order: 9 --- # Supported Robots diff --git a/util/res/auto_changelog_handlebars_helpers.js b/util/res/auto_changelog_handlebars_helpers.js new file mode 100644 index 00000000..a94c76f4 --- /dev/null +++ b/util/res/auto_changelog_handlebars_helpers.js @@ -0,0 +1,41 @@ +function mergeAndSortCategories(merges, fixes, commits) { + const allCommits = [ + ...merges.map(merge => merge.commit), + ...fixes.map(merge => merge.commit), + ...commits + ]; + + allCommits.forEach(commit => { + commit.breaking = /^[A-Za-z0-9.]+!(?:\(.*\))?:/.test(commit.subject); + }) + + return allCommits.sort((a, b) => { + return new Date(b.date) - new Date(a.date); + }); +} + +module.exports = function (Handlebars) { + Handlebars.registerHelper('get-all-non-breaking-commits', function (merges, fixes, commits) { + return mergeAndSortCategories(merges, fixes, commits).filter(c => c.breaking === false); + }) + + Handlebars.registerHelper('get-all-breaking-commits', function (merges, fixes, commits) { + return mergeAndSortCategories(merges, fixes, commits).filter(c => c.breaking === true); + }) + + Handlebars.registerHelper("render-ccm", function(subject) { + const match = /^(?[A-Za-z0-9.]+)(?!)?(?:\((?[A-Za-z0-9.]+)\))?: (?.*)$/.exec(subject); + + if (typeof match?.groups?.type === "string" && typeof match?.groups?.message === "string") { + let output = match.groups.message; + + if (typeof match.groups.scope === "string") { + output = `**${match.groups.scope}**: ${output}`; + } + + return output; + } else { + return subject; + } + }) +} \ No newline at end of file diff --git a/util/res/auto_changelog_template.hbs b/util/res/auto_changelog_template.hbs new file mode 100644 index 00000000..7ed57e7c --- /dev/null +++ b/util/res/auto_changelog_template.hbs @@ -0,0 +1,26 @@ +{{#with releases.[0]}} + {{#if tag}} + ## Valetudo {{tag}} ({{date}}) + {{else}} + ## Valetudo nightly ({{date}}) + {{/if}} + {{#commit-list (get-all-breaking-commits merges fixes commits) heading='### Breaking Changes'}} + - {{render-ccm subject}} [`{{shorthash}}`]({{href}}) + {{/commit-list}} + + {{#commit-list (get-all-non-breaking-commits merges fixes commits) heading='### Features' message='^feat!?(?:\(.*\))?:'}} + - {{render-ccm subject}} [`{{shorthash}}`]({{href}}) + {{/commit-list}} + + {{#commit-list (get-all-non-breaking-commits merges fixes commits) heading='### Fixes' message='^fix!?(?:\(.*\))?:'}} + - {{render-ccm subject}} [`{{shorthash}}`]({{href}}) + {{/commit-list}} + + {{#commit-list (get-all-non-breaking-commits merges fixes commits) heading='### Refactoring' message='^refactor!?(?:\(.*\))?:'}} + - {{render-ccm subject}} [`{{shorthash}}`]({{href}}) + {{/commit-list}} + + {{#commit-list (get-all-non-breaking-commits merges fixes commits) heading='### Chores' message='^chore!?(?:\(.*\))?:'}} + - {{render-ccm subject}} [`{{shorthash}}`]({{href}}) + {{/commit-list}} +{{/with}} \ No newline at end of file diff --git a/util/upx_compress_valetudo.js b/util/upx_compress_valetudo.js index 33d8c83b..e75dee02 100644 --- a/util/upx_compress_valetudo.js +++ b/util/upx_compress_valetudo.js @@ -1,32 +1,50 @@ /* eslint-disable */ const fs = require("fs"); -const UPX = require("upx")({ - ultraBrute: true -}); +const UPX = require("upx"); const binaries = { armv7: { - base: "./build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-armv7", + base: "./build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-armv7", built: "./build/armv7/valetudo", - out: "./build/armv7/valetudo.upx" + out: "./build/armv7/valetudo.upx", + upx: UPX({ + //ultraBrute: true // Disabled for now (2022-05-07) due to performance issues with the latest upx devel + + // instead of ultraBrute, this also works okay-ish + lzma: true, + best: true + }) }, armv7_lowmem: { - base: "./build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-armv7", + base: "./build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-armv7", built: "./build/armv7/valetudo-lowmem", - out: "./build/armv7/valetudo-lowmem.upx" + out: "./build/armv7/valetudo-lowmem.upx", + upx: UPX({ + //ultraBrute: true // Disabled for now (2022-05-07) due to performance issues with the latest upx devel + + // instead of ultraBrute, this also works okay-ish + lzma: true, + best: true + }) }, aarch64: { - base: "./build_dependencies/pkg/v3.2/built-v16.8.0-linuxstatic-arm64", + base: "./build_dependencies/pkg/v3.4/built-v18.1.0-linuxstatic-arm64", built: "./build/aarch64/valetudo", - out: "./build/aarch64/valetudo.upx" + out: "./build/aarch64/valetudo.upx", + upx: UPX({ + //ultraBrute: true // Disabled for now (2022-05-07) due to performance issues with the latest upx devel + + // instead of ultraBrute, this also works okay-ish + lzma: true, + best: true + }) } }; /** * There is absolutely no error handling in here. Great :) * - * Note that this only works with patched base binaries which don't use hardcoded offsets - * for payload and prelude + * Note that this only works with patched base binaries */ console.log("Starting UPX compression"); @@ -45,7 +63,7 @@ Object.values(binaries).forEach(async (b,i) => { // UPX will reject files without the executable bit on linux. Also, default mode is 666 fs.writeFileSync(b.out + "_runtime", runtime, {mode: 0o777}); - const upxResult = await UPX(b.out + "_runtime").start(); + const upxResult = await b.upx(b.out + "_runtime").start(); console.log("Compressed " + b.built + " from " + upxResult.fileSize.before + " to " + upxResult.fileSize.after + ". Ratio: " + upxResult.ratio);