From 941695d3e8b7d0eee57c3b54a37eaaeee2fe3b1a Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Mon, 25 Sep 2023 16:04:50 +0200
Subject: [PATCH 01/19] use new api in scripts

---
 api.js                           |   1 +
 app.js                           |  65 +++-
 examples-v1/condition.js         |  24 ++
 examples-v1/fetch.js             |  25 ++
 examples-v1/flowcard-list.js     |  40 +++
 examples-v1/flowcard-run.js      |  29 ++
 examples-v1/global-get.js        |   9 +
 examples-v1/global-set.js        |   5 +
 examples-v1/hello-world.js       |   7 +
 examples-v1/lodash.js            |   7 +
 examples-v1/printSensorValues.js |  22 ++
 {examples => examples-v1}/say.js |   0
 examples-v1/tag.js               |  30 ++
 examples-v1/turnOnDevices.js     |  21 ++
 examples-v1/wait.js              |  10 +
 examples/flowcard-list.js        |   6 +-
 examples/flowcard-run.js         |   6 +-
 examples/tag.js                  |   2 +-
 package-lock.json                | 518 ++++++++++++++++++++++++++++++-
 package.json                     |   1 +
 20 files changed, 797 insertions(+), 31 deletions(-)
 create mode 100644 examples-v1/condition.js
 create mode 100644 examples-v1/fetch.js
 create mode 100644 examples-v1/flowcard-list.js
 create mode 100644 examples-v1/flowcard-run.js
 create mode 100644 examples-v1/global-get.js
 create mode 100644 examples-v1/global-set.js
 create mode 100644 examples-v1/hello-world.js
 create mode 100644 examples-v1/lodash.js
 create mode 100644 examples-v1/printSensorValues.js
 rename {examples => examples-v1}/say.js (100%)
 create mode 100644 examples-v1/tag.js
 create mode 100644 examples-v1/turnOnDevices.js
 create mode 100644 examples-v1/wait.js

diff --git a/api.js b/api.js
index 0456db2..3d97db9 100644
--- a/api.js
+++ b/api.js
@@ -32,6 +32,7 @@ module.exports = {
         name: script.name,
         code: code || script.code,
         lastExecuted: script.lastExecuted,
+        version: 2,
         args,
       }).finally(() => {
         homey.app.updateScript({ id: script.id, lastExecuted: new Date() }).catch(() => {});
diff --git a/app.js b/app.js
index 57fcb9b..2f2113c 100644
--- a/app.js
+++ b/app.js
@@ -9,7 +9,8 @@ const https = require('https');
 const uuid = require('uuid');
 
 const Homey = require('homey');
-const { HomeyAPI } = require('athom-api');
+const { HomeyAPI: HomeyAPILegacy } = require('athom-api');
+const { HomeyAPIV2, HomeyAPIV3Local } = require('homey-api');
 const fetch = require('node-fetch');
 const _ = require('lodash');
 
@@ -24,6 +25,22 @@ module.exports = class HomeyScriptApp extends Homey.App {
     this.localURL = await this.homey.api.getLocalUrl();
     this.sessionToken = await this.homey.api.getOwnerApiToken();
 
+    this.apiProps = await (async () => {
+      const props = {
+        token: this.sessionToken,
+        baseUrl: this.localURL,
+        strategy: [],
+        properties: {
+          id: await this.homey.cloud.getHomeyId(),
+          softwareVersion: this.homey.version,
+        },
+      };
+
+      return props;
+    })();
+
+    const exampleFolder = this.homey.platformVersion >= 2 ? 'examples' : 'examples-v1';
+
     if (!this.scripts) {
       this.log('No scripts found.');
 
@@ -31,17 +48,18 @@ module.exports = class HomeyScriptApp extends Homey.App {
 
       // Copy example scripts
       try {
-        const files = await fs.readdir(path.join(__dirname, 'examples'));
+        const files = await fs.readdir(path.join(__dirname, exampleFolder));
         await Promise.all(files.map(async filename => {
           if (!filename.endsWith('.js')) return;
 
           const id = `example-${filename.substring(0, filename.length - '.js'.length)}`;
-          const filepath = path.join(__dirname, 'examples', filename);
+          const filepath = path.join(__dirname, exampleFolder, filename);
           const code = await fs.readFile(filepath, 'utf8');
 
           scripts[id] = {
             code,
             lastExecuted: null,
+            version: 2,
           };
 
           this.log(`Found Example: ${id}`);
@@ -86,6 +104,11 @@ module.exports = class HomeyScriptApp extends Homey.App {
           script.name = scriptId;
           script.id = scriptId;
         }
+
+        if (typeof script.version !== 'number') {
+          anyScriptChanged = true;
+          script.version = 1;
+        }
       }
 
       if (anyScriptChanged) {
@@ -103,6 +126,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
           name: scriptSource.name,
           code: scriptSource.code,
           lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
           realtime: false,
         }).finally(() => {
           this.updateScript({
@@ -144,6 +168,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
           name: scriptSource.name,
           code: scriptSource.code,
           lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
           args: [argument],
           realtime: false,
         }).finally(() => {
@@ -164,6 +189,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
           name: scriptSource.name,
           code: scriptSource.code,
           lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
           realtime: false,
         }).finally(() => {
           this.updateScript({
@@ -183,6 +209,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
           name: scriptSource.name,
           code: scriptSource.code,
           lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
           args: [argument],
           realtime: false,
         }).finally(() => {
@@ -319,8 +346,24 @@ module.exports = class HomeyScriptApp extends Homey.App {
     })).catch(this.error);
   }
 
-  async getHomeyAPI() {
-    const api = new HomeyAPI({
+  createAppApi() {
+    if (this.homey.platform === 'local' && this.homey.platformVersion === 1) {
+      return new HomeyAPIV2(this.apiProps);
+    }
+
+    if (this.homey.platform === 'local' && this.homey.platformVersion === 2) {
+      return new HomeyAPIV3Local(this.apiProps);
+    }
+
+    throw new Error('Not Supported');
+  }
+
+  getHomeyAPI({ version }) {
+    if (version >= 2) {
+      return this.createAppApi();
+    }
+
+    const api = new HomeyAPILegacy({
       localUrl: this.localURL,
       baseUrl: this.localURL,
       token: this.sessionToken,
@@ -406,11 +449,14 @@ module.exports = class HomeyScriptApp extends Homey.App {
     code,
     lastExecuted,
     args = [],
+    version,
     realtime = true,
   }) {
     if (lastExecuted == null) lastExecuted = new Date();
 
-    const homeyAPI = await this.getHomeyAPI();
+    const homeyAPI = this.getHomeyAPI({ version });
+
+    console.log(homeyAPI);
 
     // Create a Logger
     const log = (...props) => {
@@ -515,6 +561,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
       id: uuid.v4(),
       name,
       code,
+      version: 2,
       lastExecuted: null,
     };
 
@@ -525,7 +572,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
   }
 
   async updateScript({
-    id, name, code, lastExecuted,
+    id, name, code, lastExecuted, version,
   }) {
     this.scripts[id] = {
       ...this.scripts[id],
@@ -543,6 +590,10 @@ module.exports = class HomeyScriptApp extends Homey.App {
       this.scripts[id].lastExecuted = lastExecuted;
     }
 
+    if (version != null) {
+      this.scripts[id].version = version;
+    }
+
     this.homey.settings.set('scripts', this.scripts);
 
     return this.scripts[id];
diff --git a/examples-v1/condition.js b/examples-v1/condition.js
new file mode 100644
index 0000000..777cf14
--- /dev/null
+++ b/examples-v1/condition.js
@@ -0,0 +1,24 @@
+/*
+ * This script is an example for usage in a Flow with the 
+ * 'Run a script with an argument' in the 'And'-column.
+ * 
+ * It checks if the argument begins with an "a",
+ * and returns a boolean.
+ * 
+ * If this is true, the Flow will continue.
+ * If it's false, the Flow will stop.
+ * 
+ * For example:
+ * "aaa" -> true
+ * "baa" -> false
+ */
+
+if (typeof args[0] !== 'string') {
+  throw new Error('This script must be run from a Flow!');
+}
+
+if (args[0].startsWith('a')) {
+  return true;
+} else {
+  return false;
+}
\ No newline at end of file
diff --git a/examples-v1/fetch.js b/examples-v1/fetch.js
new file mode 100644
index 0000000..e50d336
--- /dev/null
+++ b/examples-v1/fetch.js
@@ -0,0 +1,25 @@
+/*
+ * This script demonstrates how to get some
+ * information from the internet using fetch().
+ * 
+ * In this example, we get the HomeyScript app from the Homey App Store API,
+ * and show the app's rating using emoji.
+ */
+
+// Create the request
+const res = await fetch('https://apps-api.athom.com/api/v1/app/com.athom.homeyscript');
+if (!res.ok) {
+  throw new Error(res.statusText);
+}
+
+// Get the body JSON
+const body = await res.json();
+
+log(`${body.liveBuild.name.en} (${body.id}) v${body.liveVersion}`);
+
+// Print rating
+const stars = Array(Math.round(body.rating))
+  .fill('⭐️')
+  .join('');
+
+log(`Rating: ${stars}`);
\ No newline at end of file
diff --git a/examples-v1/flowcard-list.js b/examples-v1/flowcard-list.js
new file mode 100644
index 0000000..1ffb9c2
--- /dev/null
+++ b/examples-v1/flowcard-list.js
@@ -0,0 +1,40 @@
+/*
+ * This script lists all 'And' and 'Then'-cards,
+ * so you know how to use them in HomeyScript
+ * by calling Homey.flow.runFlowCardCondition()
+ * and Homey.flow.runFlowCardAction()
+ * 
+ * Also see: example-flowcard-run.js
+ */
+
+log('===========');
+log('And-cards:');
+log('===========');
+const conditionCards = await Homey.flow.getFlowCardConditions();
+for( const card of conditionCards ) {
+  log(card.titleFormatted || card.title)
+  log(JSON.stringify({
+    uri: card.uri,
+    id: card.id,
+    args: card.args,
+    droptoken: card.droptoken,
+    duration: card.duration,
+  }, false, 2));
+  log('-----------')
+}
+
+log('===========');
+log('Then-cards:');
+log('===========');
+const actionCards = await Homey.flow.getFlowCardActions();
+for( const card of actionCards ) {
+  log(card.titleFormatted || card.title)
+  log(JSON.stringify({
+    uri: card.uri,
+    id: card.id,
+    args: card.args,
+    droptoken: card.droptoken,
+    duration: card.duration,
+  }, false, 2));
+  log('-----------')
+}
\ No newline at end of file
diff --git a/examples-v1/flowcard-run.js b/examples-v1/flowcard-run.js
new file mode 100644
index 0000000..189fee3
--- /dev/null
+++ b/examples-v1/flowcard-run.js
@@ -0,0 +1,29 @@
+/*
+ * This script demonstrates how to run an 'And' Flow Card,
+ * and how to run an 'Then' Flow Card.
+ */
+
+// Run 'Day Equals' Flow 'And' Card
+const { result: isWeekend } = await Homey.flow.runFlowCardCondition({
+  uri: 'homey:manager:cron',
+  id: 'day_equals',
+  args: {
+    day: 'weekend',
+  },
+});
+
+log('Is Weekend:', isWeekend);
+
+// Run 'Show Animation' Flow 'Then' Card
+// This will pulse Green (#00FF00) when it's a weekend
+// or pulse Red (#FF0000) when it's a weekday
+await Homey.flow.runFlowCardAction({
+  uri: 'homey:manager:ledring',
+  id: 'show_animation',
+  args: {
+    animation: 'pulse',
+    color: isWeekend
+      ? '#00FF00'
+      : '#FF0000',
+  },
+});
\ No newline at end of file
diff --git a/examples-v1/global-get.js b/examples-v1/global-get.js
new file mode 100644
index 0000000..71ad74f
--- /dev/null
+++ b/examples-v1/global-get.js
@@ -0,0 +1,9 @@
+/*
+ * This script gets a global variable.
+ */
+
+const value = global.get('myHomeyScriptVariable');
+log('Value:', value);
+
+const keys = global.keys();
+log('Variables:', keys);
\ No newline at end of file
diff --git a/examples-v1/global-set.js b/examples-v1/global-set.js
new file mode 100644
index 0000000..1538d98
--- /dev/null
+++ b/examples-v1/global-set.js
@@ -0,0 +1,5 @@
+/*
+ * This script sets a global variable.
+ */
+
+global.set('myHomeyScriptVariable', 'Some Value');
\ No newline at end of file
diff --git a/examples-v1/hello-world.js b/examples-v1/hello-world.js
new file mode 100644
index 0000000..faf06e6
--- /dev/null
+++ b/examples-v1/hello-world.js
@@ -0,0 +1,7 @@
+/*
+ * This script gets the Homey's owner,
+ * and logs "Hello, <Name>!"
+ */
+
+const user = await Homey.users.getUserMe();
+log(`Hello, ${user.name}!`);
\ No newline at end of file
diff --git a/examples-v1/lodash.js b/examples-v1/lodash.js
new file mode 100644
index 0000000..3ac7624
--- /dev/null
+++ b/examples-v1/lodash.js
@@ -0,0 +1,7 @@
+/*
+ * This script demonstrates how to use lodash.
+ * Read the docs: https://lodash.com
+ */
+
+const result = _.partition([1, 2, 3, 4], n => n % 2)
+log(result);
\ No newline at end of file
diff --git a/examples-v1/printSensorValues.js b/examples-v1/printSensorValues.js
new file mode 100644
index 0000000..7312be8
--- /dev/null
+++ b/examples-v1/printSensorValues.js
@@ -0,0 +1,22 @@
+/*
+ * In this script we print all sensor values.
+ */
+
+// Get all devices
+const devices = await Homey.devices.getDevices();
+
+// Loop over all devices
+for (const device of Object.values(devices)) {
+
+  // If this device isn't available, skip it.
+  if (!device.capabilitiesObj) continue;
+
+  // If this device is a sensor (class)
+  if (device.class === 'sensor') {
+    log(`\n=== ${device.name} ===`);
+
+    for (const capability of Object.values(device.capabilitiesObj)) {
+      log(`${capability.title}: ${capability.value}`);
+    }
+  }
+}
\ No newline at end of file
diff --git a/examples/say.js b/examples-v1/say.js
similarity index 100%
rename from examples/say.js
rename to examples-v1/say.js
diff --git a/examples-v1/tag.js b/examples-v1/tag.js
new file mode 100644
index 0000000..e2c8a1f
--- /dev/null
+++ b/examples-v1/tag.js
@@ -0,0 +1,30 @@
+/*
+ * This script will create a few Tags for use in Flow.
+ * It will remove them after 5 seconds.
+ */
+
+// Create Tags
+log('Creating My String...');
+await tag('My String', 'abcdef');
+
+log('Creating My Number...');
+await tag('My Number', 123);
+
+log('Creating My Boolean...');
+await tag('My Boolean', true);
+
+// Wait 5s
+for (let i = 0; i < 5; i++) {
+  log('.');
+  await wait(1000); // in milliseconds
+}
+
+// Delete Tags
+log('Deleting My String...');
+await tag('My String', null);
+
+log('Deleting My Number...');
+await tag('My Number', null);
+
+log('Deleting My Boolean...');
+await tag('My Boolean', null);
\ No newline at end of file
diff --git a/examples-v1/turnOnDevices.js b/examples-v1/turnOnDevices.js
new file mode 100644
index 0000000..f7b2e41
--- /dev/null
+++ b/examples-v1/turnOnDevices.js
@@ -0,0 +1,21 @@
+/*
+ * In this script we turn on all lights.
+ */
+
+// Get all devices
+const devices = await Homey.devices.getDevices();
+
+// Loop over all devices
+for (const device of Object.values(devices)) {
+
+  // If this device is a light (class)
+  // Or this is a 'What's plugged in?'-light (virtualClass)
+  if (device.class === 'light' || device.virtualClass === 'light') {
+    log(`\nTurning '${device.name}' on...`);
+
+    // Turn the light on by setting the capability `onoff` to `true`
+    await device.setCapabilityValue('onoff', true)
+      .then(() => log('OK'))
+      .catch(error => log(`Error:`, error));
+  }
+}
\ No newline at end of file
diff --git a/examples-v1/wait.js b/examples-v1/wait.js
new file mode 100644
index 0000000..11aca29
--- /dev/null
+++ b/examples-v1/wait.js
@@ -0,0 +1,10 @@
+/*
+ * This script demonstrates how to use wait().
+ */
+
+log('Time 1:', new Date());
+
+// Wait one second (1000 milliseconds)
+await wait(1000);
+
+log('Time 2:', new Date());
\ No newline at end of file
diff --git a/examples/flowcard-list.js b/examples/flowcard-list.js
index 1ffb9c2..8cbabff 100644
--- a/examples/flowcard-list.js
+++ b/examples/flowcard-list.js
@@ -11,10 +11,9 @@ log('===========');
 log('And-cards:');
 log('===========');
 const conditionCards = await Homey.flow.getFlowCardConditions();
-for( const card of conditionCards ) {
+for( const card of Object.values(conditionCards) ) {
   log(card.titleFormatted || card.title)
   log(JSON.stringify({
-    uri: card.uri,
     id: card.id,
     args: card.args,
     droptoken: card.droptoken,
@@ -27,10 +26,9 @@ log('===========');
 log('Then-cards:');
 log('===========');
 const actionCards = await Homey.flow.getFlowCardActions();
-for( const card of actionCards ) {
+for( const card of Object.values(actionCards) ) {
   log(card.titleFormatted || card.title)
   log(JSON.stringify({
-    uri: card.uri,
     id: card.id,
     args: card.args,
     droptoken: card.droptoken,
diff --git a/examples/flowcard-run.js b/examples/flowcard-run.js
index 189fee3..54487d0 100644
--- a/examples/flowcard-run.js
+++ b/examples/flowcard-run.js
@@ -5,8 +5,7 @@
 
 // Run 'Day Equals' Flow 'And' Card
 const { result: isWeekend } = await Homey.flow.runFlowCardCondition({
-  uri: 'homey:manager:cron',
-  id: 'day_equals',
+  id: 'homey:manager:cron:day_equals',
   args: {
     day: 'weekend',
   },
@@ -18,8 +17,7 @@ log('Is Weekend:', isWeekend);
 // This will pulse Green (#00FF00) when it's a weekend
 // or pulse Red (#FF0000) when it's a weekday
 await Homey.flow.runFlowCardAction({
-  uri: 'homey:manager:ledring',
-  id: 'show_animation',
+  id: 'homey:manager:ledring:animate_pulse',
   args: {
     animation: 'pulse',
     color: isWeekend
diff --git a/examples/tag.js b/examples/tag.js
index d82fe14..e2c8a1f 100644
--- a/examples/tag.js
+++ b/examples/tag.js
@@ -13,7 +13,7 @@ await tag('My Number', 123);
 log('Creating My Boolean...');
 await tag('My Boolean', true);
 
-// Wait 15s
+// Wait 5s
 for (let i = 0; i < 5; i++) {
   log('.');
   await wait(1000); // in milliseconds
diff --git a/package-lock.json b/package-lock.json
index ece95ef..cd71126 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "athom-api": "^3.7.7",
+        "homey-api": "^3.0.18",
         "lodash": "^4.17.21",
         "node-fetch": "^2.6.7",
         "uuid": "^8.3.2"
@@ -699,6 +700,11 @@
         "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
       }
     },
+    "node_modules/after": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+      "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA=="
+    },
     "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -905,6 +911,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/arraybuffer.slice": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+      "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
+    },
     "node_modules/asn1.js": {
       "version": "5.4.1",
       "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
@@ -971,6 +982,11 @@
       "optional": true,
       "peer": true
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
     "node_modules/athom-api": {
       "version": "3.7.7",
       "resolved": "https://registry.npmjs.org/athom-api/-/athom-api-3.7.7.tgz",
@@ -989,6 +1005,11 @@
         "node": ">= 4.5.0"
       }
     },
+    "node_modules/backo2": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+      "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA=="
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1078,6 +1099,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/base64-arraybuffer": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+      "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -1130,6 +1159,11 @@
         "file-uri-to-path": "1.0.0"
       }
     },
+    "node_modules/blob": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+      "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
+    },
     "node_modules/bluebird": {
       "version": "3.7.2",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -1650,6 +1684,17 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -1663,12 +1708,20 @@
       "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
       "dev": true
     },
+    "node_modules/component-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+      "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw=="
+    },
     "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==",
-      "dev": true,
-      "peer": true
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
+    },
+    "node_modules/component-inherit": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+      "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA=="
     },
     "node_modules/compressible": {
       "version": "2.0.18",
@@ -1797,6 +1850,16 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/core-js": {
+      "version": "3.32.2",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz",
+      "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==",
+      "hasInstallScript": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
     "node_modules/core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -2020,6 +2083,14 @@
         "node": ">=0.10.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": ">=0.4.0"
+      }
+    },
     "node_modules/des.js": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
@@ -2144,6 +2215,44 @@
         "once": "^1.4.0"
       }
     },
+    "node_modules/engine.io-client": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz",
+      "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==",
+      "dependencies": {
+        "component-emitter": "~1.3.0",
+        "component-inherit": "0.0.3",
+        "debug": "~3.1.0",
+        "engine.io-parser": "~2.2.0",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "ws": "~7.4.2",
+        "xmlhttprequest-ssl": "~1.6.2",
+        "yeast": "0.1.2"
+      }
+    },
+    "node_modules/engine.io-client/node_modules/debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/engine.io-parser": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
+      "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
+      "dependencies": {
+        "after": "0.8.2",
+        "arraybuffer.slice": "~0.0.7",
+        "base64-arraybuffer": "0.1.4",
+        "blob": "0.0.5",
+        "has-binary2": "~1.0.2"
+      }
+    },
     "node_modules/enhanced-resolve": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz",
@@ -3216,6 +3325,19 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/form-data": {
+      "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",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -3466,6 +3588,24 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/has-binary2": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+      "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+      "dependencies": {
+        "isarray": "2.0.1"
+      }
+    },
+    "node_modules/has-binary2/node_modules/isarray": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+      "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ=="
+    },
+    "node_modules/has-cors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+      "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA=="
+    },
     "node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3652,6 +3792,21 @@
         "minimalistic-crypto-utils": "^1.0.1"
       }
     },
+    "node_modules/homey-api": {
+      "version": "3.0.18",
+      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.0.18.tgz",
+      "integrity": "sha512-PtrfeoAd0skC9TRE2VUfwMo2kjOkl5Jq+fk/i0RadCLBzdLP3CPmgb30XKJ8oyVRtHQbqan5tyXHmzkhWa34eg==",
+      "dependencies": {
+        "core-js": "^3.19.1",
+        "form-data": "^4.0.0",
+        "node-fetch": "^2.6.7",
+        "regenerator-runtime": "^0.13.9",
+        "socket.io-client": "^2.5.0"
+      },
+      "engines": {
+        "node": ">=16"
+      }
+    },
     "node_modules/homey-jsdoc-template": {
       "version": "1.0.0",
       "resolved": "git+ssh://git@github.com/athombv/homey-jsdoc-template.git#aef542968fe021aa1672af2b2ca8c1403bad8aa4",
@@ -3748,6 +3903,11 @@
         "node": ">=0.8.19"
       }
     },
+    "node_modules/indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
+    },
     "node_modules/infer-owner": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
@@ -4559,7 +4719,6 @@
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -4568,7 +4727,6 @@
       "version": "2.1.35",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
       "dependencies": {
         "mime-db": "1.52.0"
       },
@@ -4685,8 +4843,7 @@
     "node_modules/ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
-      "dev": true
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
     },
     "node_modules/nan": {
       "version": "2.16.0",
@@ -5194,6 +5351,16 @@
         "safe-buffer": "^5.1.1"
       }
     },
+    "node_modules/parseqs": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+      "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
+    },
+    "node_modules/parseuri": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+      "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
+    },
     "node_modules/pascalcase": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@@ -5670,6 +5837,11 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/regenerator-runtime": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+    },
     "node_modules/regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -6356,6 +6528,55 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/socket.io-client": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
+      "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
+      "dependencies": {
+        "backo2": "1.0.2",
+        "component-bind": "1.0.0",
+        "component-emitter": "~1.3.0",
+        "debug": "~3.1.0",
+        "engine.io-client": "~3.5.0",
+        "has-binary2": "~1.0.2",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "socket.io-parser": "~3.3.0",
+        "to-array": "0.1.4"
+      }
+    },
+    "node_modules/socket.io-client/node_modules/debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/socket.io-parser": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz",
+      "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==",
+      "dependencies": {
+        "component-emitter": "~1.3.0",
+        "debug": "~3.1.0",
+        "isarray": "2.0.1"
+      }
+    },
+    "node_modules/socket.io-parser/node_modules/debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/socket.io-parser/node_modules/isarray": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+      "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ=="
+    },
     "node_modules/source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -6756,6 +6977,11 @@
         "node": ">=0.6.0"
       }
     },
+    "node_modules/to-array": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+      "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A=="
+    },
     "node_modules/to-arraybuffer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
@@ -8157,12 +8383,40 @@
       "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
+    "node_modules/ws": {
+      "version": "7.4.6",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+      "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+      "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
+        }
+      }
+    },
     "node_modules/xmlcreate": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
       "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
       "dev": true
     },
+    "node_modules/xmlhttprequest-ssl": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
+      "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -8219,6 +8473,11 @@
       "engines": {
         "node": ">=10"
       }
+    },
+    "node_modules/yeast": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+      "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg=="
     }
   },
   "dependencies": {
@@ -8752,6 +9011,11 @@
       "dev": true,
       "requires": {}
     },
+    "after": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+      "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA=="
+    },
     "ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -8897,6 +9161,11 @@
         "es-shim-unscopables": "^1.0.0"
       }
     },
+    "arraybuffer.slice": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+      "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
+    },
     "asn1.js": {
       "version": "5.4.1",
       "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
@@ -8964,6 +9233,11 @@
       "optional": true,
       "peer": true
     },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
     "athom-api": {
       "version": "3.7.7",
       "resolved": "https://registry.npmjs.org/athom-api/-/athom-api-3.7.7.tgz",
@@ -8976,6 +9250,11 @@
       "dev": true,
       "peer": true
     },
+    "backo2": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+      "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA=="
+    },
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -9049,6 +9328,11 @@
         }
       }
     },
+    "base64-arraybuffer": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
+      "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg=="
+    },
     "base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -9081,6 +9365,11 @@
         "file-uri-to-path": "1.0.0"
       }
     },
+    "blob": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+      "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
+    },
     "bluebird": {
       "version": "3.7.2",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
@@ -9517,6 +9806,14 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
     "commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -9530,12 +9827,20 @@
       "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
       "dev": true
     },
+    "component-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+      "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw=="
+    },
     "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==",
-      "dev": true,
-      "peer": true
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
+    },
+    "component-inherit": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+      "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA=="
     },
     "compressible": {
       "version": "2.0.18",
@@ -9643,6 +9948,11 @@
       "dev": true,
       "peer": true
     },
+    "core-js": {
+      "version": "3.32.2",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz",
+      "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ=="
+    },
     "core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -9823,6 +10133,11 @@
         "is-descriptor": "^0.1.0"
       }
     },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+    },
     "des.js": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
@@ -9938,6 +10253,46 @@
         "once": "^1.4.0"
       }
     },
+    "engine.io-client": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz",
+      "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==",
+      "requires": {
+        "component-emitter": "~1.3.0",
+        "component-inherit": "0.0.3",
+        "debug": "~3.1.0",
+        "engine.io-parser": "~2.2.0",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "ws": "~7.4.2",
+        "xmlhttprequest-ssl": "~1.6.2",
+        "yeast": "0.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "engine.io-parser": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz",
+      "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==",
+      "requires": {
+        "after": "0.8.2",
+        "arraybuffer.slice": "~0.0.7",
+        "base64-arraybuffer": "0.1.4",
+        "blob": "0.0.5",
+        "has-binary2": "~1.0.2"
+      }
+    },
     "enhanced-resolve": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz",
@@ -10776,6 +11131,16 @@
       "dev": true,
       "peer": true
     },
+    "form-data": {
+      "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",
+        "mime-types": "^2.1.12"
+      }
+    },
     "fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -10962,6 +11327,26 @@
       "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
       "dev": true
     },
+    "has-binary2": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+      "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+      "requires": {
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ=="
+        }
+      }
+    },
+    "has-cors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+      "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA=="
+    },
     "has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -11101,6 +11486,18 @@
         "minimalistic-crypto-utils": "^1.0.1"
       }
     },
+    "homey-api": {
+      "version": "3.0.18",
+      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.0.18.tgz",
+      "integrity": "sha512-PtrfeoAd0skC9TRE2VUfwMo2kjOkl5Jq+fk/i0RadCLBzdLP3CPmgb30XKJ8oyVRtHQbqan5tyXHmzkhWa34eg==",
+      "requires": {
+        "core-js": "^3.19.1",
+        "form-data": "^4.0.0",
+        "node-fetch": "^2.6.7",
+        "regenerator-runtime": "^0.13.9",
+        "socket.io-client": "^2.5.0"
+      }
+    },
     "homey-jsdoc-template": {
       "version": "git+ssh://git@github.com/athombv/homey-jsdoc-template.git#aef542968fe021aa1672af2b2ca8c1403bad8aa4",
       "integrity": "sha512-9zLBqpSCIs/Z7GBDFf0ni9kNMPXLe6ItupHrvOylYR1E9brY4niklfjtQ+trheHWa+ueVu6HriWlT1AQGNeeHw==",
@@ -11162,6 +11559,11 @@
       "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
       "dev": true
     },
+    "indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
+    },
     "infer-owner": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
@@ -11783,14 +12185,12 @@
     "mime-db": {
       "version": "1.52.0",
       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
     },
     "mime-types": {
       "version": "2.1.35",
       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
       "requires": {
         "mime-db": "1.52.0"
       }
@@ -11891,8 +12291,7 @@
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
-      "dev": true
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
     },
     "nan": {
       "version": "2.16.0",
@@ -12296,6 +12695,16 @@
         "safe-buffer": "^5.1.1"
       }
     },
+    "parseqs": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
+      "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
+    },
+    "parseuri": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
+      "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
+    },
     "pascalcase": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
@@ -12664,6 +13073,11 @@
         "picomatch": "^2.2.1"
       }
     },
+    "regenerator-runtime": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+    },
     "regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -13207,6 +13621,59 @@
         }
       }
     },
+    "socket.io-client": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz",
+      "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==",
+      "requires": {
+        "backo2": "1.0.2",
+        "component-bind": "1.0.0",
+        "component-emitter": "~1.3.0",
+        "debug": "~3.1.0",
+        "engine.io-client": "~3.5.0",
+        "has-binary2": "~1.0.2",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.6",
+        "parseuri": "0.0.6",
+        "socket.io-parser": "~3.3.0",
+        "to-array": "0.1.4"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "socket.io-parser": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz",
+      "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==",
+      "requires": {
+        "component-emitter": "~1.3.0",
+        "debug": "~3.1.0",
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ=="
+        }
+      }
+    },
     "source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -13534,6 +14001,11 @@
         "setimmediate": "^1.0.4"
       }
     },
+    "to-array": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+      "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A=="
+    },
     "to-arraybuffer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
@@ -14687,12 +15159,23 @@
       "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
+    "ws": {
+      "version": "7.4.6",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+      "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
+      "requires": {}
+    },
     "xmlcreate": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz",
       "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==",
       "dev": true
     },
+    "xmlhttprequest-ssl": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
+      "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q=="
+    },
     "xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -14739,6 +15222,11 @@
       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
       "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
       "dev": true
+    },
+    "yeast": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+      "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg=="
     }
   }
 }
diff --git a/package.json b/package.json
index 13bc5a9..49b6606 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
   "homepage": "https://github.com/athombv/com.athom.homeyscript#readme",
   "dependencies": {
     "athom-api": "^3.7.7",
+    "homey-api": "^3.0.18",
     "lodash": "^4.17.21",
     "node-fetch": "^2.6.7",
     "uuid": "^8.3.2"

From 889d8a1507fa2d22184c2aead2ec7486c621d5e0 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Wed, 18 Oct 2023 16:21:11 +0200
Subject: [PATCH 02/19] use new api in scripts

---
 .homeycompose/flow/actions/runCode.json       |  1 +
 .../flow/actions/runCodeReturnsBoolean.json   |  1 +
 .../flow/actions/runCodeReturnsNumber.json    |  1 +
 .../flow/actions/runCodeReturnsString.json    |  1 +
 .../flow/actions/runCodeWithArg.json          |  1 +
 .../actions/runCodeWithArgReturnsBoolean.json |  1 +
 .../actions/runCodeWithArgReturnsNumber.json  |  1 +
 .../actions/runCodeWithArgReturnsString.json  |  1 +
 .homeycompose/flow/actions/runCode_v2.json    | 23 +++++
 .homeycompose/flow/conditions/runCode.json    |  1 +
 .../flow/conditions/runCodeWithArg.json       |  1 +
 .../flow/conditions/runCodeWithArg_v2.json    | 37 +++++++
 .homeycompose/flow/conditions/runCode_v2.json | 23 +++++
 app.js                                        | 54 ++++++++++-
 app.json                                      | 96 +++++++++++++++++++
 15 files changed, 239 insertions(+), 4 deletions(-)
 create mode 100644 .homeycompose/flow/actions/runCode_v2.json
 create mode 100644 .homeycompose/flow/conditions/runCodeWithArg_v2.json
 create mode 100644 .homeycompose/flow/conditions/runCode_v2.json

diff --git a/.homeycompose/flow/actions/runCode.json b/.homeycompose/flow/actions/runCode.json
index b0d0a50..3ce2163 100644
--- a/.homeycompose/flow/actions/runCode.json
+++ b/.homeycompose/flow/actions/runCode.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeReturnsBoolean.json b/.homeycompose/flow/actions/runCodeReturnsBoolean.json
index 5321798..c49a91c 100644
--- a/.homeycompose/flow/actions/runCodeReturnsBoolean.json
+++ b/.homeycompose/flow/actions/runCodeReturnsBoolean.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeReturnsNumber.json b/.homeycompose/flow/actions/runCodeReturnsNumber.json
index b00608c..d3c7a9f 100644
--- a/.homeycompose/flow/actions/runCodeReturnsNumber.json
+++ b/.homeycompose/flow/actions/runCodeReturnsNumber.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeReturnsString.json b/.homeycompose/flow/actions/runCodeReturnsString.json
index bff6a0c..43975b1 100644
--- a/.homeycompose/flow/actions/runCodeReturnsString.json
+++ b/.homeycompose/flow/actions/runCodeReturnsString.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeWithArg.json b/.homeycompose/flow/actions/runCodeWithArg.json
index e465dcc..f4c0324 100644
--- a/.homeycompose/flow/actions/runCodeWithArg.json
+++ b/.homeycompose/flow/actions/runCodeWithArg.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean.json b/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean.json
index 4989947..36d9482 100644
--- a/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean.json
+++ b/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeWithArgReturnsNumber.json b/.homeycompose/flow/actions/runCodeWithArgReturnsNumber.json
index b0be764..fa554eb 100644
--- a/.homeycompose/flow/actions/runCodeWithArgReturnsNumber.json
+++ b/.homeycompose/flow/actions/runCodeWithArgReturnsNumber.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCodeWithArgReturnsString.json b/.homeycompose/flow/actions/runCodeWithArgReturnsString.json
index 35e40f2..9017dd1 100644
--- a/.homeycompose/flow/actions/runCodeWithArgReturnsString.json
+++ b/.homeycompose/flow/actions/runCodeWithArgReturnsString.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/actions/runCode_v2.json b/.homeycompose/flow/actions/runCode_v2.json
new file mode 100644
index 0000000..b0d0a50
--- /dev/null
+++ b/.homeycompose/flow/actions/runCode_v2.json
@@ -0,0 +1,23 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]]",
+    "nl": "Voer [[code]] uit"
+  },
+  "advanced": true,
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/conditions/runCode.json b/.homeycompose/flow/conditions/runCode.json
index 857dfec..a67e7a5 100644
--- a/.homeycompose/flow/conditions/runCode.json
+++ b/.homeycompose/flow/conditions/runCode.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/conditions/runCodeWithArg.json b/.homeycompose/flow/conditions/runCodeWithArg.json
index 6189073..77e7c55 100644
--- a/.homeycompose/flow/conditions/runCodeWithArg.json
+++ b/.homeycompose/flow/conditions/runCodeWithArg.json
@@ -1,4 +1,5 @@
 {
+  "deprecated": true,
   "title": {
     "en": "Run code",
     "nl": "Voer code uit"
diff --git a/.homeycompose/flow/conditions/runCodeWithArg_v2.json b/.homeycompose/flow/conditions/runCodeWithArg_v2.json
new file mode 100644
index 0000000..6189073
--- /dev/null
+++ b/.homeycompose/flow/conditions/runCodeWithArg_v2.json
@@ -0,0 +1,37 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] with [[argument]]",
+    "nl": "Voer [[code]] uit met [[argument]]"
+  },
+  "advanced": true,
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn true;"
+    },
+    {
+      "name": "argument",
+      "type": "text",
+      "required": false,
+      "title": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "placeholder": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "value": "MyArg"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/conditions/runCode_v2.json b/.homeycompose/flow/conditions/runCode_v2.json
new file mode 100644
index 0000000..857dfec
--- /dev/null
+++ b/.homeycompose/flow/conditions/runCode_v2.json
@@ -0,0 +1,23 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]]",
+    "nl": "Voer [[code]] uit"
+  },
+  "advanced": true,
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nreturn true;"
+    }
+  ]
+}
diff --git a/app.js b/app.js
index 2f2113c..4779422 100644
--- a/app.js
+++ b/app.js
@@ -14,6 +14,13 @@ const { HomeyAPIV2, HomeyAPIV3Local } = require('homey-api');
 const fetch = require('node-fetch');
 const _ = require('lodash');
 
+// TODO
+// update all examples to use the new Homey API
+// create a changes list
+// deprecate all code cards
+// add script version
+// add script version to front end
+
 module.exports = class HomeyScriptApp extends Homey.App {
 
   static RUN_TIMEOUT = 1000 * 30; // 30s
@@ -22,13 +29,13 @@ module.exports = class HomeyScriptApp extends Homey.App {
     // Init Scripts
     this.scripts = this.homey.settings.get('scripts');
 
-    this.localURL = await this.homey.api.getLocalUrl();
+    this.localUrl = await this.homey.api.getLocalUrl();
     this.sessionToken = await this.homey.api.getOwnerApiToken();
 
     this.apiProps = await (async () => {
       const props = {
         token: this.sessionToken,
-        baseUrl: this.localURL,
+        baseUrl: this.localUrl,
         strategy: [],
         properties: {
           id: await this.homey.cloud.getHomeyId(),
@@ -145,6 +152,19 @@ module.exports = class HomeyScriptApp extends Homey.App {
           code,
           args: [],
           realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        }));
+      });
+
+    this.homey.flow.getConditionCard('runCode_v2')
+      .registerRunListener(async ({ code }, state) => {
+        return Boolean(await this.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
         }));
       });
 
@@ -156,6 +176,19 @@ module.exports = class HomeyScriptApp extends Homey.App {
           code,
           args: [argument],
           realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        }));
+      });
+
+    this.homey.flow.getConditionCard('runCodeWithArg_v2')
+      .registerRunListener(async ({ code, argument }, state) => {
+        return Boolean(await this.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
         }));
       });
 
@@ -229,6 +262,19 @@ module.exports = class HomeyScriptApp extends Homey.App {
           code,
           args: [],
           realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+      });
+
+    this.homey.flow.getActionCard('runCode_v2')
+      .registerRunListener(async ({ code }, state) => {
+        await this.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
         });
       });
 
@@ -364,8 +410,8 @@ module.exports = class HomeyScriptApp extends Homey.App {
     }
 
     const api = new HomeyAPILegacy({
-      localUrl: this.localURL,
-      baseUrl: this.localURL,
+      localUrl: this.localUrl,
+      baseUrl: this.localUrl,
       token: this.sessionToken,
       apiVersion: 2,
       online: true,
diff --git a/app.json b/app.json
index 71e31b8..93862bb 100644
--- a/app.json
+++ b/app.json
@@ -79,6 +79,7 @@
         "id": "run"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -103,6 +104,31 @@
         "id": "runCode"
       },
       {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]]",
+          "nl": "Voer [[code]] uit"
+        },
+        "advanced": true,
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nreturn true;"
+          }
+        ],
+        "id": "runCode_v2"
+      },
+      {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -140,6 +166,44 @@
         ],
         "id": "runCodeWithArg"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] with [[argument]]",
+          "nl": "Voer [[code]] uit met [[argument]]"
+        },
+        "advanced": true,
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn true;"
+          },
+          {
+            "name": "argument",
+            "type": "text",
+            "required": false,
+            "title": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "placeholder": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "value": "MyArg"
+          }
+        ],
+        "id": "runCodeWithArg_v2"
+      },
       {
         "title": {
           "en": "Run a script with an argument",
@@ -197,6 +261,7 @@
         "id": "run"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -221,6 +286,31 @@
         "id": "runCode"
       },
       {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]]",
+          "nl": "Voer [[code]] uit"
+        },
+        "advanced": true,
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code"
+          }
+        ],
+        "id": "runCode_v2"
+      },
+      {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -254,6 +344,7 @@
         "id": "runCodeReturnsBoolean"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -287,6 +378,7 @@
         "id": "runCodeReturnsNumber"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -320,6 +412,7 @@
         "id": "runCodeReturnsString"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -358,6 +451,7 @@
         "id": "runCodeWithArg"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -405,6 +499,7 @@
         "id": "runCodeWithArgReturnsBoolean"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"
@@ -452,6 +547,7 @@
         "id": "runCodeWithArgReturnsNumber"
       },
       {
+        "deprecated": true,
         "title": {
           "en": "Run code",
           "nl": "Voer code uit"

From 960d7b02eb141ffead9fe5f028aef900056130f1 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Fri, 5 Apr 2024 09:05:41 +0200
Subject: [PATCH 03/19] update homey-api

---
 package-lock.json | 43 +++++++------------------------------------
 package.json      |  2 +-
 2 files changed, 8 insertions(+), 37 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index cd71126..7f3131b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "athom-api": "^3.7.7",
-        "homey-api": "^3.0.18",
+        "homey-api": "^3.4.30",
         "lodash": "^4.17.21",
         "node-fetch": "^2.6.7",
         "uuid": "^8.3.2"
@@ -1850,16 +1850,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/core-js": {
-      "version": "3.32.2",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz",
-      "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==",
-      "hasInstallScript": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/core-js"
-      }
-    },
     "node_modules/core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -3793,14 +3783,12 @@
       }
     },
     "node_modules/homey-api": {
-      "version": "3.0.18",
-      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.0.18.tgz",
-      "integrity": "sha512-PtrfeoAd0skC9TRE2VUfwMo2kjOkl5Jq+fk/i0RadCLBzdLP3CPmgb30XKJ8oyVRtHQbqan5tyXHmzkhWa34eg==",
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.4.30.tgz",
+      "integrity": "sha512-jm/mCp4UOSzJRuEUUSxr2OooKAw5g38eg26afN+e+TIs231RawNQ+Pb7KXhSNmU3Z9Fz2SxZJjMUiMO0Pn2QSg==",
       "dependencies": {
-        "core-js": "^3.19.1",
         "form-data": "^4.0.0",
         "node-fetch": "^2.6.7",
-        "regenerator-runtime": "^0.13.9",
         "socket.io-client": "^2.5.0"
       },
       "engines": {
@@ -5837,11 +5825,6 @@
         "node": ">=8.10.0"
       }
     },
-    "node_modules/regenerator-runtime": {
-      "version": "0.13.11",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
-      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
-    },
     "node_modules/regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -9948,11 +9931,6 @@
       "dev": true,
       "peer": true
     },
-    "core-js": {
-      "version": "3.32.2",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz",
-      "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ=="
-    },
     "core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -11487,14 +11465,12 @@
       }
     },
     "homey-api": {
-      "version": "3.0.18",
-      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.0.18.tgz",
-      "integrity": "sha512-PtrfeoAd0skC9TRE2VUfwMo2kjOkl5Jq+fk/i0RadCLBzdLP3CPmgb30XKJ8oyVRtHQbqan5tyXHmzkhWa34eg==",
+      "version": "3.4.30",
+      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.4.30.tgz",
+      "integrity": "sha512-jm/mCp4UOSzJRuEUUSxr2OooKAw5g38eg26afN+e+TIs231RawNQ+Pb7KXhSNmU3Z9Fz2SxZJjMUiMO0Pn2QSg==",
       "requires": {
-        "core-js": "^3.19.1",
         "form-data": "^4.0.0",
         "node-fetch": "^2.6.7",
-        "regenerator-runtime": "^0.13.9",
         "socket.io-client": "^2.5.0"
       }
     },
@@ -13073,11 +13049,6 @@
         "picomatch": "^2.2.1"
       }
     },
-    "regenerator-runtime": {
-      "version": "0.13.11",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
-      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
-    },
     "regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
diff --git a/package.json b/package.json
index 49b6606..561e6f3 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,7 @@
   "homepage": "https://github.com/athombv/com.athom.homeyscript#readme",
   "dependencies": {
     "athom-api": "^3.7.7",
-    "homey-api": "^3.0.18",
+    "homey-api": "^3.4.30",
     "lodash": "^4.17.21",
     "node-fetch": "^2.6.7",
     "uuid": "^8.3.2"

From 3f7d3eb3ae20598367b8c10a5b1ab06081f8d7f3 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Sun, 7 Apr 2024 15:44:49 +0200
Subject: [PATCH 04/19] add all new cards

---
 .eslintrc.js                                  |   21 +
 .eslintrc.json                                |    6 -
 .../actions/runCodeReturnsBoolean_v2.json     |   32 +
 .../flow/actions/runCodeReturnsNumber_v2.json |   32 +
 .../flow/actions/runCodeReturnsString_v2.json |   32 +
 .../runCodeWithArgReturnsBoolean_v2.json      |   46 +
 .../runCodeWithArgReturnsNumber_v2.json       |   46 +
 .../runCodeWithArgReturnsString_v2.json       |   46 +
 .../flow/actions/runCodeWithArg_v2.json       |   37 +
 .homeyplugins.json                            |    5 -
 .prettierrc                                   |    5 +
 api.js                                        |    6 +-
 app.js                                        |  294 +-
 app.json                                      |  278 ++
 lib/Base.js                                   |   21 +
 lib/flow/actions/RunAction.js                 |   35 +
 lib/flow/actions/RunCodeAction.js             |   37 +
 .../actions/RunCodeReturnsBooleanAction.js    |   49 +
 .../actions/RunCodeReturnsNumberAction.js     |   49 +
 .../actions/RunCodeReturnsStringAction.js     |   49 +
 lib/flow/actions/RunCodeWithArgAction.js      |   41 +
 .../actions/RunCodeWithArgReturnsBoolean.js   |   49 +
 .../RunCodeWithArgReturnsNumberAction.js      |   49 +
 .../RunCodeWithArgReturnsStringAction.js      |   49 +
 lib/flow/actions/RunWithArgAction.js          |   36 +
 lib/flow/conditions/RunCodeCondition.js       |   41 +
 .../conditions/RunCodeWithArgCondition.js     |   45 +
 lib/flow/conditions/RunCondition.js           |   35 +
 lib/flow/conditions/RunWithArgCondition.js    |   36 +
 package-lock.json                             | 3195 +++--------------
 package.json                                  |    6 +-
 31 files changed, 1763 insertions(+), 2945 deletions(-)
 create mode 100644 .eslintrc.js
 delete mode 100644 .eslintrc.json
 create mode 100644 .homeycompose/flow/actions/runCodeReturnsBoolean_v2.json
 create mode 100644 .homeycompose/flow/actions/runCodeReturnsNumber_v2.json
 create mode 100644 .homeycompose/flow/actions/runCodeReturnsString_v2.json
 create mode 100644 .homeycompose/flow/actions/runCodeWithArgReturnsBoolean_v2.json
 create mode 100644 .homeycompose/flow/actions/runCodeWithArgReturnsNumber_v2.json
 create mode 100644 .homeycompose/flow/actions/runCodeWithArgReturnsString_v2.json
 create mode 100644 .homeycompose/flow/actions/runCodeWithArg_v2.json
 delete mode 100644 .homeyplugins.json
 create mode 100644 .prettierrc
 create mode 100644 lib/Base.js
 create mode 100644 lib/flow/actions/RunAction.js
 create mode 100644 lib/flow/actions/RunCodeAction.js
 create mode 100644 lib/flow/actions/RunCodeReturnsBooleanAction.js
 create mode 100644 lib/flow/actions/RunCodeReturnsNumberAction.js
 create mode 100644 lib/flow/actions/RunCodeReturnsStringAction.js
 create mode 100644 lib/flow/actions/RunCodeWithArgAction.js
 create mode 100644 lib/flow/actions/RunCodeWithArgReturnsBoolean.js
 create mode 100644 lib/flow/actions/RunCodeWithArgReturnsNumberAction.js
 create mode 100644 lib/flow/actions/RunCodeWithArgReturnsStringAction.js
 create mode 100644 lib/flow/actions/RunWithArgAction.js
 create mode 100644 lib/flow/conditions/RunCodeCondition.js
 create mode 100644 lib/flow/conditions/RunCodeWithArgCondition.js
 create mode 100644 lib/flow/conditions/RunCondition.js
 create mode 100644 lib/flow/conditions/RunWithArgCondition.js

diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..4ca8db3
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,21 @@
+'use strict';
+
+module.exports = {
+  root: true,
+  extends: ['eslint:recommended', 'prettier'],
+  env: {
+    node: true,
+    es2023: true,
+  },
+  overrides: [
+    {
+      files: ['*.js', '*.mjs'],
+      rules: {
+        'no-unused-vars': ['warn', { args: 'none' }],
+      },
+    },
+  ],
+  ignorePatterns: [
+    "/examples/**"
+  ]
+};
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 794c55f..0000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "extends": "athom",
-  "ignorePatterns": [
-    "/examples/**"
-  ]
-}
\ No newline at end of file
diff --git a/.homeycompose/flow/actions/runCodeReturnsBoolean_v2.json b/.homeycompose/flow/actions/runCodeReturnsBoolean_v2.json
new file mode 100644
index 0000000..5321798
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeReturnsBoolean_v2.json
@@ -0,0 +1,32 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] and return Yes/No-tag",
+    "nl": "Voer [[code]] uit en return Ja/Nee-tag"
+  },
+  "tokens": [
+    {
+      "name": "boolean",
+      "type": "boolean",
+      "title": {
+        "en": "Result",
+        "nl": "Resultaat"
+      }
+    }
+  ],
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nreturn true;"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/actions/runCodeReturnsNumber_v2.json b/.homeycompose/flow/actions/runCodeReturnsNumber_v2.json
new file mode 100644
index 0000000..b00608c
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeReturnsNumber_v2.json
@@ -0,0 +1,32 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] and return Number-tag",
+    "nl": "Voer [[code]] uit en return Nummer-tag"
+  },
+  "tokens": [
+    {
+      "name": "number",
+      "type": "number",
+      "title": {
+        "en": "Result",
+        "nl": "Resultaat"
+      }
+    }
+  ],
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nreturn 1;"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/actions/runCodeReturnsString_v2.json b/.homeycompose/flow/actions/runCodeReturnsString_v2.json
new file mode 100644
index 0000000..bff6a0c
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeReturnsString_v2.json
@@ -0,0 +1,32 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] and return Text-tag",
+    "nl": "Voer [[code]] uit en return Tekst-tag"
+  },
+  "tokens": [
+    {
+      "name": "string",
+      "type": "string",
+      "title": {
+        "en": "Result",
+        "nl": "Resultaat"
+      }
+    }
+  ],
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nreturn 'Hello World!';"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean_v2.json b/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean_v2.json
new file mode 100644
index 0000000..4989947
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeWithArgReturnsBoolean_v2.json
@@ -0,0 +1,46 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] with [[argument]] and return Yes/No-tag",
+    "nl": "Voer [[code]] uit met [[argument]] en return Ja/Nee-tag"
+  },
+  "tokens": [
+    {
+      "name": "boolean",
+      "type": "boolean",
+      "title": {
+        "en": "Result",
+        "nl": "Resultaat"
+      }
+    }
+  ],
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn true;"
+    },
+    {
+      "name": "argument",
+      "type": "text",
+      "required": false,
+      "title": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "placeholder": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "value": "MyArg"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/actions/runCodeWithArgReturnsNumber_v2.json b/.homeycompose/flow/actions/runCodeWithArgReturnsNumber_v2.json
new file mode 100644
index 0000000..b0be764
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeWithArgReturnsNumber_v2.json
@@ -0,0 +1,46 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] with [[argument]] and return Number-tag",
+    "nl": "Voer [[code]] uit met [[argument]] en return Nummer-tag"
+  },
+  "tokens": [
+    {
+      "name": "number",
+      "type": "number",
+      "title": {
+        "en": "Result",
+        "nl": "Resultaat"
+      }
+    }
+  ],
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn 1;"
+    },
+    {
+      "name": "argument",
+      "type": "text",
+      "required": false,
+      "title": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "placeholder": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "value": "MyArg"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/actions/runCodeWithArgReturnsString_v2.json b/.homeycompose/flow/actions/runCodeWithArgReturnsString_v2.json
new file mode 100644
index 0000000..35e40f2
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeWithArgReturnsString_v2.json
@@ -0,0 +1,46 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] with [[argument]] and return Text-tag",
+    "nl": "Voer [[code]] uit met [[argument]] en return Tekst-tag"
+  },
+  "tokens": [
+    {
+      "name": "string",
+      "type": "string",
+      "title": {
+        "en": "Result",
+        "nl": "Resultaat"
+      }
+    }
+  ],
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn 'Hello World!';"
+    },
+    {
+      "name": "argument",
+      "type": "text",
+      "required": false,
+      "title": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "placeholder": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "value": "MyArg"
+    }
+  ]
+}
diff --git a/.homeycompose/flow/actions/runCodeWithArg_v2.json b/.homeycompose/flow/actions/runCodeWithArg_v2.json
new file mode 100644
index 0000000..e465dcc
--- /dev/null
+++ b/.homeycompose/flow/actions/runCodeWithArg_v2.json
@@ -0,0 +1,37 @@
+{
+  "title": {
+    "en": "Run code",
+    "nl": "Voer code uit"
+  },
+  "titleFormatted": {
+    "en": "Run [[code]] with [[argument]]",
+    "nl": "Voer [[code]] uit met [[argument]]"
+  },
+  "advanced": true,
+  "args": [
+    {
+      "name": "code",
+      "type": "code",
+      "language": "homeyscript",
+      "title": {
+        "en": "Code",
+        "nl": "Code"
+      },
+      "value": "// My Code\n\nconsole.log(args[0]);"
+    },
+    {
+      "name": "argument",
+      "type": "text",
+      "required": false,
+      "title": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "placeholder": {
+        "en": "Argument",
+        "nl": "Argument"
+      },
+      "value": "MyArg"
+    }
+  ]
+}
diff --git a/.homeyplugins.json b/.homeyplugins.json
deleted file mode 100644
index 7fa530b..0000000
--- a/.homeyplugins.json
+++ /dev/null
@@ -1,5 +0,0 @@
-[
-  {
-    "id": "compose"
-  }
-]
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..7de6938
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,5 @@
+{
+  "semi": true,
+  "singleQuote": true,
+  "printWidth": 100
+}
diff --git a/api.js b/api.js
index 3d97db9..7db9d93 100644
--- a/api.js
+++ b/api.js
@@ -30,7 +30,7 @@ module.exports = {
       const result = await homey.app.runScript({
         id: script.id,
         name: script.name,
-        code: code || script.code,
+        code: code ?? script.code,
         lastExecuted: script.lastExecuted,
         version: 2,
         args,
@@ -63,9 +63,9 @@ module.exports = {
     homey, params, query, body = {},
   }) {
     const { id } = params;
-    const { name, code } = body;
+    const { name, code, version } = body;
 
-    return homey.app.updateScript({ id, name, code });
+    return homey.app.updateScript({ id, name, code, version });
   },
 
   async deleteScript({ homey, params }) {
diff --git a/app.js b/app.js
index 4779422..ba52741 100644
--- a/app.js
+++ b/app.js
@@ -14,12 +14,25 @@ const { HomeyAPIV2, HomeyAPIV3Local } = require('homey-api');
 const fetch = require('node-fetch');
 const _ = require('lodash');
 
+const { RunCondition } = require('./lib/flow/conditions/RunCondition');
+const { RunWithArgCondition } = require('./lib/flow/conditions/RunWithArgCondition');
+const { RunCodeCondition } = require('./lib/flow/conditions/RunCodeCondition');
+const { RunCodeWithArgCondition } = require('./lib/flow/conditions/RunCodeWithArgCondition');
+
+const { RunAction } = require('./lib/flow/actions/RunAction');
+const { RunCodeAction } = require('./lib/flow/actions/RunCodeAction');
+const { RunWithArgAction } = require('./lib/flow/actions/RunWithArgAction');
+const { RunCodeReturnsStringAction } = require('./lib/flow/actions/RunCodeReturnsStringAction');
+const { RunCodeReturnsNumberAction } = require('./lib/flow/actions/RunCodeReturnsNumberAction');
+const { RunCodeReturnsBooleanAction } = require('./lib/flow/actions/RunCodeReturnsBooleanAction');
+const { RunCodeWithArgAction } = require('./lib/flow/actions/RunCodeWithArgAction');
+const { RunCodeWithArgReturnsStringAction } = require('./lib/flow/actions/RunCodeWithArgReturnsStringAction');
+const { RunCodeWithArgReturnsNumberAction } = require('./lib/flow/actions/RunCodeWithArgReturnsNumberAction');
+const { RunCodeWithArgReturnsBoolean } = require('./lib/flow/actions/RunCodeWithArgReturnsBoolean');
+
 // TODO
 // update all examples to use the new Homey API
 // create a changes list
-// deprecate all code cards
-// add script version
-// add script version to front end
 
 module.exports = class HomeyScriptApp extends Homey.App {
 
@@ -100,7 +113,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
       this.homey.settings.set('scripts', this.scripts);
     }
 
-    // Migration: Add missing `name` property
+    // Migration
     if (this.scripts) {
       const scriptEntries = Object.entries(this.scripts);
       let anyScriptChanged = false;
@@ -124,260 +137,21 @@ module.exports = class HomeyScriptApp extends Homey.App {
     }
 
     // Register Flow Cards
-    this.homey.flow.getConditionCard('run')
-      .registerRunListener(async ({ script }) => {
-        const scriptSource = await this.getScript({ id: script.id });
-
-        return this.runScript({
-          id: scriptSource.id,
-          name: scriptSource.name,
-          code: scriptSource.code,
-          lastExecuted: scriptSource.lastExecuted,
-          version: scriptSource.version,
-          realtime: false,
-        }).finally(() => {
-          this.updateScript({
-            id: scriptSource.id,
-            lastExecuted: new Date(),
-          }).catch(this.error);
-        });
-      })
-      .registerArgumentAutocompleteListener('script', query => this.onFlowGetScriptAutocomplete(query));
-
-    this.homey.flow.getConditionCard('runCode')
-      .registerRunListener(async ({ code }, state) => {
-        return Boolean(await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-          version: 1,
-        }));
-      });
-
-    this.homey.flow.getConditionCard('runCode_v2')
-      .registerRunListener(async ({ code }, state) => {
-        return Boolean(await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-          version: 2,
-        }));
-      });
-
-    this.homey.flow.getConditionCard('runCodeWithArg')
-      .registerRunListener(async ({ code, argument }, state) => {
-        return Boolean(await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [argument],
-          realtime: state.realtime != null ? state.realtime : false,
-          version: 1,
-        }));
-      });
-
-    this.homey.flow.getConditionCard('runCodeWithArg_v2')
-      .registerRunListener(async ({ code, argument }, state) => {
-        return Boolean(await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [argument],
-          realtime: state.realtime != null ? state.realtime : false,
-          version: 2,
-        }));
-      });
-
-    this.homey.flow.getConditionCard('runWithArg')
-      .registerRunListener(async ({ script, argument }) => {
-        const scriptSource = await this.getScript({ id: script.id });
-
-        return this.runScript({
-          id: scriptSource.id,
-          name: scriptSource.name,
-          code: scriptSource.code,
-          lastExecuted: scriptSource.lastExecuted,
-          version: scriptSource.version,
-          args: [argument],
-          realtime: false,
-        }).finally(() => {
-          this.updateScript({
-            id: scriptSource.id,
-            lastExecuted: new Date(),
-          }).catch(this.error);
-        });
-      })
-      .registerArgumentAutocompleteListener('script', query => this.onFlowGetScriptAutocomplete(query));
-
-    this.homey.flow.getActionCard('run')
-      .registerRunListener(async ({ script }) => {
-        const scriptSource = await this.getScript({ id: script.id });
-
-        return this.runScript({
-          id: scriptSource.id,
-          name: scriptSource.name,
-          code: scriptSource.code,
-          lastExecuted: scriptSource.lastExecuted,
-          version: scriptSource.version,
-          realtime: false,
-        }).finally(() => {
-          this.updateScript({
-            id: scriptSource.id,
-            lastExecuted: new Date(),
-          }).catch(this.error);
-        });
-      })
-      .registerArgumentAutocompleteListener('script', query => this.onFlowGetScriptAutocomplete(query));
-
-    this.homey.flow.getActionCard('runWithArg')
-      .registerRunListener(async ({ script, argument }) => {
-        const scriptSource = await this.getScript({ id: script.id });
-
-        return this.runScript({
-          id: scriptSource.id,
-          name: scriptSource.name,
-          code: scriptSource.code,
-          lastExecuted: scriptSource.lastExecuted,
-          version: scriptSource.version,
-          args: [argument],
-          realtime: false,
-        }).finally(() => {
-          this.updateScript({
-            id: scriptSource.id,
-            lastExecuted: new Date(),
-          }).catch(this.error);
-        });
-      })
-      .registerArgumentAutocompleteListener('script', query => this.onFlowGetScriptAutocomplete(query));
-
-    this.homey.flow.getActionCard('runCode')
-      .registerRunListener(async ({ code }, state) => {
-        await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-          version: 1,
-        });
-      });
-
-    this.homey.flow.getActionCard('runCode_v2')
-      .registerRunListener(async ({ code }, state) => {
-        await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-          version: 2,
-        });
-      });
-
-    this.homey.flow.getActionCard('runCodeReturnsString')
-      .registerRunListener(async ({ code }, state) => {
-        const result = await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-
-        return {
-          string: result,
-        };
-      });
-
-    this.homey.flow.getActionCard('runCodeReturnsNumber')
-      .registerRunListener(async ({ code }, state) => {
-        const result = await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-
-        return {
-          number: result,
-        };
-      });
-
-    this.homey.flow.getActionCard('runCodeReturnsBoolean')
-      .registerRunListener(async ({ code }, state) => {
-        const result = await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-
-        return {
-          boolean: result,
-        };
-      });
-
-    this.homey.flow.getActionCard('runCodeWithArg')
-      .registerRunListener(async ({ code, argument }, state) => {
-        await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [argument],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-      });
-
-    this.homey.flow.getActionCard('runCodeWithArgReturnsString')
-      .registerRunListener(async ({ code, argument }, state) => {
-        const result = await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [argument],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-
-        return {
-          string: result,
-        };
-      });
-
-    this.homey.flow.getActionCard('runCodeWithArgReturnsNumber')
-      .registerRunListener(async ({ code, argument }, state) => {
-        const result = await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [argument],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-
-        return {
-          number: result,
-        };
-      });
-
-    this.homey.flow.getActionCard('runCodeWithArgReturnsBoolean')
-      .registerRunListener(async ({ code, argument }, state) => {
-        const result = await this.runScript({
-          id: '__temporary__',
-          name: 'Test',
-          code,
-          args: [argument],
-          realtime: state.realtime != null ? state.realtime : false,
-        });
-
-        return {
-          boolean: result,
-        };
-      });
+    this.runCondition = new RunCondition({ homey: this.homey });
+    this.runWithArgCondition = new RunWithArgCondition({ homey: this.homey });
+    this.runCodeCondition = new RunCodeCondition({ homey: this.homey });
+    this.runCodeWithArgCondition = new RunCodeWithArgCondition({ homey: this.homey });
+
+    this.runAction = new RunAction({ homey: this.homey });
+    this.runWithArgAction = new RunWithArgAction({ homey: this.homey });
+    this.runCodeAction = new RunCodeAction({ homey: this.homey });
+    this.runCodeReturnsStringAction = new RunCodeReturnsStringAction({ homey: this.homey });
+    this.runCodeReturnsNumberAction = new RunCodeReturnsNumberAction({ homey: this.homey });
+    this.runCodeReturnsBooleanAction = new RunCodeReturnsBooleanAction({ homey: this.homey });
+    this.runCodeWithArgAction = new RunCodeWithArgAction({ homey: this.homey });
+    this.runCodeWithArgReturnsStringAction = new RunCodeWithArgReturnsStringAction({ homey: this.homey });
+    this.runCodeWithArgReturnsNumberAction = new RunCodeWithArgReturnsNumberAction({ homey: this.homey });
+    this.runCodeWithArgReturnsBoolean = new RunCodeWithArgReturnsBoolean({ homey: this.homey });
 
     // Register Flow Tokens
     this.tokens = this.homey.settings.get('tokens') || {};
@@ -397,7 +171,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
       return new HomeyAPIV2(this.apiProps);
     }
 
-    if (this.homey.platform === 'local' && this.homey.platformVersion === 2) {
+    if (this.homey.platform === 'local' && this.homey.platformVersion >= 2) {
       return new HomeyAPIV3Local(this.apiProps);
     }
 
@@ -502,8 +276,6 @@ module.exports = class HomeyScriptApp extends Homey.App {
 
     const homeyAPI = this.getHomeyAPI({ version });
 
-    console.log(homeyAPI);
-
     // Create a Logger
     const log = (...props) => {
       this.log(`[${name}]`, ...props);
diff --git a/app.json b/app.json
index 93862bb..461a558 100644
--- a/app.json
+++ b/app.json
@@ -343,6 +343,39 @@
         ],
         "id": "runCodeReturnsBoolean"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] and return Yes/No-tag",
+          "nl": "Voer [[code]] uit en return Ja/Nee-tag"
+        },
+        "tokens": [
+          {
+            "name": "boolean",
+            "type": "boolean",
+            "title": {
+              "en": "Result",
+              "nl": "Resultaat"
+            }
+          }
+        ],
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nreturn true;"
+          }
+        ],
+        "id": "runCodeReturnsBoolean_v2"
+      },
       {
         "deprecated": true,
         "title": {
@@ -377,6 +410,39 @@
         ],
         "id": "runCodeReturnsNumber"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] and return Number-tag",
+          "nl": "Voer [[code]] uit en return Nummer-tag"
+        },
+        "tokens": [
+          {
+            "name": "number",
+            "type": "number",
+            "title": {
+              "en": "Result",
+              "nl": "Resultaat"
+            }
+          }
+        ],
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nreturn 1;"
+          }
+        ],
+        "id": "runCodeReturnsNumber_v2"
+      },
       {
         "deprecated": true,
         "title": {
@@ -411,6 +477,39 @@
         ],
         "id": "runCodeReturnsString"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] and return Text-tag",
+          "nl": "Voer [[code]] uit en return Tekst-tag"
+        },
+        "tokens": [
+          {
+            "name": "string",
+            "type": "string",
+            "title": {
+              "en": "Result",
+              "nl": "Resultaat"
+            }
+          }
+        ],
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nreturn 'Hello World!';"
+          }
+        ],
+        "id": "runCodeReturnsString_v2"
+      },
       {
         "deprecated": true,
         "title": {
@@ -450,6 +549,44 @@
         ],
         "id": "runCodeWithArg"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] with [[argument]]",
+          "nl": "Voer [[code]] uit met [[argument]]"
+        },
+        "advanced": true,
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nconsole.log(args[0]);"
+          },
+          {
+            "name": "argument",
+            "type": "text",
+            "required": false,
+            "title": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "placeholder": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "value": "MyArg"
+          }
+        ],
+        "id": "runCodeWithArg_v2"
+      },
       {
         "deprecated": true,
         "title": {
@@ -498,6 +635,53 @@
         ],
         "id": "runCodeWithArgReturnsBoolean"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] with [[argument]] and return Yes/No-tag",
+          "nl": "Voer [[code]] uit met [[argument]] en return Ja/Nee-tag"
+        },
+        "tokens": [
+          {
+            "name": "boolean",
+            "type": "boolean",
+            "title": {
+              "en": "Result",
+              "nl": "Resultaat"
+            }
+          }
+        ],
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn true;"
+          },
+          {
+            "name": "argument",
+            "type": "text",
+            "required": false,
+            "title": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "placeholder": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "value": "MyArg"
+          }
+        ],
+        "id": "runCodeWithArgReturnsBoolean_v2"
+      },
       {
         "deprecated": true,
         "title": {
@@ -546,6 +730,53 @@
         ],
         "id": "runCodeWithArgReturnsNumber"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] with [[argument]] and return Number-tag",
+          "nl": "Voer [[code]] uit met [[argument]] en return Nummer-tag"
+        },
+        "tokens": [
+          {
+            "name": "number",
+            "type": "number",
+            "title": {
+              "en": "Result",
+              "nl": "Resultaat"
+            }
+          }
+        ],
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn 1;"
+          },
+          {
+            "name": "argument",
+            "type": "text",
+            "required": false,
+            "title": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "placeholder": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "value": "MyArg"
+          }
+        ],
+        "id": "runCodeWithArgReturnsNumber_v2"
+      },
       {
         "deprecated": true,
         "title": {
@@ -594,6 +825,53 @@
         ],
         "id": "runCodeWithArgReturnsString"
       },
+      {
+        "title": {
+          "en": "Run code",
+          "nl": "Voer code uit"
+        },
+        "titleFormatted": {
+          "en": "Run [[code]] with [[argument]] and return Text-tag",
+          "nl": "Voer [[code]] uit met [[argument]] en return Tekst-tag"
+        },
+        "tokens": [
+          {
+            "name": "string",
+            "type": "string",
+            "title": {
+              "en": "Result",
+              "nl": "Resultaat"
+            }
+          }
+        ],
+        "args": [
+          {
+            "name": "code",
+            "type": "code",
+            "language": "homeyscript",
+            "title": {
+              "en": "Code",
+              "nl": "Code"
+            },
+            "value": "// My Code\n\nconsole.log(args[0]);\n\nreturn 'Hello World!';"
+          },
+          {
+            "name": "argument",
+            "type": "text",
+            "required": false,
+            "title": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "placeholder": {
+              "en": "Argument",
+              "nl": "Argument"
+            },
+            "value": "MyArg"
+          }
+        ],
+        "id": "runCodeWithArgReturnsString_v2"
+      },
       {
         "title": {
           "en": "Run a script with an argument",
diff --git a/lib/Base.js b/lib/Base.js
new file mode 100644
index 0000000..5aced97
--- /dev/null
+++ b/lib/Base.js
@@ -0,0 +1,21 @@
+'use strict';
+
+class Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    this.homey = homey;
+
+    this.log = (...args) => {
+      homey.emit('__log', `[${this.constructor.name}]`, ...args);
+    };
+
+    this.error = (...args) => {
+      homey.emit('__error', `[${this.constructor.name}]`, ...args);
+    };
+  }
+}
+
+module.exports = { Base };
diff --git a/lib/flow/actions/RunAction.js b/lib/flow/actions/RunAction.js
new file mode 100644
index 0000000..2060145
--- /dev/null
+++ b/lib/flow/actions/RunAction.js
@@ -0,0 +1,35 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow.getActionCard('run')
+      .registerRunListener(async ({ script }) => {
+        const scriptSource = await this.homey.app.getScript({ id: script.id });
+
+        return this.homey.app.runScript({
+          id: scriptSource.id,
+          name: scriptSource.name,
+          code: scriptSource.code,
+          lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
+          realtime: false,
+        }).finally(() => {
+          this.homey.app.updateScript({
+            id: scriptSource.id,
+            lastExecuted: new Date(),
+          }).catch(this.error);
+        });
+      })
+      .registerArgumentAutocompleteListener('script', query => this.homey.app.onFlowGetScriptAutocomplete(query));
+  }
+}
+
+module.exports = { RunAction };
diff --git a/lib/flow/actions/RunCodeAction.js b/lib/flow/actions/RunCodeAction.js
new file mode 100644
index 0000000..e6661e3
--- /dev/null
+++ b/lib/flow/actions/RunCodeAction.js
@@ -0,0 +1,37 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow.getActionCard('runCode').registerRunListener(async ({ code }, state) => {
+      await this.homey.app.runScript({
+        id: '__temporary__',
+        name: 'Test',
+        code,
+        args: [],
+        realtime: state.realtime != null ? state.realtime : false,
+        version: 1,
+      });
+    });
+
+    this.homey.flow.getActionCard('runCode_v2').registerRunListener(async ({ code }, state) => {
+      await this.homey.app.runScript({
+        id: '__temporary__',
+        name: 'Test',
+        code,
+        args: [],
+        realtime: state.realtime != null ? state.realtime : false,
+        version: 2,
+      });
+    });
+  }
+}
+
+module.exports = { RunCodeAction };
diff --git a/lib/flow/actions/RunCodeReturnsBooleanAction.js b/lib/flow/actions/RunCodeReturnsBooleanAction.js
new file mode 100644
index 0000000..69588b1
--- /dev/null
+++ b/lib/flow/actions/RunCodeReturnsBooleanAction.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeReturnsBooleanAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeReturnsBoolean')
+      .registerRunListener(async ({ code }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+
+        return {
+          boolean: result,
+        };
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeReturnsBoolean_v2')
+      .registerRunListener(async ({ code }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+
+        return {
+          boolean: result,
+        };
+      });
+  }
+}
+
+module.exports = { RunCodeReturnsBooleanAction };
diff --git a/lib/flow/actions/RunCodeReturnsNumberAction.js b/lib/flow/actions/RunCodeReturnsNumberAction.js
new file mode 100644
index 0000000..ae45f0b
--- /dev/null
+++ b/lib/flow/actions/RunCodeReturnsNumberAction.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeReturnsNumberAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeReturnsNumber')
+      .registerRunListener(async ({ code }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+
+        return {
+          number: result,
+        };
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeReturnsNumber_v2')
+      .registerRunListener(async ({ code }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+
+        return {
+          number: result,
+        };
+      });
+  }
+}
+
+module.exports = { RunCodeReturnsNumberAction };
diff --git a/lib/flow/actions/RunCodeReturnsStringAction.js b/lib/flow/actions/RunCodeReturnsStringAction.js
new file mode 100644
index 0000000..59c5249
--- /dev/null
+++ b/lib/flow/actions/RunCodeReturnsStringAction.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeReturnsStringAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeReturnsString')
+      .registerRunListener(async ({ code }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+
+        return {
+          string: result,
+        };
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeReturnsString_v2')
+      .registerRunListener(async ({ code }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+
+        return {
+          string: result,
+        };
+      });
+  }
+}
+
+module.exports = { RunCodeReturnsStringAction };
diff --git a/lib/flow/actions/RunCodeWithArgAction.js b/lib/flow/actions/RunCodeWithArgAction.js
new file mode 100644
index 0000000..7f04be2
--- /dev/null
+++ b/lib/flow/actions/RunCodeWithArgAction.js
@@ -0,0 +1,41 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeWithArgAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArg')
+      .registerRunListener(async ({ code, argument }, state) => {
+        await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArg_v2')
+      .registerRunListener(async ({ code, argument }, state) => {
+        await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+      });
+  }
+}
+
+module.exports = { RunCodeWithArgAction };
diff --git a/lib/flow/actions/RunCodeWithArgReturnsBoolean.js b/lib/flow/actions/RunCodeWithArgReturnsBoolean.js
new file mode 100644
index 0000000..b474529
--- /dev/null
+++ b/lib/flow/actions/RunCodeWithArgReturnsBoolean.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeWithArgReturnsBoolean extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArgReturnsBoolean')
+      .registerRunListener(async ({ code, argument }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+
+        return {
+          boolean: result,
+        };
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArgReturnsBoolean_v2')
+      .registerRunListener(async ({ code, argument }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+
+        return {
+          boolean: result,
+        };
+      });
+  }
+}
+
+module.exports = { RunCodeWithArgReturnsBoolean };
diff --git a/lib/flow/actions/RunCodeWithArgReturnsNumberAction.js b/lib/flow/actions/RunCodeWithArgReturnsNumberAction.js
new file mode 100644
index 0000000..742fc06
--- /dev/null
+++ b/lib/flow/actions/RunCodeWithArgReturnsNumberAction.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeWithArgReturnsNumberAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArgReturnsNumber')
+      .registerRunListener(async ({ code, argument }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+
+        return {
+          number: result,
+        };
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArgReturnsNumber_v2')
+      .registerRunListener(async ({ code, argument }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+
+        return {
+          number: result,
+        };
+      });
+  }
+}
+
+module.exports = { RunCodeWithArgReturnsNumberAction };
diff --git a/lib/flow/actions/RunCodeWithArgReturnsStringAction.js b/lib/flow/actions/RunCodeWithArgReturnsStringAction.js
new file mode 100644
index 0000000..6863138
--- /dev/null
+++ b/lib/flow/actions/RunCodeWithArgReturnsStringAction.js
@@ -0,0 +1,49 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeWithArgReturnsStringAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArgReturnsString')
+      .registerRunListener(async ({ code, argument }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        });
+
+        return {
+          string: result,
+        };
+      });
+
+    this.homey.flow
+      .getActionCard('runCodeWithArgReturnsString_v2')
+      .registerRunListener(async ({ code, argument }, state) => {
+        const result = await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [argument],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        });
+
+        return {
+          string: result,
+        };
+      });
+  }
+}
+
+module.exports = { RunCodeWithArgReturnsStringAction };
diff --git a/lib/flow/actions/RunWithArgAction.js b/lib/flow/actions/RunWithArgAction.js
new file mode 100644
index 0000000..7871bb3
--- /dev/null
+++ b/lib/flow/actions/RunWithArgAction.js
@@ -0,0 +1,36 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunWithArgAction extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow.getActionCard('runWithArg')
+    .registerRunListener(async ({ script, argument }) => {
+      const scriptSource = await this.homey.app.getScript({ id: script.id });
+
+      return this.homey.app.runScript({
+        id: scriptSource.id,
+        name: scriptSource.name,
+        code: scriptSource.code,
+        lastExecuted: scriptSource.lastExecuted,
+        version: scriptSource.version,
+        args: [argument],
+        realtime: false,
+      }).finally(() => {
+        this.homey.app.updateScript({
+          id: scriptSource.id,
+          lastExecuted: new Date(),
+        }).catch(this.error);
+      });
+    })
+    .registerArgumentAutocompleteListener('script', query => this.homey.app.onFlowGetScriptAutocomplete(query));
+  }
+}
+
+module.exports = { RunWithArgAction };
diff --git a/lib/flow/conditions/RunCodeCondition.js b/lib/flow/conditions/RunCodeCondition.js
new file mode 100644
index 0000000..307fa56
--- /dev/null
+++ b/lib/flow/conditions/RunCodeCondition.js
@@ -0,0 +1,41 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeCondition extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow.getConditionCard('runCode').registerRunListener(async ({ code }, state) => {
+      return Boolean(
+        await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 1,
+        }),
+      );
+    });
+
+    this.homey.flow.getConditionCard('runCode_v2').registerRunListener(async ({ code }, state) => {
+      return Boolean(
+        await this.homey.app.runScript({
+          id: '__temporary__',
+          name: 'Test',
+          code,
+          args: [],
+          realtime: state.realtime != null ? state.realtime : false,
+          version: 2,
+        }),
+      );
+    });
+  }
+}
+
+module.exports = { RunCodeCondition };
diff --git a/lib/flow/conditions/RunCodeWithArgCondition.js b/lib/flow/conditions/RunCodeWithArgCondition.js
new file mode 100644
index 0000000..f3a6883
--- /dev/null
+++ b/lib/flow/conditions/RunCodeWithArgCondition.js
@@ -0,0 +1,45 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCodeWithArgCondition extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow
+      .getConditionCard('runCodeWithArg')
+      .registerRunListener(async ({ code, argument }, state) => {
+        return Boolean(
+          await this.homey.app.runScript({
+            id: '__temporary__',
+            name: 'Test',
+            code,
+            args: [argument],
+            realtime: state.realtime != null ? state.realtime : false,
+            version: 1,
+          }),
+        );
+      });
+
+    this.homey.flow
+      .getConditionCard('runCodeWithArg_v2')
+      .registerRunListener(async ({ code, argument }, state) => {
+        return Boolean(
+          await this.homey.app.runScript({
+            id: '__temporary__',
+            name: 'Test',
+            code,
+            args: [argument],
+            realtime: state.realtime != null ? state.realtime : false,
+            version: 2,
+          }),
+        );
+      });
+  }
+}
+
+module.exports = { RunCodeWithArgCondition };
diff --git a/lib/flow/conditions/RunCondition.js b/lib/flow/conditions/RunCondition.js
new file mode 100644
index 0000000..9037717
--- /dev/null
+++ b/lib/flow/conditions/RunCondition.js
@@ -0,0 +1,35 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunCondition extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow.getConditionCard('run')
+      .registerRunListener(async ({ script }) => {
+        const scriptSource = await this.homey.app.getScript({ id: script.id });
+
+        return this.homey.app.runScript({
+          id: scriptSource.id,
+          name: scriptSource.name,
+          code: scriptSource.code,
+          lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
+          realtime: false,
+        }).finally(() => {
+          this.homey.app.updateScript({
+            id: scriptSource.id,
+            lastExecuted: new Date(),
+          }).catch(this.error);
+        });
+      })
+      .registerArgumentAutocompleteListener('script', query => this.homey.app.onFlowGetScriptAutocomplete(query));
+  }
+}
+
+module.exports = { RunCondition };
diff --git a/lib/flow/conditions/RunWithArgCondition.js b/lib/flow/conditions/RunWithArgCondition.js
new file mode 100644
index 0000000..c0d580c
--- /dev/null
+++ b/lib/flow/conditions/RunWithArgCondition.js
@@ -0,0 +1,36 @@
+'use strict';
+
+const { Base } = require('../../Base');
+
+class RunWithArgCondition extends Base {
+  /**
+   * @param {Object} options
+   * @param {import('@types/homey/lib/Homey')} options.homey
+   */
+  constructor({ homey }) {
+    super({ homey });
+
+    this.homey.flow.getConditionCard('runWithArg')
+      .registerRunListener(async ({ script, argument }) => {
+        const scriptSource = await this.homey.app.getScript({ id: script.id });
+
+        return this.homey.app.runScript({
+          id: scriptSource.id,
+          name: scriptSource.name,
+          code: scriptSource.code,
+          lastExecuted: scriptSource.lastExecuted,
+          version: scriptSource.version,
+          args: [argument],
+          realtime: false,
+        }).finally(() => {
+          this.homey.app.updateScript({
+            id: scriptSource.id,
+            lastExecuted: new Date(),
+          }).catch(this.error);
+        });
+      })
+      .registerArgumentAutocompleteListener('script', query => this.homey.app.onFlowGetScriptAutocomplete(query));
+  }
+}
+
+module.exports = { RunWithArgCondition };
diff --git a/package-lock.json b/package-lock.json
index 7f3131b..232cb51 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16,12 +16,14 @@
         "uuid": "^8.3.2"
       },
       "devDependencies": {
+        "@types/homey": "npm:homey-apps-sdk-v3-types@^0.3.5",
         "concurrently": "^7.2.2",
-        "eslint": "^8.18.0",
-        "eslint-config-athom": "^3.0.1",
+        "eslint": "^8.57.0",
+        "eslint-config-prettier": "^9.1.0",
         "homey-jsdoc-template": "github:athombv/homey-jsdoc-template#1.5.1",
         "jsdoc": "^3.6.10",
         "jsdoc-ts-utils": "^3.0.0",
+        "prettier": "^3.2.5",
         "serve": "^13.0.2",
         "watch": "^1.0.2"
       },
@@ -29,6 +31,15 @@
         "node": ">=16"
       }
     },
+    "node_modules/@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/@babel/parser": {
       "version": "7.18.5",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz",
@@ -41,16 +52,40 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+      }
+    },
+    "node_modules/@eslint-community/regexpp": {
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+      "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
-      "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
       "dev": true,
       "dependencies": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.3.2",
-        "globals": "^13.15.0",
+        "espree": "^9.6.0",
+        "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
         "js-yaml": "^4.1.0",
@@ -59,6 +94,9 @@
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/@eslint/eslintrc/node_modules/debug": {
@@ -84,15 +122,24 @@
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
       "dev": true
     },
+    "node_modules/@eslint/js": {
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+      "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.9.5",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
-      "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+      "version": "0.11.14",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+      "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
       "dev": true,
       "dependencies": {
-        "@humanwhocodes/object-schema": "^1.2.1",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "@humanwhocodes/object-schema": "^2.0.2",
+        "debug": "^4.3.1",
+        "minimatch": "^3.0.5"
       },
       "engines": {
         "node": ">=10.10.0"
@@ -121,10 +168,23 @@
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
       "dev": true
     },
+    "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==",
+      "dev": true,
+      "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",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
       "dev": true
     },
     "node_modules/@nodelib/fs.scandir": {
@@ -162,18 +222,22 @@
         "node": ">= 8"
       }
     },
+    "node_modules/@types/homey": {
+      "name": "homey-apps-sdk-v3-types",
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/homey-apps-sdk-v3-types/-/homey-apps-sdk-v3-types-0.3.5.tgz",
+      "integrity": "sha512-AH7UPiPILITBmjDSAnupLp2kaBO9GuAj5y0hk9tLC2mO0AuOQuRYnbXIxrHOG3kium8m99FnS3BUHg0aY/SNCg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^14.14.20"
+      }
+    },
     "node_modules/@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==",
       "dev": true
     },
-    "node_modules/@types/json5": {
-      "version": "0.0.29",
-      "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
-      "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
-      "dev": true
-    },
     "node_modules/@types/linkify-it": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
@@ -196,263 +260,18 @@
       "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
       "dev": true
     },
-    "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==",
-      "dev": true,
-      "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"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "@typescript-eslint/parser": "^4.0.0",
-        "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/eslint-plugin/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==",
-      "dev": true
-    },
-    "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==",
-      "dev": true,
-      "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"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependencies": {
-        "eslint": "*"
-      }
-    },
-    "node_modules/@typescript-eslint/experimental-utils/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==",
-      "dev": true,
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@typescript-eslint/experimental-utils/node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "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==",
-      "dev": true,
-      "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"
-      },
-      "peerDependencies": {
-        "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/parser/node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/parser/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/@types/node": {
+      "version": "14.18.63",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
+      "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
       "dev": true
     },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/types": "4.33.0",
-        "@typescript-eslint/visitor-keys": "4.33.0"
-      },
-      "engines": {
-        "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "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==",
-      "dev": true,
-      "engines": {
-        "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "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==",
-      "dev": true,
-      "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"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "2.1.2"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@typescript-eslint/typescript-estree/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/@ungap/structured-clone": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
       "dev": true
     },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "@typescript-eslint/types": "4.33.0",
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "engines": {
-        "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/typescript-eslint"
-      }
-    },
-    "node_modules/@typescript-eslint/visitor-keys/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/@webassemblyjs/ast": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -680,9 +499,9 @@
       }
     },
     "node_modules/acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.11.3",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+      "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -855,34 +674,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/array-includes": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz",
-      "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.4",
-        "es-abstract": "^1.19.5",
-        "get-intrinsic": "^1.1.1",
-        "is-string": "^1.0.7"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/array-union": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -893,24 +684,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/array.prototype.flat": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz",
-      "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.19.2",
-        "es-shim-unscopables": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/arraybuffer.slice": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
@@ -1214,6 +987,8 @@
       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "fill-range": "^7.0.1"
       },
@@ -1443,19 +1218,6 @@
         "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",
-      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -1797,12 +1559,6 @@
         "node": "^12.20.0 || ^14.13.0 || >=16.0.0"
       }
     },
-    "node_modules/confusing-browser-globals": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
-      "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
-      "dev": true
-    },
     "node_modules/console-browserify": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
@@ -2044,28 +1800,12 @@
       "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
-    "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==",
+    "node_modules/define-property": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
       "dev": true,
-      "dependencies": {
-        "has-property-descriptors": "^1.0.0",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/define-property": {
-      "version": "0.2.5",
-      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-      "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
-      "dev": true,
-      "peer": true,
+      "peer": true,
       "dependencies": {
         "is-descriptor": "^0.1.0"
       },
@@ -2111,18 +1851,6 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/dir-glob": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-      "dev": true,
-      "dependencies": {
-        "path-type": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/doctrine": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -2293,69 +2021,6 @@
         "errno": "cli.js"
       }
     },
-    "node_modules/es-abstract": {
-      "version": "1.20.1",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz",
-      "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "function.prototype.name": "^1.1.5",
-        "get-intrinsic": "^1.1.1",
-        "get-symbol-description": "^1.0.0",
-        "has": "^1.0.3",
-        "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.2",
-        "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.2",
-        "is-string": "^1.0.7",
-        "is-weakref": "^1.0.2",
-        "object-inspect": "^1.12.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.2",
-        "regexp.prototype.flags": "^1.4.3",
-        "string.prototype.trimend": "^1.0.5",
-        "string.prototype.trimstart": "^1.0.5",
-        "unbox-primitive": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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==",
-      "dev": true,
-      "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",
-      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
-      "dev": true,
-      "dependencies": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -2375,46 +2040,49 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.18.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz",
-      "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==",
-      "dev": true,
-      "dependencies": {
-        "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.9.2",
-        "ajv": "^6.10.0",
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+      "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.57.0",
+        "@humanwhocodes/config-array": "^0.11.14",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "@ungap/structured-clone": "^1.2.0",
+        "ajv": "^6.12.4",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
         "debug": "^4.3.2",
         "doctrine": "^3.0.0",
         "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.1.1",
-        "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
-        "esquery": "^1.4.0",
+        "eslint-scope": "^7.2.2",
+        "eslint-visitor-keys": "^3.4.3",
+        "espree": "^9.6.1",
+        "esquery": "^1.4.2",
         "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": "^6.0.1",
-        "globals": "^13.15.0",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
         "ignore": "^5.2.0",
-        "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
         "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
         "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
         "lodash.merge": "^4.6.2",
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
-        "regexpp": "^3.2.0",
+        "optionator": "^0.9.3",
         "strip-ansi": "^6.0.1",
-        "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "bin": {
         "eslint": "bin/eslint.js"
@@ -2426,442 +2094,165 @@
         "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/eslint-config-airbnb-base": {
-      "version": "14.2.1",
-      "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz",
-      "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==",
-      "dev": true,
-      "dependencies": {
-        "confusing-browser-globals": "^1.0.10",
-        "object.assign": "^4.1.2",
-        "object.entries": "^1.1.2"
-      },
-      "engines": {
-        "node": ">= 6"
-      },
-      "peerDependencies": {
-        "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
-        "eslint-plugin-import": "^2.22.1"
-      }
-    },
-    "node_modules/eslint-config-athom": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/eslint-config-athom/-/eslint-config-athom-3.0.1.tgz",
-      "integrity": "sha512-9r+8XBIgHjTdJCTMcOIzBN5nSYzQqmzLgXpxv+TfGl/NoGZwJq26POyyGWJmHf89fBGB5N6lnuBAt1BuGyNFGA==",
+    "node_modules/eslint-config-prettier": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
+      "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
       "dev": true,
-      "dependencies": {
-        "@typescript-eslint/eslint-plugin": "^4.31.1",
-        "@typescript-eslint/parser": "^4.31.1",
-        "eslint-config-airbnb-base": "^14.2.1",
-        "eslint-plugin-homey-app": "^1.0.2",
-        "eslint-plugin-import": "^2.24.2",
-        "eslint-plugin-mocha": "^6.3.0",
-        "eslint-plugin-node": "^11.1.0",
-        "typescript": "^4.4.3"
-      },
-      "engines": {
-        "node": ">=12.0.0"
+      "bin": {
+        "eslint-config-prettier": "bin/cli.js"
       },
       "peerDependencies": {
-        "eslint": ">=7.5.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",
-      "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
-      "dev": true,
-      "dependencies": {
-        "debug": "^3.2.7",
-        "resolve": "^1.20.0"
-      }
-    },
-    "node_modules/eslint-import-resolver-node/node_modules/debug": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-      "dev": true,
-      "dependencies": {
-        "ms": "^2.1.1"
-      }
-    },
-    "node_modules/eslint-import-resolver-node/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/eslint-module-utils": {
-      "version": "2.7.3",
-      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
-      "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
-      "dev": true,
-      "dependencies": {
-        "debug": "^3.2.7",
-        "find-up": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/eslint-module-utils/node_modules/debug": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-      "dev": true,
-      "dependencies": {
-        "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": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
-      "dev": true,
-      "dependencies": {
-        "locate-path": "^2.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": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
-      "dev": true,
-      "dependencies": {
-        "p-locate": "^2.0.0",
-        "path-exists": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/eslint-module-utils/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/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==",
-      "dev": true,
-      "dependencies": {
-        "p-try": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "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": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
-      "dev": true,
-      "dependencies": {
-        "p-limit": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=4"
+        "eslint": ">=7.0.0"
       }
     },
-    "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": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "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-scope": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
       "dev": true,
       "dependencies": {
-        "eslint-utils": "^2.0.0",
-        "regexpp": "^3.0.0"
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
       },
       "engines": {
-        "node": ">=8.10.0"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      },
-      "peerDependencies": {
-        "eslint": ">=4.19.1"
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "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==",
+    "node_modules/eslint-visitor-keys": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
       "dev": true,
-      "dependencies": {
-        "eslint-visitor-keys": "^1.1.0"
-      },
       "engines": {
-        "node": ">=6"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
-    "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-homey-app": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-homey-app/-/eslint-plugin-homey-app-1.0.2.tgz",
-      "integrity": "sha512-uO09MpI0GaRfxWd8jKf6ei71zCCx3C4/8m1vm/GqYv1y/TEi8i2GdIlBCqyN67IXd4fwT+BNd+BoGxKh+8WC8A==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "peerDependencies": {
-        "eslint": "^7.32.0"
-      }
-    },
-    "node_modules/eslint-plugin-import": {
-      "version": "2.26.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
-      "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==",
-      "dev": true,
-      "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.3",
-        "has": "^1.0.3",
-        "is-core-module": "^2.8.1",
-        "is-glob": "^4.0.3",
-        "minimatch": "^3.1.2",
-        "object.values": "^1.1.5",
-        "resolve": "^1.22.0",
-        "tsconfig-paths": "^3.14.1"
-      },
-      "engines": {
-        "node": ">=4"
-      },
-      "peerDependencies": {
-        "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/eslint-plugin-import/node_modules/doctrine": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+    "node_modules/eslint/node_modules/cross-spawn": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
       "dependencies": {
-        "esutils": "^2.0.2"
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">= 8"
       }
     },
-    "node_modules/eslint-plugin-mocha": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz",
-      "integrity": "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg==",
+    "node_modules/eslint/node_modules/debug": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
-        "eslint-utils": "^2.0.0",
-        "ramda": "^0.27.0"
+        "ms": "2.1.2"
       },
       "engines": {
-        "node": ">=8.0.0"
+        "node": ">=6.0"
       },
-      "peerDependencies": {
-        "eslint": ">= 4.0.0"
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
       }
     },
-    "node_modules/eslint-plugin-mocha/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/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
       "dev": true,
-      "dependencies": {
-        "eslint-visitor-keys": "^1.1.0"
-      },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
-    "node_modules/eslint-plugin-mocha/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"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/eslint-plugin-node": {
-      "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
-      "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
+    "node_modules/eslint/node_modules/find-up": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
       "dev": true,
       "dependencies": {
-        "eslint-plugin-es": "^3.0.0",
-        "eslint-utils": "^2.0.0",
-        "ignore": "^5.1.1",
-        "minimatch": "^3.0.4",
-        "resolve": "^1.10.1",
-        "semver": "^6.1.0"
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
       },
       "engines": {
-        "node": ">=8.10.0"
+        "node": ">=10"
       },
-      "peerDependencies": {
-        "eslint": ">=5.16.0"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "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==",
+    "node_modules/eslint/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==",
       "dev": true,
       "dependencies": {
-        "eslint-visitor-keys": "^1.1.0"
+        "p-locate": "^5.0.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
-    "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": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
+    "node_modules/eslint/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==",
+      "dev": true
     },
-    "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/eslint/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==",
       "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"
+        "yocto-queue": "^0.1.0"
       },
-      "peerDependencies": {
-        "eslint": ">=5"
-      }
-    },
-    "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==",
-      "dev": true,
       "engines": {
         "node": ">=10"
-      }
-    },
-    "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==",
-      "dev": true,
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/eslint/node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
       },
-      "engines": {
-        "node": ">= 8"
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/eslint/node_modules/debug": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+    "node_modules/eslint/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==",
       "dev": true,
       "dependencies": {
-        "ms": "2.1.2"
+        "p-limit": "^3.0.2"
       },
       "engines": {
-        "node": ">=6.0"
+        "node": ">=10"
       },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/eslint/node_modules/escape-string-regexp": {
+    "node_modules/eslint/node_modules/path-exists": {
       "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
       "dev": true,
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=8"
       }
     },
-    "node_modules/eslint/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==",
-      "dev": true
-    },
     "node_modules/eslint/node_modules/path-key": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -2908,23 +2299,26 @@
       }
     },
     "node_modules/espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.6.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
       "dev": true,
       "dependencies": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
+        "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
       "dependencies": {
         "estraverse": "^5.1.0"
@@ -3120,47 +2514,19 @@
     "node_modules/extglob/node_modules/kind-of": {
       "version": "6.0.3",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
-      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true
-    },
-    "node_modules/fast-glob": {
-      "version": "3.2.11",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
-      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
-      "dev": true,
-      "dependencies": {
-        "@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"
-      },
-      "engines": {
-        "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==",
-      "dev": true,
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true,
+      "peer": true,
       "engines": {
-        "node": ">= 6"
+        "node": ">=0.10.0"
       }
     },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
     "node_modules/fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -3189,9 +2555,9 @@
       "dev": true
     },
     "node_modules/fastq": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
-      "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
       "dev": true,
       "dependencies": {
         "reusify": "^1.0.4"
@@ -3228,6 +2594,8 @@
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "to-regex-range": "^5.0.1"
       },
@@ -3384,45 +2752,6 @@
         "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
       }
     },
-    "node_modules/function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "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==",
-      "dev": true,
-      "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/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": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
-      "dev": true
-    },
-    "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==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -3432,20 +2761,6 @@
         "node": "6.* || 8.* || >= 10.*"
       }
     },
-    "node_modules/get-intrinsic": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
-      "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/get-stream": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -3458,22 +2773,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/get-symbol-description": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
-      "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "get-intrinsic": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "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",
@@ -3517,9 +2816,9 @@
       }
     },
     "node_modules/globals": {
-      "version": "13.15.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
-      "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
       "dev": true,
       "dependencies": {
         "type-fest": "^0.20.2"
@@ -3531,52 +2830,17 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/globby": {
-      "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
-      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
-      "dev": true,
-      "dependencies": {
-        "array-union": "^2.1.0",
-        "dir-glob": "^3.0.1",
-        "fast-glob": "^3.2.9",
-        "ignore": "^5.2.0",
-        "merge2": "^1.4.1",
-        "slash": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/graceful-fs": {
       "version": "4.2.10",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
-    "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/has-bigints": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
-      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
+    "node_modules/graphemer": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+      "dev": true
     },
     "node_modules/has-binary2": {
       "version": "1.0.3",
@@ -3605,45 +2869,6 @@
         "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==",
-      "dev": true,
-      "dependencies": {
-        "get-intrinsic": "^1.1.1"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-symbols": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
-      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/has-tostringtag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
-      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
-      "dev": true,
-      "dependencies": {
-        "has-symbols": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/has-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@@ -3858,9 +3083,9 @@
       "dev": true
     },
     "node_modules/ignore": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
       "dev": true,
       "engines": {
         "node": ">= 4"
@@ -3924,20 +3149,6 @@
       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
       "dev": true
     },
-    "node_modules/internal-slot": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
-      "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
-      "dev": true,
-      "dependencies": {
-        "get-intrinsic": "^1.1.0",
-        "has": "^1.0.3",
-        "side-channel": "^1.0.4"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/is-accessor-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -3964,18 +3175,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-bigint": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
-      "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
-      "dev": true,
-      "dependencies": {
-        "has-bigints": "^1.0.1"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-binary-path": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -3990,22 +3189,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/is-boolean-object": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
-      "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
-      "dev": true,
-      "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-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -4013,30 +3196,6 @@
       "dev": true,
       "peer": true
     },
-    "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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "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==",
-      "dev": true,
-      "dependencies": {
-        "has": "^1.0.3"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-data-descriptor": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@@ -4063,21 +3222,6 @@
         "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",
-      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
-      "dev": true,
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
@@ -4158,40 +3302,24 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-negative-zero": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
-      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=0.12.0"
       }
     },
-    "node_modules/is-number-object": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
-      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+    "node_modules/is-path-inside": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
       "dev": true,
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
       "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
+        "node": ">=8"
       }
     },
     "node_modules/is-plain-object": {
@@ -4207,34 +3335,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-regex": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
-      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
-      "dev": true,
-      "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-shared-array-buffer": {
-      "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==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
@@ -4244,48 +3344,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-string": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
-      "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
-      "dev": true,
-      "dependencies": {
-        "has-tostringtag": "^1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-symbol": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
-      "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
-      "dev": true,
-      "dependencies": {
-        "has-symbols": "^1.0.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/is-weakref": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
-      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2"
-      },
-      "funding": {
-        "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",
@@ -4660,28 +3718,6 @@
       "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
       "dev": true
     },
-    "node_modules/merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dev": true,
-      "dependencies": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
     "node_modules/miller-rabin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@@ -5115,24 +4151,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/object-inspect": {
-      "version": "1.12.2",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
-      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
-      "dev": true,
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/object-visit": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -5146,38 +4164,6 @@
         "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==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3",
-        "has-symbols": "^1.0.1",
-        "object-keys": "^1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/object.entries": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz",
-      "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.19.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      }
-    },
     "node_modules/object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -5191,23 +4177,6 @@
         "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",
-      "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.19.1"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/on-headers": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
@@ -5227,17 +4196,17 @@
       }
     },
     "node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
       "dev": true,
       "dependencies": {
+        "@aashutoshrathi/word-wrap": "^1.2.3",
         "deep-is": "^0.1.3",
         "fast-levenshtein": "^2.0.6",
         "levn": "^0.4.1",
         "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
+        "type-check": "^0.4.0"
       },
       "engines": {
         "node": ">= 0.8.0"
@@ -5407,27 +4376,12 @@
         "node": ">=4"
       }
     },
-    "node_modules/path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-      "dev": true
-    },
     "node_modules/path-to-regexp": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
       "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
       "dev": true
     },
-    "node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/pbkdf2": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
@@ -5456,6 +4410,8 @@
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "engines": {
         "node": ">=8.6"
       },
@@ -5602,7 +4558,22 @@
       "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
       "dev": true,
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin/prettier.cjs"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
       }
     },
     "node_modules/process": {
@@ -5736,12 +4707,6 @@
         }
       ]
     },
-    "node_modules/ramda": {
-      "version": "0.27.2",
-      "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
-      "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
-      "dev": true
-    },
     "node_modules/randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -5866,35 +4831,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/regexp.prototype.flags": {
-      "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==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "functions-have-names": "^1.2.2"
-      },
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
     "node_modules/registry-auth-token": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
@@ -5963,23 +4899,6 @@
         "lodash": "^4.17.14"
       }
     },
-    "node_modules/resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
-      "dev": true,
-      "dependencies": {
-        "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"
-      }
-    },
     "node_modules/resolve-from": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -6347,35 +5266,12 @@
       "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
       "dev": true
     },
-    "node_modules/side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/signal-exit": {
       "version": "3.0.7",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
       "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
-    "node_modules/slash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/snapdragon": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -6751,34 +5647,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/string.prototype.trimend": {
-      "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==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "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.5",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
-      "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.4",
-        "es-abstract": "^1.19.5"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -6791,15 +5659,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/strip-bom": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/strip-eof": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
@@ -6836,18 +5695,6 @@
         "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
-    "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==",
-      "dev": true,
-      "engines": {
-        "node": ">= 0.4"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/taffydb": {
       "version": "2.7.3",
       "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.7.3.tgz",
@@ -7019,6 +5866,8 @@
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "dependencies": {
         "is-number": "^7.0.0"
       },
@@ -7132,57 +5981,12 @@
         "tree-kill": "cli.js"
       }
     },
-    "node_modules/tsconfig-paths": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
-      "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/json5": "^0.0.29",
-        "json5": "^1.0.1",
-        "minimist": "^1.2.6",
-        "strip-bom": "^3.0.0"
-      }
-    },
-    "node_modules/tsconfig-paths/node_modules/json5": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
-      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
-      "dev": true,
-      "dependencies": {
-        "minimist": "^1.2.0"
-      },
-      "bin": {
-        "json5": "lib/cli.js"
-      }
-    },
     "node_modules/tslib": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
       "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
       "dev": true
     },
-    "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,
-      "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/tsutils/node_modules/tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "dev": true
-    },
     "node_modules/tty-browserify": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -7220,19 +6024,6 @@
       "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
       "dev": true
     },
-    "node_modules/typescript": {
-      "version": "4.7.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
-      "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
-      "dev": true,
-      "bin": {
-        "tsc": "bin/tsc",
-        "tsserver": "bin/tsserver"
-      },
-      "engines": {
-        "node": ">=4.2.0"
-      }
-    },
     "node_modules/uc.micro": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
@@ -7288,21 +6079,6 @@
         "node": ">= 4"
       }
     },
-    "node_modules/unbox-primitive": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
-      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
-      "dev": true,
-      "dependencies": {
-        "call-bind": "^1.0.2",
-        "has-bigints": "^1.0.2",
-        "has-symbols": "^1.0.3",
-        "which-boxed-primitive": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
     "node_modules/underscore": {
       "version": "1.13.4",
       "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz",
@@ -7493,12 +6269,6 @@
         "uuid": "dist/bin/uuid"
       }
     },
-    "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==",
-      "dev": true
-    },
     "node_modules/vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -8297,22 +7067,6 @@
         "which": "bin/which"
       }
     },
-    "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==",
-      "dev": true,
-      "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"
-      }
-    },
     "node_modules/widest-line": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
@@ -8325,15 +7079,6 @@
         "node": ">=8"
       }
     },
-    "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==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/worker-farm": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
@@ -8461,25 +7206,58 @@
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
       "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg=="
+    },
+    "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==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     }
   },
   "dependencies": {
+    "@aashutoshrathi/word-wrap": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+      "dev": true
+    },
     "@babel/parser": {
       "version": "7.18.5",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz",
       "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==",
       "dev": true
     },
+    "@eslint-community/eslint-utils": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+      "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^3.3.0"
+      }
+    },
+    "@eslint-community/regexpp": {
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
+      "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
+      "dev": true
+    },
     "@eslint/eslintrc": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
-      "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.3.2",
-        "globals": "^13.15.0",
+        "espree": "^9.6.0",
+        "globals": "^13.19.0",
         "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
         "js-yaml": "^4.1.0",
@@ -8504,15 +7282,21 @@
         }
       }
     },
+    "@eslint/js": {
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+      "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+      "dev": true
+    },
     "@humanwhocodes/config-array": {
-      "version": "0.9.5",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
-      "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+      "version": "0.11.14",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+      "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
       "dev": true,
       "requires": {
-        "@humanwhocodes/object-schema": "^1.2.1",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.4"
+        "@humanwhocodes/object-schema": "^2.0.2",
+        "debug": "^4.3.1",
+        "minimatch": "^3.0.5"
       },
       "dependencies": {
         "debug": {
@@ -8532,10 +7316,16 @@
         }
       }
     },
+    "@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true
+    },
     "@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==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
       "dev": true
     },
     "@nodelib/fs.scandir": {
@@ -8555,209 +7345,64 @@
       "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==",
-      "dev": true,
-      "requires": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      }
-    },
-    "@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==",
-      "dev": true
-    },
-    "@types/json5": {
-      "version": "0.0.29",
-      "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
-      "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
-      "dev": true
-    },
-    "@types/linkify-it": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
-      "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
-      "dev": true
-    },
-    "@types/markdown-it": {
-      "version": "12.2.3",
-      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
-      "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
-      "dev": true,
-      "requires": {
-        "@types/linkify-it": "*",
-        "@types/mdurl": "*"
-      }
-    },
-    "@types/mdurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
-      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
-      "dev": true
-    },
-    "@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==",
-      "dev": true,
-      "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"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "4.3.4",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-          "dev": true,
-          "requires": {
-            "ms": "2.1.2"
-          }
-        },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
-        }
-      }
-    },
-    "@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==",
-      "dev": true,
-      "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-scope": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-          "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
-          "dev": true,
-          "requires": {
-            "esrecurse": "^4.3.0",
-            "estraverse": "^4.1.1"
-          }
-        },
-        "estraverse": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-          "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-          "dev": true
-        }
-      }
-    },
-    "@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==",
-      "dev": true,
-      "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"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "4.3.4",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-          "dev": true,
-          "requires": {
-            "ms": "2.1.2"
-          }
-        },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
-        }
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
       }
     },
-    "@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==",
+    "@types/homey": {
+      "version": "npm:homey-apps-sdk-v3-types@0.3.5",
+      "resolved": "https://registry.npmjs.org/homey-apps-sdk-v3-types/-/homey-apps-sdk-v3-types-0.3.5.tgz",
+      "integrity": "sha512-AH7UPiPILITBmjDSAnupLp2kaBO9GuAj5y0hk9tLC2mO0AuOQuRYnbXIxrHOG3kium8m99FnS3BUHg0aY/SNCg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.33.0",
-        "@typescript-eslint/visitor-keys": "4.33.0"
+        "@types/node": "^14.14.20"
       }
     },
-    "@typescript-eslint/types": {
-      "version": "4.33.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz",
-      "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==",
+    "@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==",
       "dev": true
     },
-    "@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==",
-      "dev": true,
-      "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"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "4.3.4",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-          "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-          "dev": true,
-          "requires": {
-            "ms": "2.1.2"
-          }
-        },
-        "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-          "dev": true
-        }
-      }
+    "@types/linkify-it": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
+      "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==",
+      "dev": true
     },
-    "@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==",
+    "@types/markdown-it": {
+      "version": "12.2.3",
+      "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
+      "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "4.33.0",
-        "eslint-visitor-keys": "^2.0.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==",
-          "dev": true
-        }
+        "@types/linkify-it": "*",
+        "@types/mdurl": "*"
       }
     },
+    "@types/mdurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
+      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "14.18.63",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
+      "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==",
+      "dev": true
+    },
+    "@ungap/structured-clone": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+      "dev": true
+    },
     "@webassemblyjs/ast": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -8982,9 +7627,9 @@
       }
     },
     "acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.11.3",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
+      "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
       "dev": true
     },
     "acorn-jsx": {
@@ -9106,25 +7751,6 @@
       "dev": true,
       "peer": true
     },
-    "array-includes": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz",
-      "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.4",
-        "es-abstract": "^1.19.5",
-        "get-intrinsic": "^1.1.1",
-        "is-string": "^1.0.7"
-      }
-    },
-    "array-union": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "dev": true
-    },
     "array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -9132,18 +7758,6 @@
       "dev": true,
       "peer": true
     },
-    "array.prototype.flat": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz",
-      "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.19.2",
-        "es-shim-unscopables": "^1.0.0"
-      }
-    },
     "arraybuffer.slice": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
@@ -9397,6 +8011,8 @@
       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "fill-range": "^7.0.1"
       }
@@ -9604,16 +8220,6 @@
         "unset-value": "^1.0.0"
       }
     },
-    "call-bind": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
-      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1",
-        "get-intrinsic": "^1.0.2"
-      }
-    },
     "callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -9884,12 +8490,6 @@
         "yargs": "^17.3.1"
       }
     },
-    "confusing-browser-globals": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
-      "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
-      "dev": true
-    },
     "console-browserify": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
@@ -10091,16 +8691,6 @@
       "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
-    "define-properties": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
-      "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
-      "dev": true,
-      "requires": {
-        "has-property-descriptors": "^1.0.0",
-        "object-keys": "^1.1.1"
-      }
-    },
     "define-property": {
       "version": "0.2.5",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
@@ -10148,15 +8738,6 @@
         }
       }
     },
-    "dir-glob": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-      "dev": true,
-      "requires": {
-        "path-type": "^4.0.0"
-      }
-    },
     "doctrine": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -10311,57 +8892,6 @@
         "prr": "~1.0.1"
       }
     },
-    "es-abstract": {
-      "version": "1.20.1",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz",
-      "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "es-to-primitive": "^1.2.1",
-        "function-bind": "^1.1.1",
-        "function.prototype.name": "^1.1.5",
-        "get-intrinsic": "^1.1.1",
-        "get-symbol-description": "^1.0.0",
-        "has": "^1.0.3",
-        "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.2",
-        "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.2",
-        "is-string": "^1.0.7",
-        "is-weakref": "^1.0.2",
-        "object-inspect": "^1.12.0",
-        "object-keys": "^1.1.1",
-        "object.assign": "^4.1.2",
-        "regexp.prototype.flags": "^1.4.3",
-        "string.prototype.trimend": "^1.0.5",
-        "string.prototype.trimstart": "^1.0.5",
-        "unbox-primitive": "^1.0.2"
-      }
-    },
-    "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==",
-      "dev": true,
-      "requires": {
-        "has": "^1.0.3"
-      }
-    },
-    "es-to-primitive": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
-      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
-      "dev": true,
-      "requires": {
-        "is-callable": "^1.1.4",
-        "is-date-object": "^1.0.1",
-        "is-symbol": "^1.0.2"
-      }
-    },
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -10375,46 +8905,49 @@
       "dev": true
     },
     "eslint": {
-      "version": "8.18.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.18.0.tgz",
-      "integrity": "sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA==",
-      "dev": true,
-      "requires": {
-        "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.9.2",
-        "ajv": "^6.10.0",
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+      "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+      "dev": true,
+      "requires": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.57.0",
+        "@humanwhocodes/config-array": "^0.11.14",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "@ungap/structured-clone": "^1.2.0",
+        "ajv": "^6.12.4",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
         "debug": "^4.3.2",
         "doctrine": "^3.0.0",
         "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.1.1",
-        "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
-        "esquery": "^1.4.0",
+        "eslint-scope": "^7.2.2",
+        "eslint-visitor-keys": "^3.4.3",
+        "espree": "^9.6.1",
+        "esquery": "^1.4.2",
         "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": "^6.0.1",
-        "globals": "^13.15.0",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
         "ignore": "^5.2.0",
-        "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
         "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
         "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
         "lodash.merge": "^4.6.2",
         "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
-        "regexpp": "^3.2.0",
+        "optionator": "^0.9.3",
         "strip-ansi": "^6.0.1",
-        "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "dependencies": {
         "cross-spawn": {
@@ -10443,12 +8976,55 @@
           "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
           "dev": true
         },
+        "find-up": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+          "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^6.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "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==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^5.0.0"
+          }
+        },
         "ms": {
           "version": "2.1.2",
           "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
           "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
           "dev": true
         },
+        "p-limit": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+          "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+          "dev": true,
+          "requires": {
+            "yocto-queue": "^0.1.0"
+          }
+        },
+        "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==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^3.0.2"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
         "path-key": {
           "version": "3.1.1",
           "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -10481,308 +9057,44 @@
         }
       }
     },
-    "eslint-config-airbnb-base": {
-      "version": "14.2.1",
-      "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz",
-      "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==",
-      "dev": true,
-      "requires": {
-        "confusing-browser-globals": "^1.0.10",
-        "object.assign": "^4.1.2",
-        "object.entries": "^1.1.2"
-      }
-    },
-    "eslint-config-athom": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/eslint-config-athom/-/eslint-config-athom-3.0.1.tgz",
-      "integrity": "sha512-9r+8XBIgHjTdJCTMcOIzBN5nSYzQqmzLgXpxv+TfGl/NoGZwJq26POyyGWJmHf89fBGB5N6lnuBAt1BuGyNFGA==",
-      "dev": true,
-      "requires": {
-        "@typescript-eslint/eslint-plugin": "^4.31.1",
-        "@typescript-eslint/parser": "^4.31.1",
-        "eslint-config-airbnb-base": "^14.2.1",
-        "eslint-plugin-homey-app": "^1.0.2",
-        "eslint-plugin-import": "^2.24.2",
-        "eslint-plugin-mocha": "^6.3.0",
-        "eslint-plugin-node": "^11.1.0",
-        "typescript": "^4.4.3"
-      }
-    },
-    "eslint-import-resolver-node": {
-      "version": "0.3.6",
-      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
-      "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
-      "dev": true,
-      "requires": {
-        "debug": "^3.2.7",
-        "resolve": "^1.20.0"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "3.2.7",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-          "dev": true,
-          "requires": {
-            "ms": "^2.1.1"
-          }
-        },
-        "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
-        }
-      }
-    },
-    "eslint-module-utils": {
-      "version": "2.7.3",
-      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
-      "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
-      "dev": true,
-      "requires": {
-        "debug": "^3.2.7",
-        "find-up": "^2.1.0"
-      },
-      "dependencies": {
-        "debug": {
-          "version": "3.2.7",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
-          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
-          "dev": true,
-          "requires": {
-            "ms": "^2.1.1"
-          }
-        },
-        "find-up": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-          "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
-          "dev": true,
-          "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": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
-          "dev": true,
-          "requires": {
-            "p-locate": "^2.0.0",
-            "path-exists": "^3.0.0"
-          }
-        },
-        "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
-        },
-        "p-limit": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
-          "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
-          "dev": true,
-          "requires": {
-            "p-try": "^1.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-          "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
-          "dev": true,
-          "requires": {
-            "p-limit": "^1.1.0"
-          }
-        },
-        "p-try": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-          "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
-          "dev": true
-        }
-      }
-    },
-    "eslint-plugin-es": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
-      "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
-      "dev": true,
-      "requires": {
-        "eslint-utils": "^2.0.0",
-        "regexpp": "^3.0.0"
-      },
-      "dependencies": {
-        "eslint-utils": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-          "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
-          "dev": true,
-          "requires": {
-            "eslint-visitor-keys": "^1.1.0"
-          }
-        },
-        "eslint-visitor-keys": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-          "dev": true
-        }
-      }
-    },
-    "eslint-plugin-homey-app": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-homey-app/-/eslint-plugin-homey-app-1.0.2.tgz",
-      "integrity": "sha512-uO09MpI0GaRfxWd8jKf6ei71zCCx3C4/8m1vm/GqYv1y/TEi8i2GdIlBCqyN67IXd4fwT+BNd+BoGxKh+8WC8A==",
+    "eslint-config-prettier": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
+      "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
       "dev": true,
       "requires": {}
     },
-    "eslint-plugin-import": {
-      "version": "2.26.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
-      "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==",
-      "dev": true,
-      "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.3",
-        "has": "^1.0.3",
-        "is-core-module": "^2.8.1",
-        "is-glob": "^4.0.3",
-        "minimatch": "^3.1.2",
-        "object.values": "^1.1.5",
-        "resolve": "^1.22.0",
-        "tsconfig-paths": "^3.14.1"
-      },
-      "dependencies": {
-        "doctrine": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
-          "dev": true,
-          "requires": {
-            "esutils": "^2.0.2"
-          }
-        }
-      }
-    },
-    "eslint-plugin-mocha": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz",
-      "integrity": "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg==",
-      "dev": true,
-      "requires": {
-        "eslint-utils": "^2.0.0",
-        "ramda": "^0.27.0"
-      },
-      "dependencies": {
-        "eslint-utils": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-          "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
-          "dev": true,
-          "requires": {
-            "eslint-visitor-keys": "^1.1.0"
-          }
-        },
-        "eslint-visitor-keys": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-          "dev": true
-        }
-      }
-    },
-    "eslint-plugin-node": {
-      "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
-      "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
-      "dev": true,
-      "requires": {
-        "eslint-plugin-es": "^3.0.0",
-        "eslint-utils": "^2.0.0",
-        "ignore": "^5.1.1",
-        "minimatch": "^3.0.4",
-        "resolve": "^1.10.1",
-        "semver": "^6.1.0"
-      },
-      "dependencies": {
-        "eslint-utils": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-          "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
-          "dev": true,
-          "requires": {
-            "eslint-visitor-keys": "^1.1.0"
-          }
-        },
-        "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",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "dev": true
-        }
-      }
-    },
     "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==",
-      "dev": true,
-      "requires": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      }
-    },
-    "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"
-      },
-      "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==",
-          "dev": true
-        }
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
       }
     },
     "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==",
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
       "dev": true
     },
     "espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.6.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
       "dev": true,
       "requires": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
+        "eslint-visitor-keys": "^3.4.1"
       }
     },
     "esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+      "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
       "requires": {
         "estraverse": "^5.1.0"
@@ -10951,30 +9263,6 @@
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "dev": true
     },
-    "fast-glob": {
-      "version": "3.2.11",
-      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
-      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
-      "dev": true,
-      "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==",
-          "dev": true,
-          "requires": {
-            "is-glob": "^4.0.1"
-          }
-        }
-      }
-    },
     "fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -11005,9 +9293,9 @@
       }
     },
     "fastq": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
-      "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
       "dev": true,
       "requires": {
         "reusify": "^1.0.4"
@@ -11041,6 +9329,8 @@
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "to-regex-range": "^5.0.1"
       }
@@ -11165,53 +9455,12 @@
       "optional": true,
       "peer": true
     },
-    "function-bind": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
-    },
-    "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==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.19.0",
-        "functions-have-names": "^1.2.2"
-      }
-    },
-    "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": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
-      "dev": true
-    },
-    "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==",
-      "dev": true
-    },
     "get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
       "dev": true
     },
-    "get-intrinsic": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
-      "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1",
-        "has": "^1.0.3",
-        "has-symbols": "^1.0.3"
-      }
-    },
     "get-stream": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -11221,16 +9470,6 @@
         "pump": "^3.0.0"
       }
     },
-    "get-symbol-description": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
-      "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "get-intrinsic": "^1.1.1"
-      }
-    },
     "get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -11262,47 +9501,24 @@
       }
     },
     "globals": {
-      "version": "13.15.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz",
-      "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==",
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
       "dev": true,
       "requires": {
         "type-fest": "^0.20.2"
       }
     },
-    "globby": {
-      "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
-      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
-      "dev": true,
-      "requires": {
-        "array-union": "^2.1.0",
-        "dir-glob": "^3.0.1",
-        "fast-glob": "^3.2.9",
-        "ignore": "^5.2.0",
-        "merge2": "^1.4.1",
-        "slash": "^3.0.0"
-      }
-    },
     "graceful-fs": {
       "version": "4.2.10",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
-    "has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
-      "requires": {
-        "function-bind": "^1.1.1"
-      }
-    },
-    "has-bigints": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
-      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+    "graphemer": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
       "dev": true
     },
     "has-binary2": {
@@ -11331,30 +9547,6 @@
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
       "dev": true
     },
-    "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==",
-      "dev": true,
-      "requires": {
-        "get-intrinsic": "^1.1.1"
-      }
-    },
-    "has-symbols": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
-      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
-      "dev": true
-    },
-    "has-tostringtag": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
-      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
-      "dev": true,
-      "requires": {
-        "has-symbols": "^1.0.2"
-      }
-    },
     "has-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@@ -11514,9 +9706,9 @@
       "dev": true
     },
     "ignore": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
       "dev": true
     },
     "import-fresh": {
@@ -11568,17 +9760,6 @@
       "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
       "dev": true
     },
-    "internal-slot": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
-      "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
-      "dev": true,
-      "requires": {
-        "get-intrinsic": "^1.1.0",
-        "has": "^1.0.3",
-        "side-channel": "^1.0.4"
-      }
-    },
     "is-accessor-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -11601,15 +9782,6 @@
         }
       }
     },
-    "is-bigint": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
-      "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
-      "dev": true,
-      "requires": {
-        "has-bigints": "^1.0.1"
-      }
-    },
     "is-binary-path": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -11621,16 +9793,6 @@
         "binary-extensions": "^2.0.0"
       }
     },
-    "is-boolean-object": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
-      "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "has-tostringtag": "^1.0.0"
-      }
-    },
     "is-buffer": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -11638,21 +9800,6 @@
       "dev": true,
       "peer": true
     },
-    "is-callable": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
-      "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
-      "dev": true
-    },
-    "is-core-module": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
-      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
-      "dev": true,
-      "requires": {
-        "has": "^1.0.3"
-      }
-    },
     "is-data-descriptor": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@@ -11675,15 +9822,6 @@
         }
       }
     },
-    "is-date-object": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
-      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
-      "dev": true,
-      "requires": {
-        "has-tostringtag": "^1.0.0"
-      }
-    },
     "is-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
@@ -11739,26 +9877,19 @@
         "is-extglob": "^2.1.1"
       }
     },
-    "is-negative-zero": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
-      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
-      "dev": true
-    },
     "is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true
-    },
-    "is-number-object": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
-      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
       "dev": true,
-      "requires": {
-        "has-tostringtag": "^1.0.0"
-      }
+      "optional": true,
+      "peer": true
+    },
+    "is-path-inside": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+      "dev": true
     },
     "is-plain-object": {
       "version": "2.0.4",
@@ -11770,58 +9901,12 @@
         "isobject": "^3.0.1"
       }
     },
-    "is-regex": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
-      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "has-tostringtag": "^1.0.0"
-      }
-    },
-    "is-shared-array-buffer": {
-      "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==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2"
-      }
-    },
     "is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
       "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
       "dev": true
     },
-    "is-string": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
-      "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
-      "dev": true,
-      "requires": {
-        "has-tostringtag": "^1.0.0"
-      }
-    },
-    "is-symbol": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
-      "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
-      "dev": true,
-      "requires": {
-        "has-symbols": "^1.0.2"
-      }
-    },
-    "is-weakref": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
-      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2"
-      }
-    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -12122,22 +10207,6 @@
       "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
       "dev": true
     },
-    "merge2": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
-      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true
-    },
-    "micromatch": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
-      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
-      "dev": true,
-      "requires": {
-        "braces": "^3.0.2",
-        "picomatch": "^2.3.1"
-      }
-    },
     "miller-rabin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@@ -12498,18 +10567,6 @@
         }
       }
     },
-    "object-inspect": {
-      "version": "1.12.2",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
-      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
-      "dev": true
-    },
-    "object-keys": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true
-    },
     "object-visit": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@@ -12520,29 +10577,6 @@
         "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==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.0",
-        "define-properties": "^1.1.3",
-        "has-symbols": "^1.0.1",
-        "object-keys": "^1.1.1"
-      }
-    },
-    "object.entries": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz",
-      "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "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",
@@ -12553,17 +10587,6 @@
         "isobject": "^3.0.1"
       }
     },
-    "object.values": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz",
-      "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "es-abstract": "^1.19.1"
-      }
-    },
     "on-headers": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
@@ -12580,17 +10603,17 @@
       }
     },
     "optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "version": "0.9.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
+      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
       "dev": true,
       "requires": {
+        "@aashutoshrathi/word-wrap": "^1.2.3",
         "deep-is": "^0.1.3",
         "fast-levenshtein": "^2.0.6",
         "levn": "^0.4.1",
         "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
+        "type-check": "^0.4.0"
       }
     },
     "os-browserify": {
@@ -12727,24 +10750,12 @@
       "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
       "dev": true
     },
-    "path-parse": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-      "dev": true
-    },
     "path-to-regexp": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
       "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
       "dev": true
     },
-    "path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true
-    },
     "pbkdf2": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
@@ -12769,7 +10780,9 @@
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true
+      "dev": true,
+      "optional": true,
+      "peer": true
     },
     "pify": {
       "version": "4.0.1",
@@ -12862,6 +10875,12 @@
       "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
       "dev": true
     },
+    "prettier": {
+      "version": "3.2.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
+      "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
+      "dev": true
+    },
     "process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -12970,12 +10989,6 @@
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
       "dev": true
     },
-    "ramda": {
-      "version": "0.27.2",
-      "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
-      "integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
-      "dev": true
-    },
     "randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -13083,23 +11096,6 @@
         }
       }
     },
-    "regexp.prototype.flags": {
-      "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==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3",
-        "functions-have-names": "^1.2.2"
-      }
-    },
-    "regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true
-    },
     "registry-auth-token": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
@@ -13156,17 +11152,6 @@
         "lodash": "^4.17.14"
       }
     },
-    "resolve": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
-      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
-      "dev": true,
-      "requires": {
-        "is-core-module": "^2.9.0",
-        "path-parse": "^1.0.7",
-        "supports-preserve-symlinks-flag": "^1.0.0"
-      }
-    },
     "resolve-from": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -13458,29 +11443,12 @@
       "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
       "dev": true
     },
-    "side-channel": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
-      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.0",
-        "get-intrinsic": "^1.0.2",
-        "object-inspect": "^1.9.0"
-      }
-    },
     "signal-exit": {
       "version": "3.0.7",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
       "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
-    "slash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "dev": true
-    },
     "snapdragon": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -13815,28 +11783,6 @@
         "strip-ansi": "^6.0.1"
       }
     },
-    "string.prototype.trimend": {
-      "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==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.4",
-        "es-abstract": "^1.19.5"
-      }
-    },
-    "string.prototype.trimstart": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
-      "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "define-properties": "^1.1.4",
-        "es-abstract": "^1.19.5"
-      }
-    },
     "strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -13846,12 +11792,6 @@
         "ansi-regex": "^5.0.1"
       }
     },
-    "strip-bom": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
-      "dev": true
-    },
     "strip-eof": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
@@ -13873,12 +11813,6 @@
         "has-flag": "^4.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==",
-      "dev": true
-    },
     "taffydb": {
       "version": "2.7.3",
       "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.7.3.tgz",
@@ -14097,6 +12031,8 @@
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
       "dev": true,
+      "optional": true,
+      "peer": true,
       "requires": {
         "is-number": "^7.0.0"
       }
@@ -14112,52 +12048,12 @@
       "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
       "dev": true
     },
-    "tsconfig-paths": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
-      "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
-      "dev": true,
-      "requires": {
-        "@types/json5": "^0.0.29",
-        "json5": "^1.0.1",
-        "minimist": "^1.2.6",
-        "strip-bom": "^3.0.0"
-      },
-      "dependencies": {
-        "json5": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
-          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.0"
-          }
-        }
-      }
-    },
     "tslib": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
       "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
       "dev": true
     },
-    "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"
-      },
-      "dependencies": {
-        "tslib": {
-          "version": "1.14.1",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-          "dev": true
-        }
-      }
-    },
     "tty-browserify": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -14186,12 +12082,6 @@
       "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
       "dev": true
     },
-    "typescript": {
-      "version": "4.7.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
-      "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
-      "dev": true
-    },
     "uc.micro": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
@@ -14234,18 +12124,6 @@
         }
       }
     },
-    "unbox-primitive": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
-      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
-      "dev": true,
-      "requires": {
-        "call-bind": "^1.0.2",
-        "has-bigints": "^1.0.2",
-        "has-symbols": "^1.0.3",
-        "which-boxed-primitive": "^1.0.2"
-      }
-    },
     "underscore": {
       "version": "1.13.4",
       "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz",
@@ -14418,12 +12296,6 @@
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
       "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
     },
-    "v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
-    },
     "vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -15076,19 +12948,6 @@
         "isexe": "^2.0.0"
       }
     },
-    "which-boxed-primitive": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
-      "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
-      "dev": true,
-      "requires": {
-        "is-bigint": "^1.0.1",
-        "is-boolean-object": "^1.1.0",
-        "is-number-object": "^1.0.4",
-        "is-string": "^1.0.5",
-        "is-symbol": "^1.0.3"
-      }
-    },
     "widest-line": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
@@ -15098,12 +12957,6 @@
         "string-width": "^4.0.0"
       }
     },
-    "word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
-      "dev": true
-    },
     "worker-farm": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
@@ -15198,6 +13051,12 @@
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
       "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg=="
+    },
+    "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==",
+      "dev": true
     }
   }
 }
diff --git a/package.json b/package.json
index 561e6f3..9c9afd3 100644
--- a/package.json
+++ b/package.json
@@ -39,12 +39,14 @@
     "uuid": "^8.3.2"
   },
   "devDependencies": {
+    "@types/homey": "npm:homey-apps-sdk-v3-types@^0.3.5",
     "concurrently": "^7.2.2",
-    "eslint": "^8.18.0",
-    "eslint-config-athom": "^3.0.1",
+    "eslint": "^8.57.0",
+    "eslint-config-prettier": "^9.1.0",
     "homey-jsdoc-template": "github:athombv/homey-jsdoc-template#1.5.1",
     "jsdoc": "^3.6.10",
     "jsdoc-ts-utils": "^3.0.0",
+    "prettier": "^3.2.5",
     "serve": "^13.0.2",
     "watch": "^1.0.2"
   }

From e1b048652cee4110163e83650044de0a14dd9ed1 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Sun, 7 Apr 2024 16:03:43 +0200
Subject: [PATCH 05/19] pass version to run script

---
 api.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/api.js b/api.js
index 7db9d93..b8cc9b7 100644
--- a/api.js
+++ b/api.js
@@ -32,7 +32,7 @@ module.exports = {
         name: script.name,
         code: code ?? script.code,
         lastExecuted: script.lastExecuted,
-        version: 2,
+        version: script.version,
         args,
       }).finally(() => {
         homey.app.updateScript({ id: script.id, lastExecuted: new Date() }).catch(() => {});

From 47bebf8a4f4b8dee31826df259ddb8af227ac949 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Sun, 7 Apr 2024 16:16:21 +0200
Subject: [PATCH 06/19] remove rejection handler

---
 app.js | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/app.js b/app.js
index ba52741..4be91ac 100644
--- a/app.js
+++ b/app.js
@@ -39,6 +39,13 @@ module.exports = class HomeyScriptApp extends Homey.App {
   static RUN_TIMEOUT = 1000 * 30; // 30s
 
   async onInit() {
+    // Remove since alot of them will be caused by user errors.
+    process.removeAllListeners('unhandledRejection');
+    
+    process.on('unhandledRejection', (reason, promise) => {
+      this.error('Unhandled Rejection at:', promise, 'reason:', reason);
+    });
+
     // Init Scripts
     this.scripts = this.homey.settings.get('scripts');
 
@@ -180,7 +187,8 @@ module.exports = class HomeyScriptApp extends Homey.App {
 
   getHomeyAPI({ version }) {
     if (version >= 2) {
-      return this.createAppApi();
+      const api = this.createAppApi();
+      return api;
     }
 
     const api = new HomeyAPILegacy({
@@ -199,6 +207,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
 
   async onFlowGetScriptAutocomplete(query) {
     const scripts = await this.getScripts();
+
     return Object.values(scripts)
       .filter(script => script.name.toLowerCase().includes(query.toLowerCase()))
       .map(script => ({

From e77554f0534671655e4d5135294d056f99339e6c Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Sun, 7 Apr 2024 16:19:14 +0200
Subject: [PATCH 07/19] update v1 examples

---
 app.js                       | 6 +-----
 examples-v1/flowcard-list.js | 6 ++----
 examples-v1/flowcard-run.js  | 6 ++----
 3 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/app.js b/app.js
index 4be91ac..dc4f42c 100644
--- a/app.js
+++ b/app.js
@@ -30,10 +30,6 @@ const { RunCodeWithArgReturnsStringAction } = require('./lib/flow/actions/RunCod
 const { RunCodeWithArgReturnsNumberAction } = require('./lib/flow/actions/RunCodeWithArgReturnsNumberAction');
 const { RunCodeWithArgReturnsBoolean } = require('./lib/flow/actions/RunCodeWithArgReturnsBoolean');
 
-// TODO
-// update all examples to use the new Homey API
-// create a changes list
-
 module.exports = class HomeyScriptApp extends Homey.App {
 
   static RUN_TIMEOUT = 1000 * 30; // 30s
@@ -41,7 +37,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
   async onInit() {
     // Remove since alot of them will be caused by user errors.
     process.removeAllListeners('unhandledRejection');
-    
+
     process.on('unhandledRejection', (reason, promise) => {
       this.error('Unhandled Rejection at:', promise, 'reason:', reason);
     });
diff --git a/examples-v1/flowcard-list.js b/examples-v1/flowcard-list.js
index 1ffb9c2..8cbabff 100644
--- a/examples-v1/flowcard-list.js
+++ b/examples-v1/flowcard-list.js
@@ -11,10 +11,9 @@ log('===========');
 log('And-cards:');
 log('===========');
 const conditionCards = await Homey.flow.getFlowCardConditions();
-for( const card of conditionCards ) {
+for( const card of Object.values(conditionCards) ) {
   log(card.titleFormatted || card.title)
   log(JSON.stringify({
-    uri: card.uri,
     id: card.id,
     args: card.args,
     droptoken: card.droptoken,
@@ -27,10 +26,9 @@ log('===========');
 log('Then-cards:');
 log('===========');
 const actionCards = await Homey.flow.getFlowCardActions();
-for( const card of actionCards ) {
+for( const card of Object.values(actionCards) ) {
   log(card.titleFormatted || card.title)
   log(JSON.stringify({
-    uri: card.uri,
     id: card.id,
     args: card.args,
     droptoken: card.droptoken,
diff --git a/examples-v1/flowcard-run.js b/examples-v1/flowcard-run.js
index 189fee3..6f1fdcb 100644
--- a/examples-v1/flowcard-run.js
+++ b/examples-v1/flowcard-run.js
@@ -5,8 +5,7 @@
 
 // Run 'Day Equals' Flow 'And' Card
 const { result: isWeekend } = await Homey.flow.runFlowCardCondition({
-  uri: 'homey:manager:cron',
-  id: 'day_equals',
+  id: 'homey:manager:cron:day_equals',
   args: {
     day: 'weekend',
   },
@@ -18,8 +17,7 @@ log('Is Weekend:', isWeekend);
 // This will pulse Green (#00FF00) when it's a weekend
 // or pulse Red (#FF0000) when it's a weekday
 await Homey.flow.runFlowCardAction({
-  uri: 'homey:manager:ledring',
-  id: 'show_animation',
+  id: 'homey:manager:ledring:show_animation',
   args: {
     animation: 'pulse',
     color: isWeekend

From 52e83074bfa50bf332bdd756280b63112b3122ee Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Sun, 7 Apr 2024 16:25:30 +0200
Subject: [PATCH 08/19] rename

---
 app.js                                                        | 4 ++--
 ...eturnsBoolean.js => RunCodeWithArgReturnsBooleanAction.js} | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
 rename lib/flow/actions/{RunCodeWithArgReturnsBoolean.js => RunCodeWithArgReturnsBooleanAction.js} (91%)

diff --git a/app.js b/app.js
index dc4f42c..1585461 100644
--- a/app.js
+++ b/app.js
@@ -28,7 +28,7 @@ const { RunCodeReturnsBooleanAction } = require('./lib/flow/actions/RunCodeRetur
 const { RunCodeWithArgAction } = require('./lib/flow/actions/RunCodeWithArgAction');
 const { RunCodeWithArgReturnsStringAction } = require('./lib/flow/actions/RunCodeWithArgReturnsStringAction');
 const { RunCodeWithArgReturnsNumberAction } = require('./lib/flow/actions/RunCodeWithArgReturnsNumberAction');
-const { RunCodeWithArgReturnsBoolean } = require('./lib/flow/actions/RunCodeWithArgReturnsBoolean');
+const { RunCodeWithArgReturnsBooleanAction } = require('./lib/flow/actions/RunCodeWithArgReturnsBooleanAction');
 
 module.exports = class HomeyScriptApp extends Homey.App {
 
@@ -154,7 +154,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
     this.runCodeWithArgAction = new RunCodeWithArgAction({ homey: this.homey });
     this.runCodeWithArgReturnsStringAction = new RunCodeWithArgReturnsStringAction({ homey: this.homey });
     this.runCodeWithArgReturnsNumberAction = new RunCodeWithArgReturnsNumberAction({ homey: this.homey });
-    this.runCodeWithArgReturnsBoolean = new RunCodeWithArgReturnsBoolean({ homey: this.homey });
+    this.runCodeWithArgReturnsBooleanAction = new RunCodeWithArgReturnsBooleanAction({ homey: this.homey });
 
     // Register Flow Tokens
     this.tokens = this.homey.settings.get('tokens') || {};
diff --git a/lib/flow/actions/RunCodeWithArgReturnsBoolean.js b/lib/flow/actions/RunCodeWithArgReturnsBooleanAction.js
similarity index 91%
rename from lib/flow/actions/RunCodeWithArgReturnsBoolean.js
rename to lib/flow/actions/RunCodeWithArgReturnsBooleanAction.js
index b474529..bba1edf 100644
--- a/lib/flow/actions/RunCodeWithArgReturnsBoolean.js
+++ b/lib/flow/actions/RunCodeWithArgReturnsBooleanAction.js
@@ -2,7 +2,7 @@
 
 const { Base } = require('../../Base');
 
-class RunCodeWithArgReturnsBoolean extends Base {
+class RunCodeWithArgReturnsBooleanAction extends Base {
   /**
    * @param {Object} options
    * @param {import('@types/homey/lib/Homey')} options.homey
@@ -46,4 +46,4 @@ class RunCodeWithArgReturnsBoolean extends Base {
   }
 }
 
-module.exports = { RunCodeWithArgReturnsBoolean };
+module.exports = { RunCodeWithArgReturnsBooleanAction };

From 7c9c184a2b7d640447806a648c1843a21a84db43 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Sun, 7 Apr 2024 16:28:40 +0200
Subject: [PATCH 09/19] upgrade deps

---
 package-lock.json | 28 ++++++++++++++--------------
 package.json      |  4 ++--
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 62ba642..4a0fe77 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,10 +9,10 @@
       "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
-        "athom-api": "^3.7.7",
+        "athom-api": "^3.9.2",
         "homey-api": "^3.4.30",
         "lodash": "^4.17.21",
-        "node-fetch": "^2.6.7",
+        "node-fetch": "^2.7.0",
         "uuid": "^8.3.2"
       },
       "devDependencies": {
@@ -761,9 +761,9 @@
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "node_modules/athom-api": {
-      "version": "3.7.7",
-      "resolved": "https://registry.npmjs.org/athom-api/-/athom-api-3.7.7.tgz",
-      "integrity": "sha512-Z3UmmvkEa66Gpq/dS0F1X21cN8L9umR2/pMdinNpZfUqNd9GIg7vRsp4yXpTFBmBRhxtb5sCaQOd+55e7I2j6g=="
+      "version": "3.9.2",
+      "resolved": "https://registry.npmjs.org/athom-api/-/athom-api-3.9.2.tgz",
+      "integrity": "sha512-0bV75q/MJq6+/5H33RC+yImqf+ww69mgAqrf4IBaM/UcNDU8ZHTxNk9Q+aHP+h7sh8QssV3P45TeTwRXVg3tbw=="
     },
     "node_modules/atob": {
       "version": "2.1.2",
@@ -4032,9 +4032,9 @@
       "dev": true
     },
     "node_modules/node-fetch": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+      "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
       "dependencies": {
         "whatwg-url": "^5.0.0"
       },
@@ -7835,9 +7835,9 @@
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
     },
     "athom-api": {
-      "version": "3.7.7",
-      "resolved": "https://registry.npmjs.org/athom-api/-/athom-api-3.7.7.tgz",
-      "integrity": "sha512-Z3UmmvkEa66Gpq/dS0F1X21cN8L9umR2/pMdinNpZfUqNd9GIg7vRsp4yXpTFBmBRhxtb5sCaQOd+55e7I2j6g=="
+      "version": "3.9.2",
+      "resolved": "https://registry.npmjs.org/athom-api/-/athom-api-3.9.2.tgz",
+      "integrity": "sha512-0bV75q/MJq6+/5H33RC+yImqf+ww69mgAqrf4IBaM/UcNDU8ZHTxNk9Q+aHP+h7sh8QssV3P45TeTwRXVg3tbw=="
     },
     "atob": {
       "version": "2.1.2",
@@ -10469,9 +10469,9 @@
       "dev": true
     },
     "node-fetch": {
-      "version": "2.6.7",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
-      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+      "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
       "requires": {
         "whatwg-url": "^5.0.0"
       }
diff --git a/package.json b/package.json
index c9d0636..4928364 100644
--- a/package.json
+++ b/package.json
@@ -32,10 +32,10 @@
   },
   "homepage": "https://github.com/athombv/com.athom.homeyscript#readme",
   "dependencies": {
-    "athom-api": "^3.7.7",
+    "athom-api": "^3.9.2",
     "homey-api": "^3.4.30",
     "lodash": "^4.17.21",
-    "node-fetch": "^2.6.7",
+    "node-fetch": "^2.7.0",
     "uuid": "^8.3.2"
   },
   "devDependencies": {

From f41bf40fc16d269aab800f1d6d73326e7366eaf3 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Thu, 11 Apr 2024 11:38:31 +0200
Subject: [PATCH 10/19] docs wip

---
 app.js                      |  2 +-
 docs/jsdoc.json             | 14 +++++-------
 docs/tutorials/migrate.json |  3 +++
 docs/tutorials/migrate.md   | 43 +++++++++++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+), 10 deletions(-)
 create mode 100644 docs/tutorials/migrate.json
 create mode 100644 docs/tutorials/migrate.md

diff --git a/app.js b/app.js
index 1585461..7ec1e6f 100644
--- a/app.js
+++ b/app.js
@@ -39,7 +39,7 @@ module.exports = class HomeyScriptApp extends Homey.App {
     process.removeAllListeners('unhandledRejection');
 
     process.on('unhandledRejection', (reason, promise) => {
-      this.error('Unhandled Rejection at:', promise, 'reason:', reason);
+      this.error('Unhandled Rejection:', reason);
     });
 
     // Init Scripts
diff --git a/docs/jsdoc.json b/docs/jsdoc.json
index 264101a..56e13c2 100644
--- a/docs/jsdoc.json
+++ b/docs/jsdoc.json
@@ -8,15 +8,11 @@
     "mainpagetitle": "HomeyScript",
     "template": "./node_modules/homey-jsdoc-template",
     "simpleAnalyticsHost": "sa.athom.com",
-    "destination": "./build"
+    "destination": "./build",
+    "tutorials": "./docs/tutorials"
   },
   "source": {
-    "include": [
-      "./docs/README.md",
-      "./docs/api.js"
-    ]
+    "include": ["./docs/README.md", "./docs/api.js"]
   },
-  "plugins": [
-    "plugins/markdown"
-  ]
-}
\ No newline at end of file
+  "plugins": ["plugins/markdown"]
+}
diff --git a/docs/tutorials/migrate.json b/docs/tutorials/migrate.json
new file mode 100644
index 0000000..6331bda
--- /dev/null
+++ b/docs/tutorials/migrate.json
@@ -0,0 +1,3 @@
+{
+  "title": "Migrate v1 to v2"
+}
\ No newline at end of file
diff --git a/docs/tutorials/migrate.md b/docs/tutorials/migrate.md
new file mode 100644
index 0000000..cf5643e
--- /dev/null
+++ b/docs/tutorials/migrate.md
@@ -0,0 +1,43 @@
+To create a unified API for all our products we decided to introduce [homey-api](https://www.npmjs.com/package/homey-api) as the successor to [athom-api](https://www.npmjs.com/package/athom-api). New HomeyScript's will automatically use the new API under the same global variable [`Homey`](./global#.Homey).
+
+To convert your existing scripts to the new API, you can use the following steps:
+
+## Flow cards
+
+The calls to `flow.getFlowCardTriggers`, `flow.getFlowCardConditions` and `flow.getFlowCardActions` now all return an object with key value pairs instead of an array.
+
+```javascript
+// The following code changes from:
+const conditionCards = await Homey.flow.getFlowCardConditions();
+for (const card of conditionCards) {
+  // ...
+}
+
+// To:
+const conditionCards = await Homey.flow.getFlowCardConditions();
+for (const card of Object.values(conditionCards)) {
+  // ...
+}
+```
+
+The cards can be referenced by the `card.id` property. This is also the key of the card in the collection.
+
+```javascript
+const conditionCards = await Homey.flow.getFlowCardConditions();
+for (const card of Object.values(conditionCards)) {
+  console.log(conditionCards[card.id] === card));
+}
+```
+
+The property `uriObj` has been removed. Before this would contain some properties of the owner of the card. For example if the card belonged to a device it would contain the device name and the icon.
+
+Now you must fetch the device to which the card belongs. Since the id of a card will always be of the format ``homey:<ownerType>:<ownerId>:<cardId>``. It easy to get the device from the `devices.getDevices` call and find the `ownerId`.
+
+```javascript
+const [, ownerType, ownerId, cardId] = card.id.split(':');
+
+if (ownerType === 'device') {
+  const devices = await Homey.devices.getDevices();
+  console.log(devices[ownerId]);
+}
+```

From bb38502b47d8a25641637558b7aad8159f8a5711 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Thu, 11 Apr 2024 12:50:17 +0200
Subject: [PATCH 11/19] update docs

---
 docs/tutorials/migrate.md |   59 +-
 package-lock.json         | 1182 +++++++++++++++++++++----------------
 package.json              |    4 +-
 3 files changed, 732 insertions(+), 513 deletions(-)

diff --git a/docs/tutorials/migrate.md b/docs/tutorials/migrate.md
index cf5643e..72e7ad5 100644
--- a/docs/tutorials/migrate.md
+++ b/docs/tutorials/migrate.md
@@ -1,10 +1,37 @@
 To create a unified API for all our products we decided to introduce [homey-api](https://www.npmjs.com/package/homey-api) as the successor to [athom-api](https://www.npmjs.com/package/athom-api). New HomeyScript's will automatically use the new API under the same global variable [`Homey`](./global#.Homey).
 
-To convert your existing scripts to the new API, you can use the following steps:
+**Editor Scripts** - [https://my.homey.app/scripts/](https://my.homey.app/scripts/)
 
-## Flow cards
+All scripts that use the deprecated API will still work but will have an yellow indicator that tells you that it is using the deprecated API version.
 
-The calls to `flow.getFlowCardTriggers`, `flow.getFlowCardConditions` and `flow.getFlowCardActions` now all return an object with key value pairs instead of an array.
+To use the new API you have to create a new script and copy over the previous code and change it according to the steps below.
+
+**Advanced FlowCards**
+
+All Advanced FlowCards that used the inline code editor have been deprecated. To use the new API the same Advanced FlowCard must be added again and the current code can be copied over and changed according the the steps below.
+
+To convert scripts to the new API, you can use the following steps:
+
+## Step 1 - Devices
+
+For a device the `driverUri` and `zoneName` properties have been removed. The `driverUri` is now part of the `driverId` and the `zoneName` has to be fetched based on the `zone` property of the device.
+
+```javascript
+let deviceZone = await device.getZone();
+
+// Or
+deviceZone = await Homey.zones.getZone({ id: device.zone });
+
+// Or
+const zones = await Homey.zones.getZones();
+
+deviceZone = zones[device.zone];
+const zoneName = deviceZone ? deviceZone.name : 'Missing Zone';
+```
+
+## Step 2 - FlowCards
+
+The calls to `Homey.flow.getFlowCardTriggers`, `Homey.flow.getFlowCardConditions` and `Homey.flow.getFlowCardActions` now all return an object with key value pairs instead of an array.
 
 ```javascript
 // The following code changes from:
@@ -25,13 +52,13 @@ The cards can be referenced by the `card.id` property. This is also the key of t
 ```javascript
 const conditionCards = await Homey.flow.getFlowCardConditions();
 for (const card of Object.values(conditionCards)) {
-  console.log(conditionCards[card.id] === card));
+  console.log(conditionCards[card.id] === card);
 }
 ```
 
 The property `uriObj` has been removed. Before this would contain some properties of the owner of the card. For example if the card belonged to a device it would contain the device name and the icon.
 
-Now you must fetch the device to which the card belongs. Since the id of a card will always be of the format ``homey:<ownerType>:<ownerId>:<cardId>``. It easy to get the device from the `devices.getDevices` call and find the `ownerId`.
+Now you must fetch the device to which the card belongs. Since the id of a card will always be of the format ``homey:<ownerType>:<ownerId>:<cardId>``. It's easy to get the device from the `Homey.devices.getDevices` call and find the `ownerId` or pass the `ownerId` to the `devices.getDevice` call.
 
 ```javascript
 const [, ownerType, ownerId, cardId] = card.id.split(':');
@@ -39,5 +66,27 @@ const [, ownerType, ownerId, cardId] = card.id.split(':');
 if (ownerType === 'device') {
   const devices = await Homey.devices.getDevices();
   console.log(devices[ownerId]);
+
+  // Or
+  const device = await Homey.devices.getDevice({ id: ownerId });
 }
 ```
+
+Calls to `Homey.flow.runFlowCardCondition` and `Homey.flow.runFlowCardAction` no longer require the card `uri` as a parameter.
+
+```javascript
+// The following code changes from:
+await Homey.flow.runFlowCardAction({ uri: card.uri, id: card.id, args: { ... } });
+
+// To:
+await Homey.flow.runFlowCardAction({ id: card.id, args: { ... } });
+```
+
+## Step 3 - Insights
+The `uriObj` property has been deleted from a Log as returned by [`Homey.insights.getLogs()`](https://athombv.github.io/node-homey-api/HomeyAPIV3Local.ManagerInsights.html#getLogs) the owner must be matched the same way as with FlowCards.
+
+## Step 4 - FlowToken
+The `uriObj` property has been deleted from a FlowToken as returned by [`Homey.flowtoken.getFlowTokens()`](https://athombv.github.io/node-homey-api/HomeyAPIV3Local.ManagerFlowToken.html#getFlowTokens) the owner must be matched the same way as with FlowCards.
+
+## Step 5 - Drivers
+The `uriObj` property has been deleted from a Driver as returned by [`Homey.drivers.getDrivers()`](https://athombv.github.io/node-homey-api/HomeyAPIV3Local.ManagerDrivers.html#getDrivers). The icon can now be found under `driver.ownerIconObj` and the color under `driver.color`.
diff --git a/package-lock.json b/package-lock.json
index 4a0fe77..08c1c04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,7 @@
         "jsdoc": "^3.6.10",
         "jsdoc-ts-utils": "^3.0.0",
         "prettier": "^3.2.5",
-        "serve": "^13.0.2",
+        "serve": "^14.2.1",
         "watch": "^1.0.2"
       },
       "engines": {
@@ -480,9 +480,9 @@
       "peer": true
     },
     "node_modules/@zeit/schemas": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
-      "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==",
+      "version": "2.29.0",
+      "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.29.0.tgz",
+      "integrity": "sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==",
       "dev": true
     },
     "node_modules/accepts": {
@@ -633,9 +633,9 @@
       ]
     },
     "node_modules/arg": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz",
-      "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==",
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+      "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
       "dev": true
     },
     "node_modules/argparse": {
@@ -951,27 +951,130 @@
       "peer": true
     },
     "node_modules/boxen": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz",
+      "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==",
+      "dev": true,
+      "dependencies": {
+        "ansi-align": "^3.0.1",
+        "camelcase": "^7.0.0",
+        "chalk": "^5.0.1",
+        "cli-boxes": "^3.0.0",
+        "string-width": "^5.1.2",
+        "type-fest": "^2.13.0",
+        "widest-line": "^4.0.1",
+        "wrap-ansi": "^8.0.1"
+      },
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/boxen/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/boxen/node_modules/ansi-styles": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/boxen/node_modules/chalk": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+      "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+      "dev": true,
+      "engines": {
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/boxen/node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+      "dev": true
+    },
+    "node_modules/boxen/node_modules/string-width": {
       "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
-      "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
       "dev": true,
       "dependencies": {
-        "ansi-align": "^3.0.0",
-        "camelcase": "^6.2.0",
-        "chalk": "^4.1.0",
-        "cli-boxes": "^2.2.1",
-        "string-width": "^4.2.2",
-        "type-fest": "^0.20.2",
-        "widest-line": "^3.1.0",
-        "wrap-ansi": "^7.0.0"
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=12"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/boxen/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+      }
+    },
+    "node_modules/boxen/node_modules/type-fest": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+      "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/boxen/node_modules/wrap-ansi": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^6.1.0",
+        "string-width": "^5.0.1",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1228,12 +1331,12 @@
       }
     },
     "node_modules/camelcase": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz",
+      "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==",
       "dev": true,
       "engines": {
-        "node": ">=10"
+        "node": ">=14.16"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
@@ -1267,6 +1370,21 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/chalk-template": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
+      "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^4.1.2"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk-template?sponsor=1"
+      }
+    },
     "node_modules/chalk/node_modules/supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -1366,29 +1484,32 @@
       }
     },
     "node_modules/cli-boxes": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
-      "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+      "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/clipboardy": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
-      "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz",
+      "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==",
       "dev": true,
       "dependencies": {
-        "arch": "^2.1.1",
-        "execa": "^1.0.0",
-        "is-wsl": "^2.1.1"
+        "arch": "^2.2.0",
+        "execa": "^5.1.1",
+        "is-wsl": "^2.2.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/clipboardy/node_modules/is-wsl": {
@@ -1498,16 +1619,16 @@
       }
     },
     "node_modules/compression": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz",
-      "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==",
+      "version": "1.7.4",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
       "dev": true,
       "dependencies": {
         "accepts": "~1.3.5",
         "bytes": "3.0.0",
-        "compressible": "~2.0.14",
+        "compressible": "~2.0.16",
         "debug": "2.6.9",
-        "on-headers": "~1.0.1",
+        "on-headers": "~1.0.2",
         "safe-buffer": "5.1.2",
         "vary": "~1.1.2"
       },
@@ -1660,28 +1781,17 @@
       }
     },
     "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==",
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "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"
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
       },
       "engines": {
-        "node": ">=4.8"
-      }
-    },
-    "node_modules/cross-spawn/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": ">= 8"
       }
     },
     "node_modules/crypto-browserify": {
@@ -1886,6 +1996,12 @@
         "stream-shift": "^1.0.0"
       }
     },
+    "node_modules/eastasianwidth": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+      "dev": true
+    },
     "node_modules/elliptic": {
       "version": "6.5.4",
       "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
@@ -2134,20 +2250,6 @@
         "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/eslint/node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "dependencies": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
     "node_modules/eslint/node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -2253,51 +2355,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/eslint/node_modules/path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/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==",
-      "dev": true,
-      "dependencies": {
-        "shebang-regex": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/node_modules/shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/node_modules/which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "dependencies": {
-        "isexe": "^2.0.0"
-      },
-      "bin": {
-        "node-which": "bin/node-which"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
     "node_modules/espree": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
@@ -2388,21 +2445,26 @@
       }
     },
     "node_modules/execa": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
-      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
       "dev": true,
       "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"
+        "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.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
       },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
       }
     },
     "node_modules/expand-brackets": {
@@ -2762,15 +2824,15 @@
       }
     },
     "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==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
       "dev": true,
-      "dependencies": {
-        "pump": "^3.0.0"
-      },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/get-value": {
@@ -3042,6 +3104,15 @@
       "dev": true,
       "peer": true
     },
+    "node_modules/human-signals": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.17.0"
+      }
+    },
     "node_modules/icss-utils": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
@@ -3334,13 +3405,28 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/is-port-reachable": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz",
+      "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==",
+      "dev": true,
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/is-windows": {
@@ -3717,6 +3803,12 @@
       "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
       "dev": true
     },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
     "node_modules/miller-rabin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@@ -3757,6 +3849,15 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/minimalistic-assert": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -4025,12 +4126,6 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/nice-try": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
-      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
-      "dev": true
-    },
     "node_modules/node-fetch": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -4101,15 +4196,15 @@
       }
     },
     "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": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
       "dev": true,
       "dependencies": {
-        "path-key": "^2.0.0"
+        "path-key": "^3.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/object-assign": {
@@ -4194,6 +4289,21 @@
         "wrappy": "1"
       }
     },
+    "node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/optionator": {
       "version": "0.9.3",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
@@ -4218,15 +4328,6 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/p-finally": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-      "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/p-limit": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
@@ -4367,12 +4468,12 @@
       "dev": true
     },
     "node_modules/path-key": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
       "dev": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/path-to-regexp": {
@@ -4889,6 +4990,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/requizzle": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
@@ -5062,36 +5172,41 @@
       "dev": true
     },
     "node_modules/serve": {
-      "version": "13.0.2",
-      "resolved": "https://registry.npmjs.org/serve/-/serve-13.0.2.tgz",
-      "integrity": "sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ==",
-      "dev": true,
-      "dependencies": {
-        "@zeit/schemas": "2.6.0",
-        "ajv": "6.12.6",
-        "arg": "2.0.0",
-        "boxen": "5.1.2",
-        "chalk": "2.4.1",
-        "clipboardy": "2.3.0",
-        "compression": "1.7.3",
-        "serve-handler": "6.1.3",
-        "update-check": "1.5.2"
+      "version": "14.2.1",
+      "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.1.tgz",
+      "integrity": "sha512-48er5fzHh7GCShLnNyPBRPEjs2I6QBozeGr02gaacROiyS/8ARADlj595j39iZXAqBbJHH/ivJJyPRWY9sQWZA==",
+      "dev": true,
+      "dependencies": {
+        "@zeit/schemas": "2.29.0",
+        "ajv": "8.11.0",
+        "arg": "5.0.2",
+        "boxen": "7.0.0",
+        "chalk": "5.0.1",
+        "chalk-template": "0.4.0",
+        "clipboardy": "3.0.0",
+        "compression": "1.7.4",
+        "is-port-reachable": "4.0.0",
+        "serve-handler": "6.1.5",
+        "update-check": "1.5.4"
       },
       "bin": {
-        "serve": "bin/serve.js"
+        "serve": "build/main.js"
+      },
+      "engines": {
+        "node": ">= 14"
       }
     },
     "node_modules/serve-handler": {
-      "version": "6.1.3",
-      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz",
-      "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==",
+      "version": "6.1.5",
+      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz",
+      "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==",
       "dev": true,
       "dependencies": {
         "bytes": "3.0.0",
         "content-disposition": "0.5.2",
         "fast-url-parser": "1.1.3",
         "mime-types": "2.1.18",
-        "minimatch": "3.0.4",
+        "minimatch": "3.1.2",
         "path-is-inside": "1.0.2",
         "path-to-regexp": "2.2.1",
         "range-parser": "1.2.0"
@@ -5118,89 +5233,40 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/serve-handler/node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/serve/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/serve/node_modules/chalk": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-      "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+    "node_modules/serve/node_modules/ajv": {
+      "version": "8.11.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
+      "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
       "dev": true,
       "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.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"
-      }
-    },
-    "node_modules/serve/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/serve/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/serve/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": ">=0.8.0"
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "node_modules/serve/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==",
+    "node_modules/serve/node_modules/chalk": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
+      "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
       "dev": true,
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/serve/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": {
-        "has-flag": "^3.0.0"
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
       },
-      "engines": {
-        "node": ">=4"
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/serve/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
     "node_modules/set-value": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
@@ -5239,24 +5305,24 @@
       }
     },
     "node_modules/shebang-command": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
       "dev": true,
       "dependencies": {
-        "shebang-regex": "^1.0.0"
+        "shebang-regex": "^3.0.0"
       },
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=8"
       }
     },
     "node_modules/shebang-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=8"
       }
     },
     "node_modules/shell-quote": {
@@ -5658,13 +5724,13 @@
         "node": ">=8"
       }
     },
-    "node_modules/strip-eof": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
-      "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+    "node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=6"
       }
     },
     "node_modules/strip-json-comments": {
@@ -6183,9 +6249,9 @@
       }
     },
     "node_modules/update-check": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz",
-      "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==",
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz",
+      "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==",
       "dev": true,
       "dependencies": {
         "registry-auth-token": "3.3.2",
@@ -7055,27 +7121,83 @@
       }
     },
     "node_modules/which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
       "dependencies": {
         "isexe": "^2.0.0"
       },
       "bin": {
-        "which": "bin/which"
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
     "node_modules/widest-line": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
-      "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
+      "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==",
       "dev": true,
       "dependencies": {
-        "string-width": "^4.0.0"
+        "string-width": "^5.0.1"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/widest-line/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==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/widest-line/node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+      "dev": true
+    },
+    "node_modules/widest-line/node_modules/string-width": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+      "dev": true,
+      "dependencies": {
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/widest-line/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
     "node_modules/worker-farm": {
@@ -7610,9 +7732,9 @@
       "peer": true
     },
     "@zeit/schemas": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz",
-      "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==",
+      "version": "2.29.0",
+      "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.29.0.tgz",
+      "integrity": "sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==",
       "dev": true
     },
     "accepts": {
@@ -7718,9 +7840,9 @@
       "dev": true
     },
     "arg": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz",
-      "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==",
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+      "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
       "dev": true
     },
     "argparse": {
@@ -7980,19 +8102,82 @@
       "peer": true
     },
     "boxen": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz",
-      "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz",
+      "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==",
       "dev": true,
       "requires": {
-        "ansi-align": "^3.0.0",
-        "camelcase": "^6.2.0",
-        "chalk": "^4.1.0",
-        "cli-boxes": "^2.2.1",
-        "string-width": "^4.2.2",
-        "type-fest": "^0.20.2",
-        "widest-line": "^3.1.0",
-        "wrap-ansi": "^7.0.0"
+        "ansi-align": "^3.0.1",
+        "camelcase": "^7.0.0",
+        "chalk": "^5.0.1",
+        "cli-boxes": "^3.0.0",
+        "string-width": "^5.1.2",
+        "type-fest": "^2.13.0",
+        "widest-line": "^4.0.1",
+        "wrap-ansi": "^8.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==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "6.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+          "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+          "dev": true
+        },
+        "chalk": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+          "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "9.2.2",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+          "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+          "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+          "dev": true,
+          "requires": {
+            "eastasianwidth": "^0.2.0",
+            "emoji-regex": "^9.2.2",
+            "strip-ansi": "^7.0.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+          "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^6.0.1"
+          }
+        },
+        "type-fest": {
+          "version": "2.19.0",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+          "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "8.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+          "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^6.1.0",
+            "string-width": "^5.0.1",
+            "strip-ansi": "^7.0.1"
+          }
+        }
       }
     },
     "brace-expansion": {
@@ -8226,9 +8411,9 @@
       "dev": true
     },
     "camelcase": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
-      "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz",
+      "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==",
       "dev": true
     },
     "catharsis": {
@@ -8261,6 +8446,15 @@
         }
       }
     },
+    "chalk-template": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
+      "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
+      "dev": true,
+      "requires": {
+        "chalk": "^4.1.2"
+      }
+    },
     "chokidar": {
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -8330,20 +8524,20 @@
       }
     },
     "cli-boxes": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
-      "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz",
+      "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==",
       "dev": true
     },
     "clipboardy": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
-      "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz",
+      "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==",
       "dev": true,
       "requires": {
-        "arch": "^2.1.1",
-        "execa": "^1.0.0",
-        "is-wsl": "^2.1.1"
+        "arch": "^2.2.0",
+        "execa": "^5.1.1",
+        "is-wsl": "^2.2.0"
       },
       "dependencies": {
         "is-wsl": {
@@ -8440,16 +8634,16 @@
       }
     },
     "compression": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz",
-      "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==",
+      "version": "1.7.4",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
       "dev": true,
       "requires": {
         "accepts": "~1.3.5",
         "bytes": "3.0.0",
-        "compressible": "~2.0.14",
+        "compressible": "~2.0.16",
         "debug": "2.6.9",
-        "on-headers": "~1.0.1",
+        "on-headers": "~1.0.2",
         "safe-buffer": "5.1.2",
         "vary": "~1.1.2"
       }
@@ -8586,24 +8780,14 @@
       }
     },
     "cross-spawn": {
-      "version": "6.0.5",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
-      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
       "requires": {
-        "nice-try": "^1.0.4",
-        "path-key": "^2.0.1",
-        "semver": "^5.5.0",
-        "shebang-command": "^1.2.0",
-        "which": "^1.2.9"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.7.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
-          "dev": true
-        }
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
       }
     },
     "crypto-browserify": {
@@ -8765,6 +8949,12 @@
         "stream-shift": "^1.0.0"
       }
     },
+    "eastasianwidth": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+      "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+      "dev": true
+    },
     "elliptic": {
       "version": "6.5.4",
       "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
@@ -8949,17 +9139,6 @@
         "text-table": "^0.2.0"
       },
       "dependencies": {
-        "cross-spawn": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-          "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-          "dev": true,
-          "requires": {
-            "path-key": "^3.1.0",
-            "shebang-command": "^2.0.0",
-            "which": "^2.0.1"
-          }
-        },
         "debug": {
           "version": "4.3.4",
           "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -9023,36 +9202,6 @@
           "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
           "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
           "dev": true
-        },
-        "path-key": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-          "dev": true
-        },
-        "shebang-command": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "^3.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-          "dev": true
-        },
-        "which": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-          "dev": true,
-          "requires": {
-            "isexe": "^2.0.0"
-          }
         }
       }
     },
@@ -9148,18 +9297,20 @@
       }
     },
     "execa": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
-      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
       "dev": true,
       "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"
+        "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.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
       }
     },
     "expand-brackets": {
@@ -9461,13 +9612,10 @@
       "dev": true
     },
     "get-stream": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
-      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
-      "dev": true,
-      "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==",
+      "dev": true
     },
     "get-value": {
       "version": "2.0.6",
@@ -9683,6 +9831,12 @@
       "dev": true,
       "peer": true
     },
+    "human-signals": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "dev": true
+    },
     "icss-utils": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
@@ -9899,10 +10053,16 @@
         "isobject": "^3.0.1"
       }
     },
+    "is-port-reachable": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz",
+      "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==",
+      "dev": true
+    },
     "is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
       "dev": true
     },
     "is-windows": {
@@ -10205,6 +10365,12 @@
       "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
       "dev": true
     },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
     "miller-rabin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@@ -10238,6 +10404,12 @@
         "mime-db": "1.52.0"
       }
     },
+    "mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true
+    },
     "minimalistic-assert": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -10462,12 +10634,6 @@
       "dev": true,
       "peer": true
     },
-    "nice-try": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
-      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
-      "dev": true
-    },
     "node-fetch": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -10526,12 +10692,12 @@
       "peer": true
     },
     "npm-run-path": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
-      "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
       "dev": true,
       "requires": {
-        "path-key": "^2.0.0"
+        "path-key": "^3.0.0"
       }
     },
     "object-assign": {
@@ -10600,6 +10766,15 @@
         "wrappy": "1"
       }
     },
+    "onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "^2.1.0"
+      }
+    },
     "optionator": {
       "version": "0.9.3",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
@@ -10621,12 +10796,6 @@
       "dev": true,
       "peer": true
     },
-    "p-finally": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-      "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
-      "dev": true
-    },
     "p-limit": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
@@ -10743,9 +10912,9 @@
       "dev": true
     },
     "path-key": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
       "dev": true
     },
     "path-to-regexp": {
@@ -11141,6 +11310,12 @@
       "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true
     },
+    "require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true
+    },
     "requizzle": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
@@ -11273,91 +11448,61 @@
       "dev": true
     },
     "serve": {
-      "version": "13.0.2",
-      "resolved": "https://registry.npmjs.org/serve/-/serve-13.0.2.tgz",
-      "integrity": "sha512-71R6fKvNgKrqARAag6lYJNnxDzpH7DCNrMuvPY5PLVaC2PDhJsGTj/34o4o4tPWhTuLgEXqvgnAWbATQ9zGZTQ==",
-      "dev": true,
-      "requires": {
-        "@zeit/schemas": "2.6.0",
-        "ajv": "6.12.6",
-        "arg": "2.0.0",
-        "boxen": "5.1.2",
-        "chalk": "2.4.1",
-        "clipboardy": "2.3.0",
-        "compression": "1.7.3",
-        "serve-handler": "6.1.3",
-        "update-check": "1.5.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==",
+      "version": "14.2.1",
+      "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.1.tgz",
+      "integrity": "sha512-48er5fzHh7GCShLnNyPBRPEjs2I6QBozeGr02gaacROiyS/8ARADlj595j39iZXAqBbJHH/ivJJyPRWY9sQWZA==",
+      "dev": true,
+      "requires": {
+        "@zeit/schemas": "2.29.0",
+        "ajv": "8.11.0",
+        "arg": "5.0.2",
+        "boxen": "7.0.0",
+        "chalk": "5.0.1",
+        "chalk-template": "0.4.0",
+        "clipboardy": "3.0.0",
+        "compression": "1.7.4",
+        "is-port-reachable": "4.0.0",
+        "serve-handler": "6.1.5",
+        "update-check": "1.5.4"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "8.11.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
+          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
           "dev": true,
           "requires": {
-            "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"
           }
         },
         "chalk": {
-          "version": "2.4.1",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
-          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
-          "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": "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==",
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz",
+          "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==",
           "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==",
+        "json-schema-traverse": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
           "dev": true
-        },
-        "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"
-          }
         }
       }
     },
     "serve-handler": {
-      "version": "6.1.3",
-      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.3.tgz",
-      "integrity": "sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==",
+      "version": "6.1.5",
+      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz",
+      "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==",
       "dev": true,
       "requires": {
         "bytes": "3.0.0",
         "content-disposition": "0.5.2",
         "fast-url-parser": "1.1.3",
         "mime-types": "2.1.18",
-        "minimatch": "3.0.4",
+        "minimatch": "3.1.2",
         "path-is-inside": "1.0.2",
         "path-to-regexp": "2.2.1",
         "range-parser": "1.2.0"
@@ -11377,15 +11522,6 @@
           "requires": {
             "mime-db": "~1.33.0"
           }
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
         }
       }
     },
@@ -11421,18 +11557,18 @@
       }
     },
     "shebang-command": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
       "dev": true,
       "requires": {
-        "shebang-regex": "^1.0.0"
+        "shebang-regex": "^3.0.0"
       }
     },
     "shebang-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
       "dev": true
     },
     "shell-quote": {
@@ -11790,10 +11926,10 @@
         "ansi-regex": "^5.0.1"
       }
     },
-    "strip-eof": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
-      "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+    "strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
       "dev": true
     },
     "strip-json-comments": {
@@ -12212,9 +12348,9 @@
       "peer": true
     },
     "update-check": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz",
-      "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==",
+      "version": "1.5.4",
+      "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz",
+      "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==",
       "dev": true,
       "requires": {
         "registry-auth-token": "3.3.2",
@@ -12938,21 +13074,55 @@
       }
     },
     "which": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
-      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
       "requires": {
         "isexe": "^2.0.0"
       }
     },
     "widest-line": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
-      "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
+      "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==",
       "dev": true,
       "requires": {
-        "string-width": "^4.0.0"
+        "string-width": "^5.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==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "9.2.2",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+          "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+          "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+          "dev": true,
+          "requires": {
+            "eastasianwidth": "^0.2.0",
+            "emoji-regex": "^9.2.2",
+            "strip-ansi": "^7.0.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+          "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^6.0.1"
+          }
+        }
       }
     },
     "worker-farm": {
diff --git a/package.json b/package.json
index 4928364..311044c 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
   "scripts": {
     "lint": "eslint .",
     "start": "nodemon --watch . --exec \"homey app run\"",
-    "serve": "concurrently \"serve build/\" \"npm run jsdoc:watch\"",
+    "serve": "concurrently \"serve -l 5000 build/\" \"npm run jsdoc:watch\"",
     "build": "npm ci; npm run jsdoc:clean; npm run jsdoc;",
     "jsdoc": "jsdoc --configure ./docs/jsdoc.json;",
     "jsdoc:clean": "rm -rf ./build",
@@ -47,7 +47,7 @@
     "jsdoc": "^3.6.10",
     "jsdoc-ts-utils": "^3.0.0",
     "prettier": "^3.2.5",
-    "serve": "^13.0.2",
+    "serve": "^14.2.1",
     "watch": "^1.0.2"
   }
 }

From 4be2e7477c4eabed248c4ca0cc52c83213b6312c Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Thu, 11 Apr 2024 12:57:22 +0200
Subject: [PATCH 12/19] update docs

---
 docs/tutorials/migrate.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/tutorials/migrate.md b/docs/tutorials/migrate.md
index 72e7ad5..11afaff 100644
--- a/docs/tutorials/migrate.md
+++ b/docs/tutorials/migrate.md
@@ -2,13 +2,13 @@ To create a unified API for all our products we decided to introduce [homey-api]
 
 **Editor Scripts** - [https://my.homey.app/scripts/](https://my.homey.app/scripts/)
 
-All scripts that use the deprecated API will still work but will have an yellow indicator that tells you that it is using the deprecated API version.
+All scripts that use the deprecated API will still work but will have a yellow indicator that tells you that it is using the deprecated API version. If your scripts are not using the global Homey API object there is no need to change the code.
 
 To use the new API you have to create a new script and copy over the previous code and change it according to the steps below.
 
 **Advanced FlowCards**
 
-All Advanced FlowCards that used the inline code editor have been deprecated. To use the new API the same Advanced FlowCard must be added again and the current code can be copied over and changed according the the steps below.
+All Advanced FlowCards that used the inline code editor have been deprecated. To use the new API the same Advanced FlowCard must be added again and the current code can be copied over and changed according the the steps below. The deprecated cards will still work and keep working so if the global Homey API object is not used there is no need to change the code.
 
 To convert scripts to the new API, you can use the following steps:
 

From 7ca51b3fdc08e6a293ec85d56675a6e1ef0fa762 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Thu, 11 Apr 2024 13:26:20 +0200
Subject: [PATCH 13/19] fix lint

---
 .eslintrc.js | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/.eslintrc.js b/.eslintrc.js
index 4ca8db3..4417fcb 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -15,7 +15,5 @@ module.exports = {
       },
     },
   ],
-  ignorePatterns: [
-    "/examples/**"
-  ]
-};
\ No newline at end of file
+  ignorePatterns: ['/examples/**', '/examples-v1/**', 'build'],
+};

From 3042f9c5a0a29abd2c81d28eca4f7656092d3b61 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Thu, 11 Apr 2024 13:33:05 +0200
Subject: [PATCH 14/19] update title

---
 docs/tutorials/migrate.json |   2 +-
 package-lock.json           | 386 +++++++++++++++++++++++++-----------
 package.json                |  10 +-
 3 files changed, 273 insertions(+), 125 deletions(-)

diff --git a/docs/tutorials/migrate.json b/docs/tutorials/migrate.json
index 6331bda..270dfb0 100644
--- a/docs/tutorials/migrate.json
+++ b/docs/tutorials/migrate.json
@@ -1,3 +1,3 @@
 {
-  "title": "Migrate v1 to v2"
+  "title": "Migrating deprecated scripts"
 }
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 08c1c04..8934951 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,12 +17,12 @@
       },
       "devDependencies": {
         "@types/homey": "npm:homey-apps-sdk-v3-types@^0.3.5",
-        "concurrently": "^7.2.2",
+        "concurrently": "^8.2.2",
         "eslint": "^8.57.0",
         "eslint-config-prettier": "^9.1.0",
         "homey-jsdoc-template": "github:athombv/homey-jsdoc-template#1.5.2",
-        "jsdoc": "^3.6.10",
-        "jsdoc-ts-utils": "^3.0.0",
+        "jsdoc": "^3.6.11",
+        "jsdoc-ts-utils": "^5.0.0",
         "prettier": "^3.2.5",
         "serve": "^14.2.1",
         "watch": "^1.0.2"
@@ -41,9 +41,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.18.5",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz",
-      "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==",
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
+      "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -52,6 +52,18 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/@babel/runtime": {
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
+      "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
+      "dev": true,
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@eslint-community/eslint-utils": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -187,6 +199,18 @@
       "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
       "dev": true
     },
+    "node_modules/@jsdoc/salty": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.7.tgz",
+      "integrity": "sha512-mh8LbS9d4Jq84KLw8pzho7XC2q2/IJGiJss3xwRoLD1A+EE16SjN4PfaG4jRCzKegTFLlN0Zd8SdUPE6XdoPFg==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.21"
+      },
+      "engines": {
+        "node": ">=v12.0.0"
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1525,14 +1549,17 @@
       }
     },
     "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==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
       "dependencies": {
         "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
+        "strip-ansi": "^6.0.1",
         "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
     "node_modules/collection-visit": {
@@ -1658,26 +1685,30 @@
       }
     },
     "node_modules/concurrently": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.2.2.tgz",
-      "integrity": "sha512-DcQkI0ruil5BA/g7Xy3EWySGrFJovF5RYAYxwGvv9Jf9q9B1v3jPFP2tl6axExNf1qgF30kjoNYrangZ0ey4Aw==",
+      "version": "8.2.2",
+      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz",
+      "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==",
       "dev": true,
       "dependencies": {
-        "chalk": "^4.1.0",
-        "date-fns": "^2.16.1",
+        "chalk": "^4.1.2",
+        "date-fns": "^2.30.0",
         "lodash": "^4.17.21",
-        "rxjs": "^7.0.0",
-        "shell-quote": "^1.7.3",
-        "spawn-command": "^0.0.2-1",
-        "supports-color": "^8.1.0",
+        "rxjs": "^7.8.1",
+        "shell-quote": "^1.8.1",
+        "spawn-command": "0.0.2",
+        "supports-color": "^8.1.1",
         "tree-kill": "^1.2.2",
-        "yargs": "^17.3.1"
+        "yargs": "^17.7.2"
       },
       "bin": {
+        "conc": "dist/bin/concurrently.js",
         "concurrently": "dist/bin/concurrently.js"
       },
       "engines": {
-        "node": "^12.20.0 || ^14.13.0 || >=16.0.0"
+        "node": "^14.13.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
       }
     },
     "node_modules/console-browserify": {
@@ -1864,10 +1895,13 @@
       "dev": true
     },
     "node_modules/date-fns": {
-      "version": "2.28.0",
-      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz",
-      "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==",
+      "version": "2.30.0",
+      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+      "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
       "dev": true,
+      "dependencies": {
+        "@babel/runtime": "^7.21.0"
+      },
       "engines": {
         "node": ">=0.11"
       },
@@ -2138,9 +2172,9 @@
       }
     },
     "node_modules/escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
       "dev": true,
       "engines": {
         "node": ">=6"
@@ -3492,9 +3526,9 @@
       }
     },
     "node_modules/jsdoc": {
-      "version": "3.6.10",
-      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz",
-      "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==",
+      "version": "3.6.11",
+      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.11.tgz",
+      "integrity": "sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==",
       "dev": true,
       "dependencies": {
         "@babel/parser": "^7.9.4",
@@ -3503,7 +3537,7 @@
         "catharsis": "^0.9.0",
         "escape-string-regexp": "^2.0.0",
         "js2xmlparser": "^4.0.2",
-        "klaw": "^4.0.1",
+        "klaw": "^3.0.0",
         "markdown-it": "^12.3.2",
         "markdown-it-anchor": "^8.4.1",
         "marked": "^4.0.10",
@@ -3517,19 +3551,63 @@
         "jsdoc": "jsdoc.js"
       },
       "engines": {
-        "node": ">=8.15.0"
+        "node": ">=12.0.0"
       }
     },
     "node_modules/jsdoc-ts-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/jsdoc-ts-utils/-/jsdoc-ts-utils-3.0.0.tgz",
-      "integrity": "sha512-8Qy8EGi9CLKXi1ZZEUmU4s8xuET6zmXSUc6suB1EpR6Sws3A1z/m17U10+Gxbjxsurv2SlV3h6j3FPHN33LPFQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-ts-utils/-/jsdoc-ts-utils-5.0.0.tgz",
+      "integrity": "sha512-8/80crdVqPmEUXHaWhS7tLFpngw5BwA28ITkX11WSdJmsKM5Ry96vNUw20zu17lEvCAGZyi9UN3Y9gu8xzx7tg==",
       "dev": true,
       "dependencies": {
-        "jsdoc": "^3.6.10"
+        "jsdoc": "^4.0.2"
       },
       "engines": {
-        "node": ">=14"
+        "node": ">=18.17 <21"
+      },
+      "peerDependencies": {
+        "jsdoc": "*"
+      }
+    },
+    "node_modules/jsdoc-ts-utils/node_modules/jsdoc": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz",
+      "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.20.15",
+        "@jsdoc/salty": "^0.2.1",
+        "@types/markdown-it": "^12.2.3",
+        "bluebird": "^3.7.2",
+        "catharsis": "^0.9.0",
+        "escape-string-regexp": "^2.0.0",
+        "js2xmlparser": "^4.0.2",
+        "klaw": "^3.0.0",
+        "markdown-it": "^12.3.2",
+        "markdown-it-anchor": "^8.4.1",
+        "marked": "^4.0.10",
+        "mkdirp": "^1.0.4",
+        "requizzle": "^0.2.3",
+        "strip-json-comments": "^3.1.0",
+        "underscore": "~1.13.2"
+      },
+      "bin": {
+        "jsdoc": "jsdoc.js"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/jsdoc-ts-utils/node_modules/mkdirp": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+      "dev": true,
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
     "node_modules/jsdoc/node_modules/mkdirp": {
@@ -3595,12 +3673,12 @@
       }
     },
     "node_modules/klaw": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz",
-      "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+      "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
       "dev": true,
-      "engines": {
-        "node": ">=14.14.0"
+      "dependencies": {
+        "graceful-fs": "^4.1.9"
       }
     },
     "node_modules/levn": {
@@ -4890,6 +4968,12 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+      "dev": true
+    },
     "node_modules/regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -5101,9 +5185,9 @@
       }
     },
     "node_modules/rxjs": {
-      "version": "7.5.5",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
-      "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
       "dev": true,
       "dependencies": {
         "tslib": "^2.1.0"
@@ -5326,10 +5410,13 @@
       }
     },
     "node_modules/shell-quote": {
-      "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==",
-      "dev": true
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
+      "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
     "node_modules/signal-exit": {
       "version": "3.0.7",
@@ -5580,9 +5667,9 @@
       "peer": true
     },
     "node_modules/spawn-command": {
-      "version": "0.0.2-1",
-      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
-      "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==",
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz",
+      "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==",
       "dev": true
     },
     "node_modules/split-string": {
@@ -6047,9 +6134,9 @@
       }
     },
     "node_modules/tslib": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
-      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
       "dev": true
     },
     "node_modules/tty-browserify": {
@@ -7288,27 +7375,27 @@
       "dev": true
     },
     "node_modules/yargs": {
-      "version": "17.5.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
-      "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+      "version": "17.7.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "dev": true,
       "dependencies": {
-        "cliui": "^7.0.2",
+        "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
         "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^21.0.0"
+        "yargs-parser": "^21.1.1"
       },
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/yargs-parser": {
-      "version": "21.0.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
-      "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
       "dev": true,
       "engines": {
         "node": ">=12"
@@ -7349,11 +7436,20 @@
       "dev": true
     },
     "@babel/parser": {
-      "version": "7.18.5",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz",
-      "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==",
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
+      "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
       "dev": true
     },
+    "@babel/runtime": {
+      "version": "7.24.4",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
+      "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
+      "dev": true,
+      "requires": {
+        "regenerator-runtime": "^0.14.0"
+      }
+    },
     "@eslint-community/eslint-utils": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -7449,6 +7545,15 @@
       "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
       "dev": true
     },
+    "@jsdoc/salty": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.7.tgz",
+      "integrity": "sha512-mh8LbS9d4Jq84KLw8pzho7XC2q2/IJGiJss3xwRoLD1A+EE16SjN4PfaG4jRCzKegTFLlN0Zd8SdUPE6XdoPFg==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.21"
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -8552,13 +8657,13 @@
       }
     },
     "cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "version": "8.0.1",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
       "requires": {
         "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
+        "strip-ansi": "^6.0.1",
         "wrap-ansi": "^7.0.0"
       }
     },
@@ -8667,20 +8772,20 @@
       }
     },
     "concurrently": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.2.2.tgz",
-      "integrity": "sha512-DcQkI0ruil5BA/g7Xy3EWySGrFJovF5RYAYxwGvv9Jf9q9B1v3jPFP2tl6axExNf1qgF30kjoNYrangZ0ey4Aw==",
+      "version": "8.2.2",
+      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz",
+      "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==",
       "dev": true,
       "requires": {
-        "chalk": "^4.1.0",
-        "date-fns": "^2.16.1",
+        "chalk": "^4.1.2",
+        "date-fns": "^2.30.0",
         "lodash": "^4.17.21",
-        "rxjs": "^7.0.0",
-        "shell-quote": "^1.7.3",
-        "spawn-command": "^0.0.2-1",
-        "supports-color": "^8.1.0",
+        "rxjs": "^7.8.1",
+        "shell-quote": "^1.8.1",
+        "spawn-command": "0.0.2",
+        "supports-color": "^8.1.1",
         "tree-kill": "^1.2.2",
-        "yargs": "^17.3.1"
+        "yargs": "^17.7.2"
       }
     },
     "console-browserify": {
@@ -8841,10 +8946,13 @@
       "dev": true
     },
     "date-fns": {
-      "version": "2.28.0",
-      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz",
-      "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==",
-      "dev": true
+      "version": "2.30.0",
+      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+      "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+      "dev": true,
+      "requires": {
+        "@babel/runtime": "^7.21.0"
+      }
     },
     "debug": {
       "version": "2.6.9",
@@ -9082,9 +9190,9 @@
       }
     },
     "escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
+      "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
       "dev": true
     },
     "escape-string-regexp": {
@@ -10116,9 +10224,9 @@
       }
     },
     "jsdoc": {
-      "version": "3.6.10",
-      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz",
-      "integrity": "sha512-IdQ8ppSo5LKZ9o3M+LKIIK8i00DIe5msDvG3G81Km+1dhy0XrOWD0Ji8H61ElgyEj/O9KRLokgKbAM9XX9CJAg==",
+      "version": "3.6.11",
+      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.11.tgz",
+      "integrity": "sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==",
       "dev": true,
       "requires": {
         "@babel/parser": "^7.9.4",
@@ -10127,7 +10235,7 @@
         "catharsis": "^0.9.0",
         "escape-string-regexp": "^2.0.0",
         "js2xmlparser": "^4.0.2",
-        "klaw": "^4.0.1",
+        "klaw": "^3.0.0",
         "markdown-it": "^12.3.2",
         "markdown-it-anchor": "^8.4.1",
         "marked": "^4.0.10",
@@ -10153,12 +10261,43 @@
       }
     },
     "jsdoc-ts-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/jsdoc-ts-utils/-/jsdoc-ts-utils-3.0.0.tgz",
-      "integrity": "sha512-8Qy8EGi9CLKXi1ZZEUmU4s8xuET6zmXSUc6suB1EpR6Sws3A1z/m17U10+Gxbjxsurv2SlV3h6j3FPHN33LPFQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/jsdoc-ts-utils/-/jsdoc-ts-utils-5.0.0.tgz",
+      "integrity": "sha512-8/80crdVqPmEUXHaWhS7tLFpngw5BwA28ITkX11WSdJmsKM5Ry96vNUw20zu17lEvCAGZyi9UN3Y9gu8xzx7tg==",
       "dev": true,
       "requires": {
-        "jsdoc": "^3.6.10"
+        "jsdoc": "^4.0.2"
+      },
+      "dependencies": {
+        "jsdoc": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz",
+          "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==",
+          "dev": true,
+          "requires": {
+            "@babel/parser": "^7.20.15",
+            "@jsdoc/salty": "^0.2.1",
+            "@types/markdown-it": "^12.2.3",
+            "bluebird": "^3.7.2",
+            "catharsis": "^0.9.0",
+            "escape-string-regexp": "^2.0.0",
+            "js2xmlparser": "^4.0.2",
+            "klaw": "^3.0.0",
+            "markdown-it": "^12.3.2",
+            "markdown-it-anchor": "^8.4.1",
+            "marked": "^4.0.10",
+            "mkdirp": "^1.0.4",
+            "requizzle": "^0.2.3",
+            "strip-json-comments": "^3.1.0",
+            "underscore": "~1.13.2"
+          }
+        },
+        "mkdirp": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+          "dev": true
+        }
       }
     },
     "json-parse-better-errors": {
@@ -10197,10 +10336,13 @@
       }
     },
     "klaw": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz",
-      "integrity": "sha512-pgsE40/SvC7st04AHiISNewaIMUbY5V/K8b21ekiPiFoYs/EYSdsGa+FJArB1d441uq4Q8zZyIxvAzkGNlBdRw==",
-      "dev": true
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+      "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.9"
+      }
     },
     "levn": {
       "version": "0.4.1",
@@ -11229,6 +11371,12 @@
         "picomatch": "^2.2.1"
       }
     },
+    "regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+      "dev": true
+    },
     "regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -11390,9 +11538,9 @@
       }
     },
     "rxjs": {
-      "version": "7.5.5",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
-      "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
       "dev": true,
       "requires": {
         "tslib": "^2.1.0"
@@ -11572,9 +11720,9 @@
       "dev": true
     },
     "shell-quote": {
-      "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==",
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
+      "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
       "dev": true
     },
     "signal-exit": {
@@ -11798,9 +11946,9 @@
       "peer": true
     },
     "spawn-command": {
-      "version": "0.0.2-1",
-      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
-      "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==",
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz",
+      "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==",
       "dev": true
     },
     "split-string": {
@@ -12183,9 +12331,9 @@
       "dev": true
     },
     "tslib": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
-      "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
       "dev": true
     },
     "tty-browserify": {
@@ -13187,18 +13335,18 @@
       "dev": true
     },
     "yargs": {
-      "version": "17.5.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
-      "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+      "version": "17.7.2",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "dev": true,
       "requires": {
-        "cliui": "^7.0.2",
+        "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
         "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^21.0.0"
+        "yargs-parser": "^21.1.1"
       },
       "dependencies": {
         "y18n": {
@@ -13210,9 +13358,9 @@
       }
     },
     "yargs-parser": {
-      "version": "21.0.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
-      "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
       "dev": true
     },
     "yeast": {
diff --git a/package.json b/package.json
index 311044c..d4b955f 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "com.athom.homeyscript",
   "version": "1.0.0",
   "description": "",
-  "main": "api.js",
+  "main": "app.js",
   "scripts": {
     "lint": "eslint .",
     "start": "nodemon --watch . --exec \"homey app run\"",
@@ -19,7 +19,7 @@
     ]
   },
   "engines": {
-    "node": ">=16"
+    "node": ">=18"
   },
   "repository": {
     "type": "git",
@@ -40,12 +40,12 @@
   },
   "devDependencies": {
     "@types/homey": "npm:homey-apps-sdk-v3-types@^0.3.5",
-    "concurrently": "^7.2.2",
+    "concurrently": "^8.2.2",
     "eslint": "^8.57.0",
     "eslint-config-prettier": "^9.1.0",
     "homey-jsdoc-template": "github:athombv/homey-jsdoc-template#1.5.2",
-    "jsdoc": "^3.6.10",
-    "jsdoc-ts-utils": "^3.0.0",
+    "jsdoc": "^3.6.11",
+    "jsdoc-ts-utils": "^5.0.0",
     "prettier": "^3.2.5",
     "serve": "^14.2.1",
     "watch": "^1.0.2"

From 648f69fe4c989ac5c8c4354d76e6548dd669d577 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Thu, 11 Apr 2024 13:35:05 +0200
Subject: [PATCH 15/19] update editorconfig

---
 .editorconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.editorconfig b/.editorconfig
index 23511fc..20d5574 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,7 +9,7 @@ indent_size = 2
 
 trim_trailing_whitespace = true
 
-max_line_length = 120
+max_line_length = 100
 insert_final_newline = true
 
 ij_javascript_use_double_quotes = false

From e026df0c88fcef6764b2266388fbb8eda2e90de9 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Mon, 15 Apr 2024 13:26:09 +0200
Subject: [PATCH 16/19] update homey-api

---
 package-lock.json | 14 +++++++-------
 package.json      |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 8934951..29b9bcf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "athom-api": "^3.9.2",
-        "homey-api": "^3.4.30",
+        "homey-api": "^3.4.31",
         "lodash": "^4.17.21",
         "node-fetch": "^2.7.0",
         "uuid": "^8.3.2"
@@ -3104,9 +3104,9 @@
       }
     },
     "node_modules/homey-api": {
-      "version": "3.4.30",
-      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.4.30.tgz",
-      "integrity": "sha512-jm/mCp4UOSzJRuEUUSxr2OooKAw5g38eg26afN+e+TIs231RawNQ+Pb7KXhSNmU3Z9Fz2SxZJjMUiMO0Pn2QSg==",
+      "version": "3.4.31",
+      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.4.31.tgz",
+      "integrity": "sha512-HdSG7eEhX3axHG1ODODY9Yev0xOmw5Dpx6uMW5gkRGIHuyMH0KKkE29WiqnvrVPyok5Vo5DIb9AbBW1TsQ03vQ==",
       "dependencies": {
         "form-data": "^4.0.0",
         "node-fetch": "^2.6.7",
@@ -9912,9 +9912,9 @@
       }
     },
     "homey-api": {
-      "version": "3.4.30",
-      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.4.30.tgz",
-      "integrity": "sha512-jm/mCp4UOSzJRuEUUSxr2OooKAw5g38eg26afN+e+TIs231RawNQ+Pb7KXhSNmU3Z9Fz2SxZJjMUiMO0Pn2QSg==",
+      "version": "3.4.31",
+      "resolved": "https://registry.npmjs.org/homey-api/-/homey-api-3.4.31.tgz",
+      "integrity": "sha512-HdSG7eEhX3axHG1ODODY9Yev0xOmw5Dpx6uMW5gkRGIHuyMH0KKkE29WiqnvrVPyok5Vo5DIb9AbBW1TsQ03vQ==",
       "requires": {
         "form-data": "^4.0.0",
         "node-fetch": "^2.6.7",
diff --git a/package.json b/package.json
index d4b955f..f4499e6 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,7 @@
   "homepage": "https://github.com/athombv/com.athom.homeyscript#readme",
   "dependencies": {
     "athom-api": "^3.9.2",
-    "homey-api": "^3.4.30",
+    "homey-api": "^3.4.31",
     "lodash": "^4.17.21",
     "node-fetch": "^2.7.0",
     "uuid": "^8.3.2"

From 9f90408f540d1642dd1e764e3cbea8193e4bcf28 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Mon, 15 Apr 2024 15:18:11 +0200
Subject: [PATCH 17/19] update actions

---
 .github/workflows/docs.yml | 30 ++++++++++++++++--------------
 .github/workflows/lint.yml | 37 +++++++++++++++++++------------------
 .nvmrc                     |  1 +
 3 files changed, 36 insertions(+), 32 deletions(-)
 create mode 100644 .nvmrc

diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index e93a3bd..321451b 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -13,20 +13,22 @@ jobs:
     name: Build & Deploy
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
 
-    - name: Setup Node.js
-      uses: actions/setup-node@v1
-      with:
-        node-version: '12'
+      # Setup
+      - name: Setup Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version-file: '.nvmrc'
+          registry-url: 'https://npm.pkg.github.com'
 
-    # Build
-    - name: Build
-      run: npm run build
+      # Build
+      - name: Build
+        run: npm run build
 
-    # Deploy
-    - name: Deploy To GitHub Pages
-      uses: peaceiris/actions-gh-pages@v3.8.0
-      with:
-        personal_token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
-        publish_dir: ./build
\ No newline at end of file
+      # Deploy
+      - name: Deploy To GitHub Pages
+        uses: peaceiris/actions-gh-pages@v3.8.0
+        with:
+          personal_token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
+          publish_dir: ./build
\ No newline at end of file
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index b895270..6cf73f8 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,7 +1,10 @@
 name: Lint
 
-# Optional secrets:
-# - SSH_KEY: if `npm ci` needs to install private npm packages
+# Version: 2.0.1
+# Modified: Yes
+#
+# Secrets:
+# - HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN
 
 # GitHub repo configuration:
 # 1. If you have protected branches, go to Branches > edit protected branch > enable 'Require status checks to pass before
@@ -12,33 +15,31 @@ name: Lint
 # Defines the trigger for this action (e.g. [pull_request, push])
 # For more information see: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#about-workflow-events)
 on:
+  workflow_dispatch:
+  pull_request:
   push:
     branches:
       - master
-  pull_request:
+      - develop
 
 jobs:
   lint:
     name: Lint
     runs-on: ubuntu-latest
     steps:
-      # Checks out the current repository.
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4
 
-      # Configures a Node.js environment.
-      - uses: actions/setup-node@v1
+      # Setup
+      - name: Setup Node.js
+        uses: actions/setup-node@v4
         with:
-          node-version: '12'
+          node-version-file: '.nvmrc'
+          registry-url: 'https://npm.pkg.github.com'
 
-      # Set SSH key
-      - uses: webfactory/ssh-agent@v0.4.1
+      - name: Install modules
+        run: npm clean-install --audit=false
         env:
-          SSH_KEY: ${{ secrets.SSH_KEY }}
-        if: env.SSH_KEY != null
-        with:
-          ssh-private-key: ${{ env.SSH_KEY }}
+          GITHUB_TOKEN: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
 
-      # Run `npm ci` to re-create your local environment (make sure to commit your package-lock.json!).
-      # Finally run `npm run lint` (make sure you have defined a lint command in package.json e.g. "lint": "eslint .").
-      - run: npm ci
-      - run: npm run lint
\ No newline at end of file
+      - name: Lint
+        run: npm run lint
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..2edeafb
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+20
\ No newline at end of file

From 77bf08f31b1dcfc4f02886d08281d17941348a48 Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Mon, 15 Apr 2024 15:36:49 +0200
Subject: [PATCH 18/19] update actions

---
 .github/workflows/docs.yml | 7 +++++++
 .github/workflows/lint.yml | 8 ++++++++
 2 files changed, 15 insertions(+)

diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 321451b..21ffbb4 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -15,6 +15,13 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - uses: webfactory/ssh-agent@v0.9.0
+        env:
+          SSH_KEY: ${{ secrets.SSH_KEY }}
+        if: env.SSH_KEY != null
+        with:
+          ssh-private-key: ${{ env.SSH_KEY }}
+
       # Setup
       - name: Setup Node.js
         uses: actions/setup-node@v4
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 6cf73f8..c4661a4 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -5,6 +5,7 @@ name: Lint
 #
 # Secrets:
 # - HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN
+# - SSH_KEY
 
 # GitHub repo configuration:
 # 1. If you have protected branches, go to Branches > edit protected branch > enable 'Require status checks to pass before
@@ -29,6 +30,13 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - uses: webfactory/ssh-agent@v0.9.0
+        env:
+          SSH_KEY: ${{ secrets.SSH_KEY }}
+        if: env.SSH_KEY != null
+        with:
+          ssh-private-key: ${{ env.SSH_KEY }}
+
       # Setup
       - name: Setup Node.js
         uses: actions/setup-node@v4

From 5cd3bb35ceb5855e93a79ea977646d92ef34fb3b Mon Sep 17 00:00:00 2001
From: Jeroen Wienk <jeroenwienk@gmail.com>
Date: Mon, 15 Apr 2024 15:53:38 +0200
Subject: [PATCH 19/19] update actions

---
 .github/workflows/docs.yml | 5 +++++
 package.json               | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 21ffbb4..63fdf40 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -29,6 +29,11 @@ jobs:
           node-version-file: '.nvmrc'
           registry-url: 'https://npm.pkg.github.com'
 
+      - name: Install modules
+        run: npm clean-install --audit=false
+        env:
+          GITHUB_TOKEN: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
+
       # Build
       - name: Build
         run: npm run build
diff --git a/package.json b/package.json
index f4499e6..a41c19b 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
     "lint": "eslint .",
     "start": "nodemon --watch . --exec \"homey app run\"",
     "serve": "concurrently \"serve -l 5000 build/\" \"npm run jsdoc:watch\"",
-    "build": "npm ci; npm run jsdoc:clean; npm run jsdoc;",
+    "build": "npm run jsdoc:clean; npm run jsdoc;",
     "jsdoc": "jsdoc --configure ./docs/jsdoc.json;",
     "jsdoc:clean": "rm -rf ./build",
     "jsdoc:watch": "watch \"npm run jsdoc:clean && npm run jsdoc\" ./docs docs"