Repository: stateful/vscode-runme
Pull request #522 (2023-05-18 16:37:57)

Store last stdout in `$__`
Solves #519

Requires stateful/runme#250 (proto changes needed for build)


Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a5a0d2ad..4f73c844 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -61,7 +61,7 @@ cd vscode-runme
 nvm install
 ```
 
-optionally install the GitHub CLI to streamline downloading the WASM binary:
+optionally install the GitHub CLI to streamline downloading binaries:
 
 ```sh
 # macOS
@@ -75,18 +75,34 @@ make sure to configure your local npm to pull from Buf's registry (for GRPC depe
 npm config set @buf:registry https://buf.build/gen/npm/v1
 ```
 
-then ensure to install all project dependencies.
+then ensure to install all project dependencies. Note GitHub token is required to auto-dowload the latest `runme` binary. The branch ref name is optional, if it's not `main` pre-release binaries are being considered.
 
-```sh { name=setup }
-GITHUB_REF_NAME=$(git branch --show-current) GITHUB_TOKEN=$(gh auth token) npm install --include=dev
+```sh { name=setup promptEnv=false }
+$ export GITHUB_REF_NAME=$(git branch --show-current)
+$ export GITHUB_TOKEN=$(gh auth token)
+$ npm install --include=dev
 ```
 
-This should also download the Runme CLI WASM file. If an error happened follow the error instructions and re-run the download, via:
+Similarly a Runme WASM binary needs to be downloaded. If an error happened follow the error instructions and re-run the download, via:
 
-```sh { interactive=false }
-export GITHUB_REF_NAME=$(git branch --show-current)
-GITHUB_TOKEN=$(gh auth token) npm run download:wasm
-npm run prepare-binary -- -f tar
+```sh { interactive=true promptEnv=false }
+$ export GITHUB_REF_NAME=$(git branch --show-current)
+$ GITHUB_TOKEN=$(gh auth token) npm run download:wasm
+$ npm run prepare-binary -- -f tar
+```
+
+### Dev against Project
+
+Make sure to install all recommended extensions please:
+
+```sh { interactive=false mimeType=text/x-json }
+cat .vscode/extensions.json | grep -v '\/\/' | jq .
+```
+
+Then just run the watcher and you're off to the races.
+
+```sh { name=npm-watch background=true }
+npm run watch
 ```
 
 ### Build Project
diff --git a/__mocks__/vscode.ts b/__mocks__/vscode.ts
index 7348f62b..c6d766b3 100644
--- a/__mocks__/vscode.ts
+++ b/__mocks__/vscode.ts
@@ -74,6 +74,9 @@ export const terminal = {
 }
 
 export const window = {
+  createOutputChannel: vi.fn().mockReturnValue({
+    appendLine: vi.fn()
+  }),
   showWarningMessage: vi.fn(),
   showInformationMessage: vi.fn(),
   showErrorMessage: vi.fn(),
diff --git a/examples/README.md b/examples/README.md
index 3f2c432c..f3b7c23f 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,3 +1,8 @@
+---
+sidebar_position: 1
+title: Examples
+---
+
 # Runme Examples
 
 This `README.md` contains some examples for testing this extension.
diff --git a/package-lock.json b/package-lock.json
index 866a7f7b..5f6b8253 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,17 +1,17 @@
 {
   "name": "runme",
-  "version": "1.3.1-edge.0",
+  "version": "1.3.1-edge.1",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "runme",
-      "version": "1.3.1-edge.0",
+      "version": "1.3.1-edge.1",
       "hasInstallScript": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@buf/grpc_grpc.community_timostamm-protobuf-ts": "^2.9.0-20230505202852-f6db652602f5.1",
-        "@buf/stateful_runme.community_timostamm-protobuf-ts": "^2.9.0-20230419234326-3a45ee6262e7.1",
+        "@buf/stateful_runme.community_timostamm-protobuf-ts": "^2.9.0-20230522162609-549daeeacece.1",
         "@protobuf-ts/grpc-transport": "^2.9.0",
         "@protobuf-ts/runtime": "^2.9.0",
         "@protobuf-ts/runtime-rpc": "^2.9.0",
@@ -1848,8 +1848,8 @@
       }
     },
     "node_modules/@buf/stateful_runme.community_timostamm-protobuf-ts": {
-      "version": "2.9.0-20230419234326-3a45ee6262e7.1",
-      "resolved": "https://buf.build/gen/npm/v1/@buf/stateful_runme.community_timostamm-protobuf-ts/-/stateful_runme.community_timostamm-protobuf-ts-2.9.0-20230419234326-3a45ee6262e7.1.tgz",
+      "version": "2.9.0-20230522162609-549daeeacece.1",
+      "resolved": "https://buf.build/gen/npm/v1/@buf/stateful_runme.community_timostamm-protobuf-ts/-/stateful_runme.community_timostamm-protobuf-ts-2.9.0-20230522162609-549daeeacece.1.tgz",
       "peerDependencies": {
         "@protobuf-ts/runtime": "^2.9.0",
         "@protobuf-ts/runtime-rpc": "^2.9.0"
@@ -2319,9 +2319,9 @@
       }
     },
     "node_modules/@eslint/js": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
-      "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
+      "version": "8.41.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
+      "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3160,9 +3160,9 @@
       }
     },
     "node_modules/@octokit/core": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
-      "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz",
+      "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==",
       "dependencies": {
         "@octokit/auth-token": "^3.0.0",
         "@octokit/graphql": "^5.0.0",
@@ -3250,11 +3250,12 @@
       "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ=="
     },
     "node_modules/@octokit/plugin-paginate-rest": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.0.tgz",
-      "integrity": "sha512-5T4iXjJdYCVA1rdWS1C+uZV9AvtZY9QgTG74kFiSFVj94dZXowyi/YK8f4SGjZaL69jZthGlBaDKRdCMCF9log==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
+      "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
       "dependencies": {
-        "@octokit/types": "^9.2.2"
+        "@octokit/tsconfig": "^1.0.2",
+        "@octokit/types": "^9.2.3"
       },
       "engines": {
         "node": ">= 14"
@@ -3273,11 +3274,11 @@
       }
     },
     "node_modules/@octokit/plugin-rest-endpoint-methods": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.0.tgz",
-      "integrity": "sha512-SWwz/hc47GaKJR6BlJI4WIVRodbAFRvrR0QRPSoPMs7krb7anYPML3psg+ThEz/kcwOdSNh/oA8qThi/Wvs4Fw==",
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz",
+      "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==",
       "dependencies": {
-        "@octokit/types": "^9.2.2",
+        "@octokit/types": "^9.2.3",
         "deprecation": "^2.3.1"
       },
       "engines": {
@@ -3303,9 +3304,9 @@
       }
     },
     "node_modules/@octokit/plugin-throttling": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.0.tgz",
-      "integrity": "sha512-qWYvVIS1aRC3hN4a0ICWUp51IolHIn7E4iri2AKjbExJaovMDvRtae4nGoxG5pP6+WATk7JZ5epOJobFbGYV1w==",
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz",
+      "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==",
       "dependencies": {
         "@octokit/types": "^9.0.0",
         "bottleneck": "^2.15.3"
@@ -3347,26 +3348,31 @@
       }
     },
     "node_modules/@octokit/rest": {
-      "version": "19.0.8",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.8.tgz",
-      "integrity": "sha512-/PKrzqn+zDzXKwBMwLI2IKrvk8yv8cedJOdcmxrjR3gmu6UIzURhP5oQj+4qkn7+uQi1gg7QqV4SqlaQ1HYW1Q==",
+      "version": "19.0.11",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz",
+      "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==",
       "dev": true,
       "dependencies": {
-        "@octokit/core": "^4.1.0",
-        "@octokit/plugin-paginate-rest": "^6.1.0",
+        "@octokit/core": "^4.2.1",
+        "@octokit/plugin-paginate-rest": "^6.1.2",
         "@octokit/plugin-request-log": "^1.0.4",
-        "@octokit/plugin-rest-endpoint-methods": "^7.1.0"
+        "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
       },
       "engines": {
         "node": ">= 14"
       }
     },
+    "node_modules/@octokit/tsconfig": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz",
+      "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA=="
+    },
     "node_modules/@octokit/types": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.2.tgz",
-      "integrity": "sha512-9BjDxjgQIvCjNWZsbqyH5QC2Yni16oaE6xL+8SUBMzcYPF4TGQBXGA97Cl3KceK9mwiNMb1mOYCz6FbCCLEL+g==",
+      "version": "9.2.3",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz",
+      "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==",
       "dependencies": {
-        "@octokit/openapi-types": "^17.1.2"
+        "@octokit/openapi-types": "^17.2.0"
       }
     },
     "node_modules/@octokit/webhooks": {
@@ -3522,9 +3528,9 @@
       "peer": true
     },
     "node_modules/@puppeteer/browsers": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.0.1.tgz",
-      "integrity": "sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.2.0.tgz",
+      "integrity": "sha512-F2ygRTaNKq2HQQGsvypvy2S/Dg7aqqp2zxv4uolkxxTQvdbYfI0DcLPFNdqenaC+rZX5ldSPs/s39yAPpTVZ0A==",
       "dev": true,
       "dependencies": {
         "debug": "4.3.4",
@@ -4390,9 +4396,9 @@
       "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
     },
     "node_modules/@types/node": {
-      "version": "20.1.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.5.tgz",
-      "integrity": "sha512-IvGD1CD/nego63ySR7vrAKEX3AJTcmrAN2kn+/sDNLi1Ff5kBzDeEdqWDplK+0HAEoLYej137Sk0cUU8OLOlMg=="
+      "version": "20.2.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz",
+      "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw=="
     },
     "node_modules/@types/node-fetch": {
       "version": "2.6.3",
@@ -5330,13 +5336,13 @@
       }
     },
     "node_modules/@vitest/expect": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.0.tgz",
-      "integrity": "sha512-Jlm8ZTyp6vMY9iz9Ny9a0BHnCG4fqBa8neCF6Pk/c/6vkUk49Ls6UBlgGAU82QnzzoaUs9E/mUhq/eq9uMOv/g==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.1.tgz",
+      "integrity": "sha512-BV1LyNvhnX+eNYzJxlHIGPWZpwJFZaCcOIzp2CNG0P+bbetenTupk6EO0LANm4QFt0TTit+yqx7Rxd1qxi/SQA==",
       "dev": true,
       "dependencies": {
-        "@vitest/spy": "0.31.0",
-        "@vitest/utils": "0.31.0",
+        "@vitest/spy": "0.31.1",
+        "@vitest/utils": "0.31.1",
         "chai": "^4.3.7"
       },
       "funding": {
@@ -5344,12 +5350,12 @@
       }
     },
     "node_modules/@vitest/runner": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.0.tgz",
-      "integrity": "sha512-H1OE+Ly7JFeBwnpHTrKyCNm/oZgr+16N4qIlzzqSG/YRQDATBYmJb/KUn3GrZaiQQyL7GwpNHVZxSQd6juLCgw==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.1.tgz",
+      "integrity": "sha512-imWuc82ngOtxdCUpXwtEzZIuc1KMr+VlQ3Ondph45VhWoQWit5yvG/fFcldbnCi8DUuFi+NmNx5ehMUw/cGLUw==",
       "dev": true,
       "dependencies": {
-        "@vitest/utils": "0.31.0",
+        "@vitest/utils": "0.31.1",
         "concordance": "^5.0.4",
         "p-limit": "^4.0.0",
         "pathe": "^1.1.0"
@@ -5386,9 +5392,9 @@
       }
     },
     "node_modules/@vitest/snapshot": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.0.tgz",
-      "integrity": "sha512-5dTXhbHnyUMTMOujZPB0wjFjQ6q5x9c8TvAsSPUNKjp1tVU7i9pbqcKPqntyu2oXtmVxKbuHCqrOd+Ft60r4tg==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.1.tgz",
+      "integrity": "sha512-L3w5uU9bMe6asrNzJ8WZzN+jUTX4KSgCinEJPXyny0o90fG4FPQMV0OWsq7vrCWfQlAilMjDnOF9nP8lidsJ+g==",
       "dev": true,
       "dependencies": {
         "magic-string": "^0.30.0",
@@ -5432,9 +5438,9 @@
       "dev": true
     },
     "node_modules/@vitest/spy": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.0.tgz",
-      "integrity": "sha512-IzCEQ85RN26GqjQNkYahgVLLkULOxOm5H/t364LG0JYb3Apg0PsYCHLBYGA006+SVRMWhQvHlBBCyuByAMFmkg==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.1.tgz",
+      "integrity": "sha512-1cTpt2m9mdo3hRLDyCG2hDQvRrePTDgEJBFQQNz1ydHHZy03EiA6EpFxY+7ODaY7vMRCie+WlFZBZ0/dQWyssQ==",
       "dev": true,
       "dependencies": {
         "tinyspy": "^2.1.0"
@@ -5444,9 +5450,9 @@
       }
     },
     "node_modules/@vitest/utils": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.0.tgz",
-      "integrity": "sha512-kahaRyLX7GS1urekRXN2752X4gIgOGVX4Wo8eDUGUkTWlGpXzf5ZS6N9RUUS+Re3XEE8nVGqNyxkSxF5HXlGhQ==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.1.tgz",
+      "integrity": "sha512-yFyRD5ilwojsZfo3E0BnH72pSVSuLg2356cN1tCEe/0RtDzxTPYwOomIC+eQbot7m6DRy4tPZw+09mB7NkbMmA==",
       "dev": true,
       "dependencies": {
         "concordance": "^5.0.4",
@@ -5642,6 +5648,64 @@
         "node": "^16.13 || >=18"
       }
     },
+    "node_modules/@wdio/cli/node_modules/@puppeteer/browsers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.0.1.tgz",
+      "integrity": "sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==",
+      "dev": true,
+      "dependencies": {
+        "debug": "4.3.4",
+        "extract-zip": "2.0.1",
+        "http-proxy-agent": "5.0.0",
+        "https-proxy-agent": "5.0.1",
+        "progress": "2.0.3",
+        "proxy-from-env": "1.1.0",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "yargs": "17.7.1"
+      },
+      "bin": {
+        "browsers": "lib/cjs/main-cli.js"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      },
+      "peerDependencies": {
+        "typescript": ">= 4.7.4"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/@puppeteer/browsers/node_modules/yargs": {
+      "version": "17.7.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+      "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/@tootallnate/once": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/@wdio/cli/node_modules/chalk": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz",
@@ -5654,6 +5718,196 @@
         "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
+    "node_modules/@wdio/cli/node_modules/devtools": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.2.tgz",
+      "integrity": "sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0",
+        "@wdio/config": "8.10.2",
+        "@wdio/logger": "8.6.6",
+        "@wdio/protocols": "8.10.2",
+        "@wdio/types": "8.10.2",
+        "@wdio/utils": "8.10.2",
+        "chrome-launcher": "^0.15.0",
+        "edge-paths": "^3.0.5",
+        "import-meta-resolve": "^3.0.0",
+        "puppeteer-core": "20.1.1",
+        "query-selector-shadow-dom": "^1.0.0",
+        "ua-parser-js": "^1.0.1",
+        "uuid": "^9.0.0",
+        "which": "^3.0.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/devtools-protocol": {
+      "version": "0.0.1138159",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1138159.tgz",
+      "integrity": "sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==",
+      "dev": true
+    },
+    "node_modules/@wdio/cli/node_modules/http-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+      "dev": true,
+      "dependencies": {
+        "@tootallnate/once": "2",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/minimatch": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/puppeteer-core": {
+      "version": "20.1.1",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.1.1.tgz",
+      "integrity": "sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==",
+      "dev": true,
+      "dependencies": {
+        "@puppeteer/browsers": "1.0.1",
+        "chromium-bidi": "0.4.7",
+        "cross-fetch": "3.1.5",
+        "debug": "4.3.4",
+        "devtools-protocol": "0.0.1120988",
+        "extract-zip": "2.0.1",
+        "https-proxy-agent": "5.0.1",
+        "proxy-from-env": "1.1.0",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "ws": "8.13.0"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      },
+      "peerDependencies": {
+        "typescript": ">= 4.7.4"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/puppeteer-core/node_modules/devtools-protocol": {
+      "version": "0.0.1120988",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz",
+      "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==",
+      "dev": true
+    },
+    "node_modules/@wdio/cli/node_modules/webdriver": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.2.tgz",
+      "integrity": "sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0",
+        "@types/ws": "^8.5.3",
+        "@wdio/config": "8.10.2",
+        "@wdio/logger": "8.6.6",
+        "@wdio/protocols": "8.10.2",
+        "@wdio/types": "8.10.2",
+        "@wdio/utils": "8.10.2",
+        "deepmerge-ts": "^5.0.0",
+        "got": "^12.1.0",
+        "ky": "^0.33.0",
+        "ws": "^8.8.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/webdriverio": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.2.tgz",
+      "integrity": "sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0",
+        "@wdio/config": "8.10.2",
+        "@wdio/logger": "8.6.6",
+        "@wdio/protocols": "8.10.2",
+        "@wdio/repl": "8.10.1",
+        "@wdio/types": "8.10.2",
+        "@wdio/utils": "8.10.2",
+        "archiver": "^5.0.0",
+        "aria-query": "^5.0.0",
+        "css-shorthand-properties": "^1.1.1",
+        "css-value": "^0.0.1",
+        "devtools": "8.10.2",
+        "devtools-protocol": "^0.0.1138159",
+        "grapheme-splitter": "^1.0.2",
+        "import-meta-resolve": "^3.0.0",
+        "is-plain-obj": "^4.1.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.zip": "^4.2.0",
+        "minimatch": "^9.0.0",
+        "puppeteer-core": "20.1.1",
+        "query-selector-shadow-dom": "^1.0.0",
+        "resq": "^1.9.1",
+        "rgb2hex": "0.2.5",
+        "serialize-error": "^8.0.0",
+        "webdriver": "8.10.2"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/which": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+      "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/@wdio/cli/node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/@wdio/config": {
       "version": "8.10.2",
       "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.2.tgz",
@@ -5760,17 +6014,279 @@
         "webdriverio": "8.10.2"
       }
     },
-    "node_modules/@wdio/local-runner": {
+    "node_modules/@wdio/globals/node_modules/@puppeteer/browsers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.0.1.tgz",
+      "integrity": "sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "debug": "4.3.4",
+        "extract-zip": "2.0.1",
+        "http-proxy-agent": "5.0.0",
+        "https-proxy-agent": "5.0.1",
+        "progress": "2.0.3",
+        "proxy-from-env": "1.1.0",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "yargs": "17.7.1"
+      },
+      "bin": {
+        "browsers": "lib/cjs/main-cli.js"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      },
+      "peerDependencies": {
+        "typescript": ">= 4.7.4"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/@tootallnate/once": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/devtools": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.2.tgz",
+      "integrity": "sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/node": "^20.1.0",
+        "@wdio/config": "8.10.2",
+        "@wdio/logger": "8.6.6",
+        "@wdio/protocols": "8.10.2",
+        "@wdio/types": "8.10.2",
+        "@wdio/utils": "8.10.2",
+        "chrome-launcher": "^0.15.0",
+        "edge-paths": "^3.0.5",
+        "import-meta-resolve": "^3.0.0",
+        "puppeteer-core": "20.1.1",
+        "query-selector-shadow-dom": "^1.0.0",
+        "ua-parser-js": "^1.0.1",
+        "uuid": "^9.0.0",
+        "which": "^3.0.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/devtools-protocol": {
+      "version": "0.0.1138159",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1138159.tgz",
+      "integrity": "sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/@wdio/globals/node_modules/http-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@tootallnate/once": "2",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/is-plain-obj": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+      "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/minimatch": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/puppeteer-core": {
+      "version": "20.1.1",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.1.1.tgz",
+      "integrity": "sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@puppeteer/browsers": "1.0.1",
+        "chromium-bidi": "0.4.7",
+        "cross-fetch": "3.1.5",
+        "debug": "4.3.4",
+        "devtools-protocol": "0.0.1120988",
+        "extract-zip": "2.0.1",
+        "https-proxy-agent": "5.0.1",
+        "proxy-from-env": "1.1.0",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "ws": "8.13.0"
+      },
+      "engines": {
+        "node": ">=16.0.0"
+      },
+      "peerDependencies": {
+        "typescript": ">= 4.7.4"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/puppeteer-core/node_modules/devtools-protocol": {
+      "version": "0.0.1120988",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz",
+      "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/@wdio/globals/node_modules/webdriver": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.2.tgz",
+      "integrity": "sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "@types/node": "^20.1.0",
+        "@types/ws": "^8.5.3",
+        "@wdio/config": "8.10.2",
+        "@wdio/logger": "8.6.6",
+        "@wdio/protocols": "8.10.2",
+        "@wdio/types": "8.10.2",
+        "@wdio/utils": "8.10.2",
+        "deepmerge-ts": "^5.0.0",
+        "got": "^12.1.0",
+        "ky": "^0.33.0",
+        "ws": "^8.8.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/webdriverio": {
       "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.10.2.tgz",
-      "integrity": "sha512-f9XkFe09KqhtabuvbJIMs95138Jo8eCp+MbG3/zy789kD4Y2yndkmcmtthI75H2VuT+zwmiwtBp9pSnGQkBrOw==",
+      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.2.tgz",
+      "integrity": "sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==",
       "dev": true,
+      "optional": true,
       "dependencies": {
         "@types/node": "^20.1.0",
+        "@wdio/config": "8.10.2",
         "@wdio/logger": "8.6.6",
+        "@wdio/protocols": "8.10.2",
         "@wdio/repl": "8.10.1",
-        "@wdio/runner": "8.10.2",
         "@wdio/types": "8.10.2",
+        "@wdio/utils": "8.10.2",
+        "archiver": "^5.0.0",
+        "aria-query": "^5.0.0",
+        "css-shorthand-properties": "^1.1.1",
+        "css-value": "^0.0.1",
+        "devtools": "8.10.2",
+        "devtools-protocol": "^0.0.1138159",
+        "grapheme-splitter": "^1.0.2",
+        "import-meta-resolve": "^3.0.0",
+        "is-plain-obj": "^4.1.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.zip": "^4.2.0",
+        "minimatch": "^9.0.0",
+        "puppeteer-core": "20.1.1",
+        "query-selector-shadow-dom": "^1.0.0",
+        "resq": "^1.9.1",
+        "rgb2hex": "0.2.5",
+        "serialize-error": "^8.0.0",
+        "webdriver": "8.10.2"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/which": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+      "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/which.js"
+      },
+      "engines": {
+        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/yargs": {
+      "version": "17.7.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+      "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+      "dev": true,
+      "optional": true,
+      "dependencies": {
+        "cliui": "^8.0.1",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.3",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^21.1.1"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@wdio/globals/node_modules/yargs-parser": {
+      "version": "21.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+      "dev": true,
+      "optional": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@wdio/local-runner": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.10.4.tgz",
+      "integrity": "sha512-zCDmKLdKQVInG4KABU1Y2lZS7k/QSh54JMYsTqTy0NWD0b48kZOM6sUWP4mub/njTinnKKvzXbwmrehl2Ij0SA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0",
+        "@wdio/logger": "8.6.6",
+        "@wdio/repl": "8.10.1",
+        "@wdio/runner": "8.10.4",
+        "@wdio/types": "8.10.4",
         "async-exit-hook": "^2.0.1",
         "split2": "^4.1.0",
         "stream-buffers": "^3.0.2"
@@ -5779,6 +6295,18 @@
         "node": "^16.13 || >=18"
       }
     },
+    "node_modules/@wdio/local-runner/node_modules/@wdio/types": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+      "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
     "node_modules/@wdio/logger": {
       "version": "8.6.6",
       "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.6.6.tgz",
@@ -5807,22 +6335,49 @@
       }
     },
     "node_modules/@wdio/mocha-framework": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.10.2.tgz",
-      "integrity": "sha512-qD8wGJWCXDXMiH917aAzZaOfWavgI2H9SjrNjSHbE8BEZSd9cX43zTo5ZBsqY0JEWD0Ihz32iOyTCvRNynUImA==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.10.4.tgz",
+      "integrity": "sha512-RJPFFfGeDrFChOg22wqzSPp40CUKpAeThzA2oS2REPLyzxmyKAR6m3/wxcOrqtQPVBhuW8ZycOHu4z7WBlYdXg==",
       "dev": true,
       "dependencies": {
         "@types/mocha": "^10.0.0",
         "@types/node": "^20.1.0",
         "@wdio/logger": "8.6.6",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "mocha": "^10.0.0"
       },
       "engines": {
         "node": "^16.13 || >=18"
       }
     },
+    "node_modules/@wdio/mocha-framework/node_modules/@wdio/types": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+      "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/mocha-framework/node_modules/@wdio/utils": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+      "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "import-meta-resolve": "^3.0.0",
+        "p-iteration": "^1.1.8"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
     "node_modules/@wdio/protocols": {
       "version": "8.10.2",
       "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.10.2.tgz",
@@ -5859,27 +6414,160 @@
       }
     },
     "node_modules/@wdio/runner": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.10.2.tgz",
-      "integrity": "sha512-xPDiTjPLS49dPYiHSrHe94sLIaivdGGIsaeuflzV3Ow7RUudUEiaj1XUc0/znJHmNJJF1MHyZgV+9NJRtQJK8Q==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.10.4.tgz",
+      "integrity": "sha512-/8zGiZed1CMyK3UtmHxDC/TjVQnUplly70fTPxfrn/ckZXXqRn9+4/ScOJ+hgaYfEzobf9gFVudY4pGcyzXC/Q==",
       "dev": true,
       "dependencies": {
         "@types/node": "^20.1.0",
-        "@wdio/config": "8.10.2",
-        "@wdio/globals": "8.10.2",
+        "@wdio/config": "8.10.4",
+        "@wdio/globals": "8.10.4",
         "@wdio/logger": "8.6.6",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "deepmerge-ts": "^5.0.0",
         "expect-webdriverio": "^4.0.1",
         "gaze": "^1.1.2",
-        "webdriver": "8.10.2",
-        "webdriverio": "8.10.2"
+        "webdriver": "8.10.4",
+        "webdriverio": "8.10.4"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/@wdio/config": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+      "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
+        "decamelize": "^6.0.0",
+        "deepmerge-ts": "^5.0.0",
+        "glob": "^10.2.2",
+        "import-meta-resolve": "^3.0.0",
+        "read-pkg-up": "^9.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/@wdio/globals": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.10.4.tgz",
+      "integrity": "sha512-+/LujjcieK9p6qBWRKHuNCt9ih/nsYx0beqV1FvRJwCoZ7mxShvM+UAmOaJkJRJ+9hOPRKF7K5suBEBS9QW9Wg==",
+      "dev": true,
+      "engines": {
+        "node": "^16.13 || >=18"
+      },
+      "optionalDependencies": {
+        "expect-webdriverio": "^4.0.1",
+        "webdriverio": "8.10.4"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/@wdio/types": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+      "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/@wdio/utils": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+      "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "import-meta-resolve": "^3.0.0",
+        "p-iteration": "^1.1.8"
       },
       "engines": {
         "node": "^16.13 || >=18"
       }
     },
+    "node_modules/@wdio/runner/node_modules/foreground-child": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+      "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/glob": {
+      "version": "10.2.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+      "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+      "dev": true,
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^2.0.3",
+        "minimatch": "^9.0.1",
+        "minipass": "^5.0.0 || ^6.0.2",
+        "path-scurry": "^1.7.0"
+      },
+      "bin": {
+        "glob": "dist/cjs/src/bin.js"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/minimatch": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/minipass": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+      "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/@wdio/runner/node_modules/signal-exit": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+      "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/@wdio/spec-reporter": {
       "version": "8.10.2",
       "resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.10.2.tgz",
@@ -9067,21 +9755,21 @@
       }
     },
     "node_modules/devtools": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.2.tgz",
-      "integrity": "sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.4.tgz",
+      "integrity": "sha512-OVvT1KabSgSsxppWvM4C7e1TcVmbOn6Px5DcP2DGQ0h2YOWeawqHRdA7TFCBhrToWqhleCbfUBjtea8V4fI2GQ==",
       "dev": true,
       "dependencies": {
         "@types/node": "^20.1.0",
-        "@wdio/config": "8.10.2",
+        "@wdio/config": "8.10.4",
         "@wdio/logger": "8.6.6",
         "@wdio/protocols": "8.10.2",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "chrome-launcher": "^0.15.0",
         "edge-paths": "^3.0.5",
         "import-meta-resolve": "^3.0.0",
-        "puppeteer-core": "20.1.1",
+        "puppeteer-core": "20.2.0",
         "query-selector-shadow-dom": "^1.0.0",
         "ua-parser-js": "^1.0.1",
         "uuid": "^9.0.0",
@@ -9092,11 +9780,131 @@
       }
     },
     "node_modules/devtools-protocol": {
-      "version": "0.0.1138159",
-      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1138159.tgz",
-      "integrity": "sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==",
+      "version": "0.0.1143632",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1143632.tgz",
+      "integrity": "sha512-QYlQucMwbsBVGKkC4+IdClQYG1FbDrm/0N0kwYiC8DUxuygkyA1RUe7dmM+iCZkQQMaPWmBmilYkNbJweWEuhA==",
       "dev": true
     },
+    "node_modules/devtools/node_modules/@wdio/config": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+      "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
+        "decamelize": "^6.0.0",
+        "deepmerge-ts": "^5.0.0",
+        "glob": "^10.2.2",
+        "import-meta-resolve": "^3.0.0",
+        "read-pkg-up": "^9.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/devtools/node_modules/@wdio/types": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+      "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/devtools/node_modules/@wdio/utils": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+      "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "import-meta-resolve": "^3.0.0",
+        "p-iteration": "^1.1.8"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/devtools/node_modules/foreground-child": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+      "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/devtools/node_modules/glob": {
+      "version": "10.2.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+      "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+      "dev": true,
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^2.0.3",
+        "minimatch": "^9.0.1",
+        "minipass": "^5.0.0 || ^6.0.2",
+        "path-scurry": "^1.7.0"
+      },
+      "bin": {
+        "glob": "dist/cjs/src/bin.js"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/devtools/node_modules/minimatch": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/devtools/node_modules/minipass": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+      "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/devtools/node_modules/signal-exit": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+      "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/devtools/node_modules/which": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
@@ -10348,15 +11156,15 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
-      "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
+      "version": "8.41.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
+      "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.4.0",
         "@eslint/eslintrc": "^2.0.3",
-        "@eslint/js": "8.40.0",
+        "@eslint/js": "8.41.0",
         "@humanwhocodes/config-array": "^0.11.8",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
@@ -10376,13 +11184,12 @@
         "find-up": "^5.0.0",
         "glob-parent": "^6.0.2",
         "globals": "^13.19.0",
-        "grapheme-splitter": "^1.0.4",
+        "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-sdsl": "^4.1.4",
         "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
@@ -11419,9 +12226,9 @@
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
     },
     "node_modules/fast-diff": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
-      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+      "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
       "dev": true
     },
     "node_modules/fast-glob": {
@@ -12593,6 +13400,12 @@
       "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
       "dev": true
     },
+    "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/gunzip-maybe": {
       "version": "1.4.2",
       "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz",
@@ -14335,16 +15148,6 @@
         "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
-    "node_modules/js-sdsl": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
-      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
-      "dev": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/js-sdsl"
-      }
-    },
     "node_modules/js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -14681,9 +15484,9 @@
       }
     },
     "node_modules/lighthouse-logger": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz",
-      "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
+      "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==",
       "dev": true,
       "dependencies": {
         "debug": "^2.6.9",
@@ -16913,18 +17716,18 @@
       "dev": true
     },
     "node_modules/octokit": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.14.tgz",
-      "integrity": "sha512-z6cgZBFxirpFEQ1La8Lg83GCs5hOV2EPpkYYdjsGNbfQMv8qUGjq294MiRBCbZqLufviakGsPUxaNKe3JrPmsA==",
+      "version": "2.0.16",
+      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.16.tgz",
+      "integrity": "sha512-n7lqH8wkvBRzjzdWGUKZjFYEbGnLjcv5+eS6W6LXGXrXEZbJwQ8WpADMYKbTL0LdOeXdvmpf9DTtpPk0cXndBg==",
       "dependencies": {
-        "@octokit/app": "^13.1.1",
-        "@octokit/core": "^4.0.4",
-        "@octokit/oauth-app": "^4.0.6",
-        "@octokit/plugin-paginate-rest": "^6.0.0",
-        "@octokit/plugin-rest-endpoint-methods": "^7.0.0",
-        "@octokit/plugin-retry": "^4.0.3",
-        "@octokit/plugin-throttling": "^5.0.0",
-        "@octokit/types": "^9.0.0"
+        "@octokit/app": "^13.1.3",
+        "@octokit/core": "^4.2.1",
+        "@octokit/oauth-app": "^4.2.1",
+        "@octokit/plugin-paginate-rest": "^6.1.0",
+        "@octokit/plugin-rest-endpoint-methods": "^7.1.1",
+        "@octokit/plugin-retry": "^4.1.3",
+        "@octokit/plugin-throttling": "^5.2.2",
+        "@octokit/types": "^9.2.2"
       },
       "engines": {
         "node": ">= 14"
@@ -17870,9 +18673,9 @@
       }
     },
     "node_modules/preact": {
-      "version": "10.14.1",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.14.1.tgz",
-      "integrity": "sha512-4XDSnUisk3YFBb3p9WeKeH1mKoxdFUsaXcvxs9wlpYR1wax/TWJVqhwmIWbByX0h7jMEJH6Zc5J6jqc58FKaNQ==",
+      "version": "10.15.0",
+      "resolved": "https://registry.npmjs.org/preact/-/preact-10.15.0.tgz",
+      "integrity": "sha512-nZSa8M2R2m1n7nJSBlzDpxRJaIsejrTO1vlFbdpFvyC8qM1iU+On2y0otfoUm6SRB5o0lF0CKDFxg6grEFU0iQ==",
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/preact"
@@ -18139,21 +18942,16 @@
       }
     },
     "node_modules/puppeteer-core": {
-      "version": "20.1.1",
-      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.1.1.tgz",
-      "integrity": "sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==",
+      "version": "20.2.0",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.2.0.tgz",
+      "integrity": "sha512-QKLu4ELW/609vlLqp/NvQA564LzvLaF6x1ZH+4BhPhxPgreoY8WR/AYOzXS12hgtPPjNCqPKiRLxmyXGnlIK8A==",
       "dev": true,
       "dependencies": {
-        "@puppeteer/browsers": "1.0.1",
+        "@puppeteer/browsers": "1.2.0",
         "chromium-bidi": "0.4.7",
         "cross-fetch": "3.1.5",
         "debug": "4.3.4",
         "devtools-protocol": "0.0.1120988",
-        "extract-zip": "2.0.1",
-        "https-proxy-agent": "5.0.1",
-        "proxy-from-env": "1.1.0",
-        "tar-fs": "2.1.1",
-        "unbzip2-stream": "1.4.3",
         "ws": "8.13.0"
       },
       "engines": {
@@ -21978,19 +22776,19 @@
       }
     },
     "node_modules/vitest": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.0.tgz",
-      "integrity": "sha512-JwWJS9p3GU9GxkG7eBSmr4Q4x4bvVBSswaCFf1PBNHiPx00obfhHRJfgHcnI0ffn+NMlIh9QGvG75FlaIBdKGA==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.1.tgz",
+      "integrity": "sha512-/dOoOgzoFk/5pTvg1E65WVaobknWREN15+HF+0ucudo3dDG/vCZoXTQrjIfEaWvQXmqScwkRodrTbM/ScMpRcQ==",
       "dev": true,
       "dependencies": {
-        "@types/chai": "^4.3.4",
+        "@types/chai": "^4.3.5",
         "@types/chai-subset": "^1.3.3",
         "@types/node": "*",
-        "@vitest/expect": "0.31.0",
-        "@vitest/runner": "0.31.0",
-        "@vitest/snapshot": "0.31.0",
-        "@vitest/spy": "0.31.0",
-        "@vitest/utils": "0.31.0",
+        "@vitest/expect": "0.31.1",
+        "@vitest/runner": "0.31.1",
+        "@vitest/snapshot": "0.31.1",
+        "@vitest/spy": "0.31.1",
+        "@vitest/utils": "0.31.1",
         "acorn": "^8.8.2",
         "acorn-walk": "^8.2.0",
         "cac": "^6.7.14",
@@ -22003,10 +22801,10 @@
         "picocolors": "^1.0.0",
         "std-env": "^3.3.2",
         "strip-literal": "^1.0.1",
-        "tinybench": "^2.4.0",
+        "tinybench": "^2.5.0",
         "tinypool": "^0.5.0",
         "vite": "^3.0.0 || ^4.0.0",
-        "vite-node": "0.31.0",
+        "vite-node": "0.31.1",
         "why-is-node-running": "^2.2.2"
       },
       "bin": {
@@ -22056,9 +22854,9 @@
       }
     },
     "node_modules/vitest/node_modules/vite-node": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.0.tgz",
-      "integrity": "sha512-8x1x1LNuPvE2vIvkSB7c1mApX5oqlgsxzHQesYF7l5n1gKrEmrClIiZuOFbFDQcjLsmcWSwwmrWrcGWm9Fxc/g==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.1.tgz",
+      "integrity": "sha512-BajE/IsNQ6JyizPzu9zRgHrBwczkAs0erQf/JRpgTIESpKvNj9/Gd0vxX905klLkb0I0SJVCKbdrl5c6FnqYKA==",
       "dev": true,
       "dependencies": {
         "cac": "^6.7.14",
@@ -22274,18 +23072,18 @@
       "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
     },
     "node_modules/webdriver": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.2.tgz",
-      "integrity": "sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.4.tgz",
+      "integrity": "sha512-Dvv6LzylhbXN16roQuKzG2W+/IyTLKWFz4tzkwXotd48CAkdy8d2Ds0gVcwo8JpyZQweEKylGdvNC3W50aPLMQ==",
       "dev": true,
       "dependencies": {
         "@types/node": "^20.1.0",
         "@types/ws": "^8.5.3",
-        "@wdio/config": "8.10.2",
+        "@wdio/config": "8.10.4",
         "@wdio/logger": "8.6.6",
         "@wdio/protocols": "8.10.2",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "deepmerge-ts": "^5.0.0",
         "got": "^12.1.0",
         "ky": "^0.33.0",
@@ -22295,42 +23093,246 @@
         "node": "^16.13 || >=18"
       }
     },
+    "node_modules/webdriver/node_modules/@wdio/config": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+      "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
+        "decamelize": "^6.0.0",
+        "deepmerge-ts": "^5.0.0",
+        "glob": "^10.2.2",
+        "import-meta-resolve": "^3.0.0",
+        "read-pkg-up": "^9.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/webdriver/node_modules/@wdio/types": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+      "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/webdriver/node_modules/@wdio/utils": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+      "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "import-meta-resolve": "^3.0.0",
+        "p-iteration": "^1.1.8"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/webdriver/node_modules/foreground-child": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+      "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/webdriver/node_modules/glob": {
+      "version": "10.2.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+      "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+      "dev": true,
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^2.0.3",
+        "minimatch": "^9.0.1",
+        "minipass": "^5.0.0 || ^6.0.2",
+        "path-scurry": "^1.7.0"
+      },
+      "bin": {
+        "glob": "dist/cjs/src/bin.js"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/webdriver/node_modules/minimatch": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/webdriver/node_modules/minipass": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+      "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/webdriver/node_modules/signal-exit": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+      "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/webdriverio": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.2.tgz",
-      "integrity": "sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.4.tgz",
+      "integrity": "sha512-5PcAIxf+hBj6JKub/5OXhgJncHgMQrRH3bdpfvOOeLSk26DVRNAcBOOSFOJX+l/Vef0Tqyw/NgSlSbY0x4PUgQ==",
       "dev": true,
       "dependencies": {
         "@types/node": "^20.1.0",
-        "@wdio/config": "8.10.2",
+        "@wdio/config": "8.10.4",
         "@wdio/logger": "8.6.6",
         "@wdio/protocols": "8.10.2",
         "@wdio/repl": "8.10.1",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "archiver": "^5.0.0",
         "aria-query": "^5.0.0",
         "css-shorthand-properties": "^1.1.1",
         "css-value": "^0.0.1",
-        "devtools": "8.10.2",
-        "devtools-protocol": "^0.0.1138159",
+        "devtools": "8.10.4",
+        "devtools-protocol": "^0.0.1143632",
         "grapheme-splitter": "^1.0.2",
         "import-meta-resolve": "^3.0.0",
         "is-plain-obj": "^4.1.0",
         "lodash.clonedeep": "^4.5.0",
         "lodash.zip": "^4.2.0",
         "minimatch": "^9.0.0",
-        "puppeteer-core": "20.1.1",
+        "puppeteer-core": "20.2.0",
         "query-selector-shadow-dom": "^1.0.0",
         "resq": "^1.9.1",
         "rgb2hex": "0.2.5",
         "serialize-error": "^8.0.0",
-        "webdriver": "8.10.2"
+        "webdriver": "8.10.4"
       },
       "engines": {
         "node": "^16.13 || >=18"
       }
     },
+    "node_modules/webdriverio/node_modules/@wdio/config": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+      "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
+        "decamelize": "^6.0.0",
+        "deepmerge-ts": "^5.0.0",
+        "glob": "^10.2.2",
+        "import-meta-resolve": "^3.0.0",
+        "read-pkg-up": "^9.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/webdriverio/node_modules/@wdio/types": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+      "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "^20.1.0"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/webdriverio/node_modules/@wdio/utils": {
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+      "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+      "dev": true,
+      "dependencies": {
+        "@wdio/logger": "8.6.6",
+        "@wdio/types": "8.10.4",
+        "import-meta-resolve": "^3.0.0",
+        "p-iteration": "^1.1.8"
+      },
+      "engines": {
+        "node": "^16.13 || >=18"
+      }
+    },
+    "node_modules/webdriverio/node_modules/foreground-child": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+      "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/webdriverio/node_modules/glob": {
+      "version": "10.2.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+      "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+      "dev": true,
+      "dependencies": {
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^2.0.3",
+        "minimatch": "^9.0.1",
+        "minipass": "^5.0.0 || ^6.0.2",
+        "path-scurry": "^1.7.0"
+      },
+      "bin": {
+        "glob": "dist/cjs/src/bin.js"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/webdriverio/node_modules/is-plain-obj": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
@@ -22344,9 +23346,9 @@
       }
     },
     "node_modules/webdriverio/node_modules/minimatch": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
-      "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+      "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
       "dev": true,
       "dependencies": {
         "brace-expansion": "^2.0.1"
@@ -22358,6 +23360,27 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/webdriverio/node_modules/minipass": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+      "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/webdriverio/node_modules/signal-exit": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+      "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/webidl-conversions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -24673,8 +25696,8 @@
       "requires": {}
     },
     "@buf/stateful_runme.community_timostamm-protobuf-ts": {
-      "version": "2.9.0-20230419234326-3a45ee6262e7.1",
-      "resolved": "https://buf.build/gen/npm/v1/@buf/stateful_runme.community_timostamm-protobuf-ts/-/stateful_runme.community_timostamm-protobuf-ts-2.9.0-20230419234326-3a45ee6262e7.1.tgz",
+      "version": "2.9.0-20230522162609-549daeeacece.1",
+      "resolved": "https://buf.build/gen/npm/v1/@buf/stateful_runme.community_timostamm-protobuf-ts/-/stateful_runme.community_timostamm-protobuf-ts-2.9.0-20230522162609-549daeeacece.1.tgz",
       "requires": {}
     },
     "@cspotcode/source-map-support": {
@@ -24915,9 +25938,9 @@
       }
     },
     "@eslint/js": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
-      "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
+      "version": "8.41.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
+      "integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
       "dev": true
     },
     "@fastify/accept-negotiator": {
@@ -25595,9 +26618,9 @@
       }
     },
     "@octokit/core": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
-      "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz",
+      "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==",
       "requires": {
         "@octokit/auth-token": "^3.0.0",
         "@octokit/graphql": "^5.0.0",
@@ -25667,11 +26690,12 @@
       "integrity": "sha512-MazrFNx4plbLsGl+LFesMo96eIXkFgEtaKbnNpdh4aQ0VM10aoylFsTYP1AEjkeoRNZiiPe3T6Gl2Hr8dJWdlQ=="
     },
     "@octokit/plugin-paginate-rest": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.0.tgz",
-      "integrity": "sha512-5T4iXjJdYCVA1rdWS1C+uZV9AvtZY9QgTG74kFiSFVj94dZXowyi/YK8f4SGjZaL69jZthGlBaDKRdCMCF9log==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
+      "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
       "requires": {
-        "@octokit/types": "^9.2.2"
+        "@octokit/tsconfig": "^1.0.2",
+        "@octokit/types": "^9.2.3"
       }
     },
     "@octokit/plugin-request-log": {
@@ -25682,11 +26706,11 @@
       "requires": {}
     },
     "@octokit/plugin-rest-endpoint-methods": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.0.tgz",
-      "integrity": "sha512-SWwz/hc47GaKJR6BlJI4WIVRodbAFRvrR0QRPSoPMs7krb7anYPML3psg+ThEz/kcwOdSNh/oA8qThi/Wvs4Fw==",
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.1.2.tgz",
+      "integrity": "sha512-R0oJ7j6f/AdqPLtB9qRXLO+wjI9pctUn8Ka8UGfGaFCcCv3Otx14CshQ89K4E88pmyYZS8p0rNTiprML/81jig==",
       "requires": {
-        "@octokit/types": "^9.2.2",
+        "@octokit/types": "^9.2.3",
         "deprecation": "^2.3.1"
       }
     },
@@ -25700,9 +26724,9 @@
       }
     },
     "@octokit/plugin-throttling": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.0.tgz",
-      "integrity": "sha512-qWYvVIS1aRC3hN4a0ICWUp51IolHIn7E4iri2AKjbExJaovMDvRtae4nGoxG5pP6+WATk7JZ5epOJobFbGYV1w==",
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz",
+      "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==",
       "requires": {
         "@octokit/types": "^9.0.0",
         "bottleneck": "^2.15.3"
@@ -25732,23 +26756,28 @@
       }
     },
     "@octokit/rest": {
-      "version": "19.0.8",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.8.tgz",
-      "integrity": "sha512-/PKrzqn+zDzXKwBMwLI2IKrvk8yv8cedJOdcmxrjR3gmu6UIzURhP5oQj+4qkn7+uQi1gg7QqV4SqlaQ1HYW1Q==",
+      "version": "19.0.11",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz",
+      "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==",
       "dev": true,
       "requires": {
-        "@octokit/core": "^4.1.0",
-        "@octokit/plugin-paginate-rest": "^6.1.0",
+        "@octokit/core": "^4.2.1",
+        "@octokit/plugin-paginate-rest": "^6.1.2",
         "@octokit/plugin-request-log": "^1.0.4",
-        "@octokit/plugin-rest-endpoint-methods": "^7.1.0"
+        "@octokit/plugin-rest-endpoint-methods": "^7.1.2"
       }
     },
+    "@octokit/tsconfig": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz",
+      "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA=="
+    },
     "@octokit/types": {
-      "version": "9.2.2",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.2.tgz",
-      "integrity": "sha512-9BjDxjgQIvCjNWZsbqyH5QC2Yni16oaE6xL+8SUBMzcYPF4TGQBXGA97Cl3KceK9mwiNMb1mOYCz6FbCCLEL+g==",
+      "version": "9.2.3",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.2.3.tgz",
+      "integrity": "sha512-MMeLdHyFIALioycq+LFcA71v0S2xpQUX2cw6pPbHQjaibcHYwLnmK/kMZaWuGfGfjBJZ3wRUq+dOaWsvrPJVvA==",
       "requires": {
-        "@octokit/openapi-types": "^17.1.2"
+        "@octokit/openapi-types": "^17.2.0"
       }
     },
     "@octokit/webhooks": {
@@ -25888,9 +26917,9 @@
       "peer": true
     },
     "@puppeteer/browsers": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.0.1.tgz",
-      "integrity": "sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.2.0.tgz",
+      "integrity": "sha512-F2ygRTaNKq2HQQGsvypvy2S/Dg7aqqp2zxv4uolkxxTQvdbYfI0DcLPFNdqenaC+rZX5ldSPs/s39yAPpTVZ0A==",
       "dev": true,
       "requires": {
         "debug": "4.3.4",
@@ -26569,9 +27598,9 @@
       "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
     },
     "@types/node": {
-      "version": "20.1.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.5.tgz",
-      "integrity": "sha512-IvGD1CD/nego63ySR7vrAKEX3AJTcmrAN2kn+/sDNLi1Ff5kBzDeEdqWDplK+0HAEoLYej137Sk0cUU8OLOlMg=="
+      "version": "20.2.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz",
+      "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw=="
     },
     "@types/node-fetch": {
       "version": "2.6.3",
@@ -27328,23 +28357,23 @@
       }
     },
     "@vitest/expect": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.0.tgz",
-      "integrity": "sha512-Jlm8ZTyp6vMY9iz9Ny9a0BHnCG4fqBa8neCF6Pk/c/6vkUk49Ls6UBlgGAU82QnzzoaUs9E/mUhq/eq9uMOv/g==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.31.1.tgz",
+      "integrity": "sha512-BV1LyNvhnX+eNYzJxlHIGPWZpwJFZaCcOIzp2CNG0P+bbetenTupk6EO0LANm4QFt0TTit+yqx7Rxd1qxi/SQA==",
       "dev": true,
       "requires": {
-        "@vitest/spy": "0.31.0",
-        "@vitest/utils": "0.31.0",
+        "@vitest/spy": "0.31.1",
+        "@vitest/utils": "0.31.1",
         "chai": "^4.3.7"
       }
     },
     "@vitest/runner": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.0.tgz",
-      "integrity": "sha512-H1OE+Ly7JFeBwnpHTrKyCNm/oZgr+16N4qIlzzqSG/YRQDATBYmJb/KUn3GrZaiQQyL7GwpNHVZxSQd6juLCgw==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.31.1.tgz",
+      "integrity": "sha512-imWuc82ngOtxdCUpXwtEzZIuc1KMr+VlQ3Ondph45VhWoQWit5yvG/fFcldbnCi8DUuFi+NmNx5ehMUw/cGLUw==",
       "dev": true,
       "requires": {
-        "@vitest/utils": "0.31.0",
+        "@vitest/utils": "0.31.1",
         "concordance": "^5.0.4",
         "p-limit": "^4.0.0",
         "pathe": "^1.1.0"
@@ -27368,9 +28397,9 @@
       }
     },
     "@vitest/snapshot": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.0.tgz",
-      "integrity": "sha512-5dTXhbHnyUMTMOujZPB0wjFjQ6q5x9c8TvAsSPUNKjp1tVU7i9pbqcKPqntyu2oXtmVxKbuHCqrOd+Ft60r4tg==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.31.1.tgz",
+      "integrity": "sha512-L3w5uU9bMe6asrNzJ8WZzN+jUTX4KSgCinEJPXyny0o90fG4FPQMV0OWsq7vrCWfQlAilMjDnOF9nP8lidsJ+g==",
       "dev": true,
       "requires": {
         "magic-string": "^0.30.0",
@@ -27404,18 +28433,18 @@
       }
     },
     "@vitest/spy": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.0.tgz",
-      "integrity": "sha512-IzCEQ85RN26GqjQNkYahgVLLkULOxOm5H/t364LG0JYb3Apg0PsYCHLBYGA006+SVRMWhQvHlBBCyuByAMFmkg==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.31.1.tgz",
+      "integrity": "sha512-1cTpt2m9mdo3hRLDyCG2hDQvRrePTDgEJBFQQNz1ydHHZy03EiA6EpFxY+7ODaY7vMRCie+WlFZBZ0/dQWyssQ==",
       "dev": true,
       "requires": {
         "tinyspy": "^2.1.0"
       }
     },
     "@vitest/utils": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.0.tgz",
-      "integrity": "sha512-kahaRyLX7GS1urekRXN2752X4gIgOGVX4Wo8eDUGUkTWlGpXzf5ZS6N9RUUS+Re3XEE8nVGqNyxkSxF5HXlGhQ==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.31.1.tgz",
+      "integrity": "sha512-yFyRD5ilwojsZfo3E0BnH72pSVSuLg2356cN1tCEe/0RtDzxTPYwOomIC+eQbot7m6DRy4tPZw+09mB7NkbMmA==",
       "dev": true,
       "requires": {
         "concordance": "^5.0.4",
@@ -27571,11 +28600,199 @@
         "yarn-install": "^1.0.0"
       },
       "dependencies": {
+        "@puppeteer/browsers": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.0.1.tgz",
+          "integrity": "sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==",
+          "dev": true,
+          "requires": {
+            "debug": "4.3.4",
+            "extract-zip": "2.0.1",
+            "http-proxy-agent": "5.0.0",
+            "https-proxy-agent": "5.0.1",
+            "progress": "2.0.3",
+            "proxy-from-env": "1.1.0",
+            "tar-fs": "2.1.1",
+            "unbzip2-stream": "1.4.3",
+            "yargs": "17.7.1"
+          },
+          "dependencies": {
+            "yargs": {
+              "version": "17.7.1",
+              "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+              "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+              "dev": true,
+              "requires": {
+                "cliui": "^8.0.1",
+                "escalade": "^3.1.1",
+                "get-caller-file": "^2.0.5",
+                "require-directory": "^2.1.1",
+                "string-width": "^4.2.3",
+                "y18n": "^5.0.5",
+                "yargs-parser": "^21.1.1"
+              }
+            }
+          }
+        },
+        "@tootallnate/once": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+          "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+          "dev": true
+        },
         "chalk": {
           "version": "5.2.0",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz",
           "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==",
           "dev": true
+        },
+        "devtools": {
+          "version": "8.10.2",
+          "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.2.tgz",
+          "integrity": "sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0",
+            "@wdio/config": "8.10.2",
+            "@wdio/logger": "8.6.6",
+            "@wdio/protocols": "8.10.2",
+            "@wdio/types": "8.10.2",
+            "@wdio/utils": "8.10.2",
+            "chrome-launcher": "^0.15.0",
+            "edge-paths": "^3.0.5",
+            "import-meta-resolve": "^3.0.0",
+            "puppeteer-core": "20.1.1",
+            "query-selector-shadow-dom": "^1.0.0",
+            "ua-parser-js": "^1.0.1",
+            "uuid": "^9.0.0",
+            "which": "^3.0.0"
+          }
+        },
+        "devtools-protocol": {
+          "version": "0.0.1138159",
+          "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1138159.tgz",
+          "integrity": "sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==",
+          "dev": true
+        },
+        "http-proxy-agent": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+          "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+          "dev": true,
+          "requires": {
+            "@tootallnate/once": "2",
+            "agent-base": "6",
+            "debug": "4"
+          }
+        },
+        "is-plain-obj": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+          "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+          "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "puppeteer-core": {
+          "version": "20.1.1",
+          "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.1.1.tgz",
+          "integrity": "sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==",
+          "dev": true,
+          "requires": {
+            "@puppeteer/browsers": "1.0.1",
+            "chromium-bidi": "0.4.7",
+            "cross-fetch": "3.1.5",
+            "debug": "4.3.4",
+            "devtools-protocol": "0.0.1120988",
+            "extract-zip": "2.0.1",
+            "https-proxy-agent": "5.0.1",
+            "proxy-from-env": "1.1.0",
+            "tar-fs": "2.1.1",
+            "unbzip2-stream": "1.4.3",
+            "ws": "8.13.0"
+          },
+          "dependencies": {
+            "devtools-protocol": {
+              "version": "0.0.1120988",
+              "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz",
+              "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==",
+              "dev": true
+            }
+          }
+        },
+        "webdriver": {
+          "version": "8.10.2",
+          "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.2.tgz",
+          "integrity": "sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0",
+            "@types/ws": "^8.5.3",
+            "@wdio/config": "8.10.2",
+            "@wdio/logger": "8.6.6",
+            "@wdio/protocols": "8.10.2",
+            "@wdio/types": "8.10.2",
+            "@wdio/utils": "8.10.2",
+            "deepmerge-ts": "^5.0.0",
+            "got": "^12.1.0",
+            "ky": "^0.33.0",
+            "ws": "^8.8.0"
+          }
+        },
+        "webdriverio": {
+          "version": "8.10.2",
+          "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.2.tgz",
+          "integrity": "sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0",
+            "@wdio/config": "8.10.2",
+            "@wdio/logger": "8.6.6",
+            "@wdio/protocols": "8.10.2",
+            "@wdio/repl": "8.10.1",
+            "@wdio/types": "8.10.2",
+            "@wdio/utils": "8.10.2",
+            "archiver": "^5.0.0",
+            "aria-query": "^5.0.0",
+            "css-shorthand-properties": "^1.1.1",
+            "css-value": "^0.0.1",
+            "devtools": "8.10.2",
+            "devtools-protocol": "^0.0.1138159",
+            "grapheme-splitter": "^1.0.2",
+            "import-meta-resolve": "^3.0.0",
+            "is-plain-obj": "^4.1.0",
+            "lodash.clonedeep": "^4.5.0",
+            "lodash.zip": "^4.2.0",
+            "minimatch": "^9.0.0",
+            "puppeteer-core": "20.1.1",
+            "query-selector-shadow-dom": "^1.0.0",
+            "resq": "^1.9.1",
+            "rgb2hex": "0.2.5",
+            "serialize-error": "^8.0.0",
+            "webdriver": "8.10.2"
+          }
+        },
+        "which": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+          "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "21.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+          "dev": true
         }
       }
     },
@@ -27649,22 +28866,235 @@
       "requires": {
         "expect-webdriverio": "^4.0.1",
         "webdriverio": "8.10.2"
+      },
+      "dependencies": {
+        "@puppeteer/browsers": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.0.1.tgz",
+          "integrity": "sha512-9wkYhON9zBgtjYRE3FcokGCfjG25zjzNAYmsHpiWitRZ/4DeT3v125/fCUU66SaPJ4nUsxGNPgpS1TOcQ+8StA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "4.3.4",
+            "extract-zip": "2.0.1",
+            "http-proxy-agent": "5.0.0",
+            "https-proxy-agent": "5.0.1",
+            "progress": "2.0.3",
+            "proxy-from-env": "1.1.0",
+            "tar-fs": "2.1.1",
+            "unbzip2-stream": "1.4.3",
+            "yargs": "17.7.1"
+          }
+        },
+        "@tootallnate/once": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+          "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+          "dev": true,
+          "optional": true
+        },
+        "devtools": {
+          "version": "8.10.2",
+          "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.2.tgz",
+          "integrity": "sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@types/node": "^20.1.0",
+            "@wdio/config": "8.10.2",
+            "@wdio/logger": "8.6.6",
+            "@wdio/protocols": "8.10.2",
+            "@wdio/types": "8.10.2",
+            "@wdio/utils": "8.10.2",
+            "chrome-launcher": "^0.15.0",
+            "edge-paths": "^3.0.5",
+            "import-meta-resolve": "^3.0.0",
+            "puppeteer-core": "20.1.1",
+            "query-selector-shadow-dom": "^1.0.0",
+            "ua-parser-js": "^1.0.1",
+            "uuid": "^9.0.0",
+            "which": "^3.0.0"
+          }
+        },
+        "devtools-protocol": {
+          "version": "0.0.1138159",
+          "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1138159.tgz",
+          "integrity": "sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==",
+          "dev": true,
+          "optional": true
+        },
+        "http-proxy-agent": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+          "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@tootallnate/once": "2",
+            "agent-base": "6",
+            "debug": "4"
+          }
+        },
+        "is-plain-obj": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+          "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+          "dev": true,
+          "optional": true
+        },
+        "minimatch": {
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+          "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "puppeteer-core": {
+          "version": "20.1.1",
+          "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.1.1.tgz",
+          "integrity": "sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@puppeteer/browsers": "1.0.1",
+            "chromium-bidi": "0.4.7",
+            "cross-fetch": "3.1.5",
+            "debug": "4.3.4",
+            "devtools-protocol": "0.0.1120988",
+            "extract-zip": "2.0.1",
+            "https-proxy-agent": "5.0.1",
+            "proxy-from-env": "1.1.0",
+            "tar-fs": "2.1.1",
+            "unbzip2-stream": "1.4.3",
+            "ws": "8.13.0"
+          },
+          "dependencies": {
+            "devtools-protocol": {
+              "version": "0.0.1120988",
+              "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1120988.tgz",
+              "integrity": "sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==",
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "webdriver": {
+          "version": "8.10.2",
+          "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.2.tgz",
+          "integrity": "sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@types/node": "^20.1.0",
+            "@types/ws": "^8.5.3",
+            "@wdio/config": "8.10.2",
+            "@wdio/logger": "8.6.6",
+            "@wdio/protocols": "8.10.2",
+            "@wdio/types": "8.10.2",
+            "@wdio/utils": "8.10.2",
+            "deepmerge-ts": "^5.0.0",
+            "got": "^12.1.0",
+            "ky": "^0.33.0",
+            "ws": "^8.8.0"
+          }
+        },
+        "webdriverio": {
+          "version": "8.10.2",
+          "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.2.tgz",
+          "integrity": "sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "@types/node": "^20.1.0",
+            "@wdio/config": "8.10.2",
+            "@wdio/logger": "8.6.6",
+            "@wdio/protocols": "8.10.2",
+            "@wdio/repl": "8.10.1",
+            "@wdio/types": "8.10.2",
+            "@wdio/utils": "8.10.2",
+            "archiver": "^5.0.0",
+            "aria-query": "^5.0.0",
+            "css-shorthand-properties": "^1.1.1",
+            "css-value": "^0.0.1",
+            "devtools": "8.10.2",
+            "devtools-protocol": "^0.0.1138159",
+            "grapheme-splitter": "^1.0.2",
+            "import-meta-resolve": "^3.0.0",
+            "is-plain-obj": "^4.1.0",
+            "lodash.clonedeep": "^4.5.0",
+            "lodash.zip": "^4.2.0",
+            "minimatch": "^9.0.0",
+            "puppeteer-core": "20.1.1",
+            "query-selector-shadow-dom": "^1.0.0",
+            "resq": "^1.9.1",
+            "rgb2hex": "0.2.5",
+            "serialize-error": "^8.0.0",
+            "webdriver": "8.10.2"
+          }
+        },
+        "which": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
+          "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        },
+        "yargs": {
+          "version": "17.7.1",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
+          "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "cliui": "^8.0.1",
+            "escalade": "^3.1.1",
+            "get-caller-file": "^2.0.5",
+            "require-directory": "^2.1.1",
+            "string-width": "^4.2.3",
+            "y18n": "^5.0.5",
+            "yargs-parser": "^21.1.1"
+          }
+        },
+        "yargs-parser": {
+          "version": "21.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+          "dev": true,
+          "optional": true
+        }
       }
     },
     "@wdio/local-runner": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.10.2.tgz",
-      "integrity": "sha512-f9XkFe09KqhtabuvbJIMs95138Jo8eCp+MbG3/zy789kD4Y2yndkmcmtthI75H2VuT+zwmiwtBp9pSnGQkBrOw==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.10.4.tgz",
+      "integrity": "sha512-zCDmKLdKQVInG4KABU1Y2lZS7k/QSh54JMYsTqTy0NWD0b48kZOM6sUWP4mub/njTinnKKvzXbwmrehl2Ij0SA==",
       "dev": true,
       "requires": {
         "@types/node": "^20.1.0",
         "@wdio/logger": "8.6.6",
         "@wdio/repl": "8.10.1",
-        "@wdio/runner": "8.10.2",
-        "@wdio/types": "8.10.2",
+        "@wdio/runner": "8.10.4",
+        "@wdio/types": "8.10.4",
         "async-exit-hook": "^2.0.1",
         "split2": "^4.1.0",
         "stream-buffers": "^3.0.2"
+      },
+      "dependencies": {
+        "@wdio/types": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+          "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0"
+          }
+        }
       }
     },
     "@wdio/logger": {
@@ -27688,17 +29118,40 @@
       }
     },
     "@wdio/mocha-framework": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.10.2.tgz",
-      "integrity": "sha512-qD8wGJWCXDXMiH917aAzZaOfWavgI2H9SjrNjSHbE8BEZSd9cX43zTo5ZBsqY0JEWD0Ihz32iOyTCvRNynUImA==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.10.4.tgz",
+      "integrity": "sha512-RJPFFfGeDrFChOg22wqzSPp40CUKpAeThzA2oS2REPLyzxmyKAR6m3/wxcOrqtQPVBhuW8ZycOHu4z7WBlYdXg==",
       "dev": true,
       "requires": {
         "@types/mocha": "^10.0.0",
         "@types/node": "^20.1.0",
         "@wdio/logger": "8.6.6",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "mocha": "^10.0.0"
+      },
+      "dependencies": {
+        "@wdio/types": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+          "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0"
+          }
+        },
+        "@wdio/utils": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+          "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "import-meta-resolve": "^3.0.0",
+            "p-iteration": "^1.1.8"
+          }
+        }
       }
     },
     "@wdio/protocols": {
@@ -27731,22 +29184,115 @@
       }
     },
     "@wdio/runner": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.10.2.tgz",
-      "integrity": "sha512-xPDiTjPLS49dPYiHSrHe94sLIaivdGGIsaeuflzV3Ow7RUudUEiaj1XUc0/znJHmNJJF1MHyZgV+9NJRtQJK8Q==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.10.4.tgz",
+      "integrity": "sha512-/8zGiZed1CMyK3UtmHxDC/TjVQnUplly70fTPxfrn/ckZXXqRn9+4/ScOJ+hgaYfEzobf9gFVudY4pGcyzXC/Q==",
       "dev": true,
       "requires": {
         "@types/node": "^20.1.0",
-        "@wdio/config": "8.10.2",
-        "@wdio/globals": "8.10.2",
+        "@wdio/config": "8.10.4",
+        "@wdio/globals": "8.10.4",
         "@wdio/logger": "8.6.6",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "deepmerge-ts": "^5.0.0",
         "expect-webdriverio": "^4.0.1",
         "gaze": "^1.1.2",
-        "webdriver": "8.10.2",
-        "webdriverio": "8.10.2"
+        "webdriver": "8.10.4",
+        "webdriverio": "8.10.4"
+      },
+      "dependencies": {
+        "@wdio/config": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+          "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "@wdio/utils": "8.10.4",
+            "decamelize": "^6.0.0",
+            "deepmerge-ts": "^5.0.0",
+            "glob": "^10.2.2",
+            "import-meta-resolve": "^3.0.0",
+            "read-pkg-up": "^9.1.0"
+          }
+        },
+        "@wdio/globals": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.10.4.tgz",
+          "integrity": "sha512-+/LujjcieK9p6qBWRKHuNCt9ih/nsYx0beqV1FvRJwCoZ7mxShvM+UAmOaJkJRJ+9hOPRKF7K5suBEBS9QW9Wg==",
+          "dev": true,
+          "requires": {
+            "expect-webdriverio": "^4.0.1",
+            "webdriverio": "8.10.4"
+          }
+        },
+        "@wdio/types": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+          "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0"
+          }
+        },
+        "@wdio/utils": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+          "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "import-meta-resolve": "^3.0.0",
+            "p-iteration": "^1.1.8"
+          }
+        },
+        "foreground-child": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+          "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "signal-exit": "^4.0.1"
+          }
+        },
+        "glob": {
+          "version": "10.2.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+          "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+          "dev": true,
+          "requires": {
+            "foreground-child": "^3.1.0",
+            "jackspeak": "^2.0.3",
+            "minimatch": "^9.0.1",
+            "minipass": "^5.0.0 || ^6.0.2",
+            "path-scurry": "^1.7.0"
+          }
+        },
+        "minimatch": {
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+          "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "minipass": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+          "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+          "dev": true
+        },
+        "signal-exit": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+          "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+          "dev": true
+        }
       }
     },
     "@wdio/spec-reporter": {
@@ -30165,27 +31711,108 @@
       }
     },
     "devtools": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.2.tgz",
-      "integrity": "sha512-pvnTf0GtY1ILgBBxjGpQmwmiIklPQFQNirW4deluoLnhKLt6ekdKjYRLoK7goNN0rYPx7R/KK6Aqe5mgWKxBaA==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/devtools/-/devtools-8.10.4.tgz",
+      "integrity": "sha512-OVvT1KabSgSsxppWvM4C7e1TcVmbOn6Px5DcP2DGQ0h2YOWeawqHRdA7TFCBhrToWqhleCbfUBjtea8V4fI2GQ==",
       "dev": true,
       "requires": {
         "@types/node": "^20.1.0",
-        "@wdio/config": "8.10.2",
+        "@wdio/config": "8.10.4",
         "@wdio/logger": "8.6.6",
         "@wdio/protocols": "8.10.2",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "chrome-launcher": "^0.15.0",
         "edge-paths": "^3.0.5",
         "import-meta-resolve": "^3.0.0",
-        "puppeteer-core": "20.1.1",
+        "puppeteer-core": "20.2.0",
         "query-selector-shadow-dom": "^1.0.0",
         "ua-parser-js": "^1.0.1",
         "uuid": "^9.0.0",
         "which": "^3.0.0"
       },
       "dependencies": {
+        "@wdio/config": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+          "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "@wdio/utils": "8.10.4",
+            "decamelize": "^6.0.0",
+            "deepmerge-ts": "^5.0.0",
+            "glob": "^10.2.2",
+            "import-meta-resolve": "^3.0.0",
+            "read-pkg-up": "^9.1.0"
+          }
+        },
+        "@wdio/types": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+          "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0"
+          }
+        },
+        "@wdio/utils": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+          "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "import-meta-resolve": "^3.0.0",
+            "p-iteration": "^1.1.8"
+          }
+        },
+        "foreground-child": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+          "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "signal-exit": "^4.0.1"
+          }
+        },
+        "glob": {
+          "version": "10.2.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+          "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+          "dev": true,
+          "requires": {
+            "foreground-child": "^3.1.0",
+            "jackspeak": "^2.0.3",
+            "minimatch": "^9.0.1",
+            "minipass": "^5.0.0 || ^6.0.2",
+            "path-scurry": "^1.7.0"
+          }
+        },
+        "minimatch": {
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+          "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "minipass": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+          "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+          "dev": true
+        },
+        "signal-exit": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+          "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+          "dev": true
+        },
         "which": {
           "version": "3.0.1",
           "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz",
@@ -30198,9 +31825,9 @@
       }
     },
     "devtools-protocol": {
-      "version": "0.0.1138159",
-      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1138159.tgz",
-      "integrity": "sha512-IVXe1ZEQJWkMkeg10hRoZu3luP054z8USOpBIyorCTTABKVg0gBGt4rmwjGmThMEKaTb4nEmjVJkZ3/YxU0whA==",
+      "version": "0.0.1143632",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1143632.tgz",
+      "integrity": "sha512-QYlQucMwbsBVGKkC4+IdClQYG1FbDrm/0N0kwYiC8DUxuygkyA1RUe7dmM+iCZkQQMaPWmBmilYkNbJweWEuhA==",
       "dev": true
     },
     "diff": {
@@ -31070,15 +32697,15 @@
       }
     },
     "eslint": {
-      "version": "8.40.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
-      "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
+      "version": "8.41.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
+      "integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
       "dev": true,
       "requires": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.4.0",
         "@eslint/eslintrc": "^2.0.3",
-        "@eslint/js": "8.40.0",
+        "@eslint/js": "8.41.0",
         "@humanwhocodes/config-array": "^0.11.8",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
@@ -31098,13 +32725,12 @@
         "find-up": "^5.0.0",
         "glob-parent": "^6.0.2",
         "globals": "^13.19.0",
-        "grapheme-splitter": "^1.0.4",
+        "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-sdsl": "^4.1.4",
         "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
@@ -31883,9 +33509,9 @@
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
     },
     "fast-diff": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
-      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
+      "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
       "dev": true
     },
     "fast-glob": {
@@ -32793,6 +34419,12 @@
       "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
       "dev": true
     },
+    "graphemer": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+      "dev": true
+    },
     "gunzip-maybe": {
       "version": "1.4.2",
       "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz",
@@ -34017,12 +35649,6 @@
         }
       }
     },
-    "js-sdsl": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
-      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
-      "dev": true
-    },
     "js-string-escape": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz",
@@ -34321,9 +35947,9 @@
       }
     },
     "lighthouse-logger": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz",
-      "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
+      "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==",
       "dev": true,
       "requires": {
         "debug": "^2.6.9",
@@ -35916,18 +37542,18 @@
       "dev": true
     },
     "octokit": {
-      "version": "2.0.14",
-      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.14.tgz",
-      "integrity": "sha512-z6cgZBFxirpFEQ1La8Lg83GCs5hOV2EPpkYYdjsGNbfQMv8qUGjq294MiRBCbZqLufviakGsPUxaNKe3JrPmsA==",
+      "version": "2.0.16",
+      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.0.16.tgz",
+      "integrity": "sha512-n7lqH8wkvBRzjzdWGUKZjFYEbGnLjcv5+eS6W6LXGXrXEZbJwQ8WpADMYKbTL0LdOeXdvmpf9DTtpPk0cXndBg==",
       "requires": {
-        "@octokit/app": "^13.1.1",
-        "@octokit/core": "^4.0.4",
-        "@octokit/oauth-app": "^4.0.6",
-        "@octokit/plugin-paginate-rest": "^6.0.0",
-        "@octokit/plugin-rest-endpoint-methods": "^7.0.0",
-        "@octokit/plugin-retry": "^4.0.3",
-        "@octokit/plugin-throttling": "^5.0.0",
-        "@octokit/types": "^9.0.0"
+        "@octokit/app": "^13.1.3",
+        "@octokit/core": "^4.2.1",
+        "@octokit/oauth-app": "^4.2.1",
+        "@octokit/plugin-paginate-rest": "^6.1.0",
+        "@octokit/plugin-rest-endpoint-methods": "^7.1.1",
+        "@octokit/plugin-retry": "^4.1.3",
+        "@octokit/plugin-throttling": "^5.2.2",
+        "@octokit/types": "^9.2.2"
       }
     },
     "on-exit-leak-free": {
@@ -36600,9 +38226,9 @@
       "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
     },
     "preact": {
-      "version": "10.14.1",
-      "resolved": "https://registry.npmjs.org/preact/-/preact-10.14.1.tgz",
-      "integrity": "sha512-4XDSnUisk3YFBb3p9WeKeH1mKoxdFUsaXcvxs9wlpYR1wax/TWJVqhwmIWbByX0h7jMEJH6Zc5J6jqc58FKaNQ=="
+      "version": "10.15.0",
+      "resolved": "https://registry.npmjs.org/preact/-/preact-10.15.0.tgz",
+      "integrity": "sha512-nZSa8M2R2m1n7nJSBlzDpxRJaIsejrTO1vlFbdpFvyC8qM1iU+On2y0otfoUm6SRB5o0lF0CKDFxg6grEFU0iQ=="
     },
     "prebuild-install": {
       "version": "7.1.1",
@@ -36806,21 +38432,16 @@
       "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
     },
     "puppeteer-core": {
-      "version": "20.1.1",
-      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.1.1.tgz",
-      "integrity": "sha512-iB9F2Om8J+nU4qi30oYw0hMWOw6eQN7kFkLLI/u3UvxONOCx5o0KmM6+byaK2/QGIuQu2ly1mPaJnC1DyoW07Q==",
+      "version": "20.2.0",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.2.0.tgz",
+      "integrity": "sha512-QKLu4ELW/609vlLqp/NvQA564LzvLaF6x1ZH+4BhPhxPgreoY8WR/AYOzXS12hgtPPjNCqPKiRLxmyXGnlIK8A==",
       "dev": true,
       "requires": {
-        "@puppeteer/browsers": "1.0.1",
+        "@puppeteer/browsers": "1.2.0",
         "chromium-bidi": "0.4.7",
         "cross-fetch": "3.1.5",
         "debug": "4.3.4",
         "devtools-protocol": "0.0.1120988",
-        "extract-zip": "2.0.1",
-        "https-proxy-agent": "5.0.1",
-        "proxy-from-env": "1.1.0",
-        "tar-fs": "2.1.1",
-        "unbzip2-stream": "1.4.3",
         "ws": "8.13.0"
       },
       "dependencies": {
@@ -39536,19 +41157,19 @@
       }
     },
     "vitest": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.0.tgz",
-      "integrity": "sha512-JwWJS9p3GU9GxkG7eBSmr4Q4x4bvVBSswaCFf1PBNHiPx00obfhHRJfgHcnI0ffn+NMlIh9QGvG75FlaIBdKGA==",
+      "version": "0.31.1",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.31.1.tgz",
+      "integrity": "sha512-/dOoOgzoFk/5pTvg1E65WVaobknWREN15+HF+0ucudo3dDG/vCZoXTQrjIfEaWvQXmqScwkRodrTbM/ScMpRcQ==",
       "dev": true,
       "requires": {
-        "@types/chai": "^4.3.4",
+        "@types/chai": "^4.3.5",
         "@types/chai-subset": "^1.3.3",
         "@types/node": "*",
-        "@vitest/expect": "0.31.0",
-        "@vitest/runner": "0.31.0",
-        "@vitest/snapshot": "0.31.0",
-        "@vitest/spy": "0.31.0",
-        "@vitest/utils": "0.31.0",
+        "@vitest/expect": "0.31.1",
+        "@vitest/runner": "0.31.1",
+        "@vitest/snapshot": "0.31.1",
+        "@vitest/spy": "0.31.1",
+        "@vitest/utils": "0.31.1",
         "acorn": "^8.8.2",
         "acorn-walk": "^8.2.0",
         "cac": "^6.7.14",
@@ -39561,17 +41182,17 @@
         "picocolors": "^1.0.0",
         "std-env": "^3.3.2",
         "strip-literal": "^1.0.1",
-        "tinybench": "^2.4.0",
+        "tinybench": "^2.5.0",
         "tinypool": "^0.5.0",
         "vite": "^3.0.0 || ^4.0.0",
-        "vite-node": "0.31.0",
+        "vite-node": "0.31.1",
         "why-is-node-running": "^2.2.2"
       },
       "dependencies": {
         "vite-node": {
-          "version": "0.31.0",
-          "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.0.tgz",
-          "integrity": "sha512-8x1x1LNuPvE2vIvkSB7c1mApX5oqlgsxzHQesYF7l5n1gKrEmrClIiZuOFbFDQcjLsmcWSwwmrWrcGWm9Fxc/g==",
+          "version": "0.31.1",
+          "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.31.1.tgz",
+          "integrity": "sha512-BajE/IsNQ6JyizPzu9zRgHrBwczkAs0erQf/JRpgTIESpKvNj9/Gd0vxX905klLkb0I0SJVCKbdrl5c6FnqYKA==",
           "dev": true,
           "requires": {
             "cac": "^6.7.14",
@@ -39726,57 +41347,200 @@
       "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
     },
     "webdriver": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.2.tgz",
-      "integrity": "sha512-xwoY+JtmEwN9hFx00V08PBlLLbuOHnPcO78ImPn6IzlhDW960f/6C8fzP0oiJkDyjQ7U81gHU6Mjkp/tBNpKEQ==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.10.4.tgz",
+      "integrity": "sha512-Dvv6LzylhbXN16roQuKzG2W+/IyTLKWFz4tzkwXotd48CAkdy8d2Ds0gVcwo8JpyZQweEKylGdvNC3W50aPLMQ==",
       "dev": true,
       "requires": {
         "@types/node": "^20.1.0",
         "@types/ws": "^8.5.3",
-        "@wdio/config": "8.10.2",
+        "@wdio/config": "8.10.4",
         "@wdio/logger": "8.6.6",
         "@wdio/protocols": "8.10.2",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "deepmerge-ts": "^5.0.0",
         "got": "^12.1.0",
         "ky": "^0.33.0",
         "ws": "^8.8.0"
+      },
+      "dependencies": {
+        "@wdio/config": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+          "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "@wdio/utils": "8.10.4",
+            "decamelize": "^6.0.0",
+            "deepmerge-ts": "^5.0.0",
+            "glob": "^10.2.2",
+            "import-meta-resolve": "^3.0.0",
+            "read-pkg-up": "^9.1.0"
+          }
+        },
+        "@wdio/types": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+          "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0"
+          }
+        },
+        "@wdio/utils": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+          "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "import-meta-resolve": "^3.0.0",
+            "p-iteration": "^1.1.8"
+          }
+        },
+        "foreground-child": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+          "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "signal-exit": "^4.0.1"
+          }
+        },
+        "glob": {
+          "version": "10.2.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+          "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+          "dev": true,
+          "requires": {
+            "foreground-child": "^3.1.0",
+            "jackspeak": "^2.0.3",
+            "minimatch": "^9.0.1",
+            "minipass": "^5.0.0 || ^6.0.2",
+            "path-scurry": "^1.7.0"
+          }
+        },
+        "minimatch": {
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+          "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        },
+        "minipass": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+          "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+          "dev": true
+        },
+        "signal-exit": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+          "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+          "dev": true
+        }
       }
     },
     "webdriverio": {
-      "version": "8.10.2",
-      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.2.tgz",
-      "integrity": "sha512-VrA9oFI17sBhPDvMwywve4CwODHi5FEzjn9gyInN7Nv+6tVaDC+PVGsKV7ZQQSj5C0bzPCn3IgXSoM1Qqn3XeQ==",
+      "version": "8.10.4",
+      "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.10.4.tgz",
+      "integrity": "sha512-5PcAIxf+hBj6JKub/5OXhgJncHgMQrRH3bdpfvOOeLSk26DVRNAcBOOSFOJX+l/Vef0Tqyw/NgSlSbY0x4PUgQ==",
       "dev": true,
       "requires": {
         "@types/node": "^20.1.0",
-        "@wdio/config": "8.10.2",
+        "@wdio/config": "8.10.4",
         "@wdio/logger": "8.6.6",
         "@wdio/protocols": "8.10.2",
         "@wdio/repl": "8.10.1",
-        "@wdio/types": "8.10.2",
-        "@wdio/utils": "8.10.2",
+        "@wdio/types": "8.10.4",
+        "@wdio/utils": "8.10.4",
         "archiver": "^5.0.0",
         "aria-query": "^5.0.0",
         "css-shorthand-properties": "^1.1.1",
         "css-value": "^0.0.1",
-        "devtools": "8.10.2",
-        "devtools-protocol": "^0.0.1138159",
+        "devtools": "8.10.4",
+        "devtools-protocol": "^0.0.1143632",
         "grapheme-splitter": "^1.0.2",
         "import-meta-resolve": "^3.0.0",
         "is-plain-obj": "^4.1.0",
         "lodash.clonedeep": "^4.5.0",
         "lodash.zip": "^4.2.0",
         "minimatch": "^9.0.0",
-        "puppeteer-core": "20.1.1",
+        "puppeteer-core": "20.2.0",
         "query-selector-shadow-dom": "^1.0.0",
         "resq": "^1.9.1",
         "rgb2hex": "0.2.5",
         "serialize-error": "^8.0.0",
-        "webdriver": "8.10.2"
+        "webdriver": "8.10.4"
       },
       "dependencies": {
+        "@wdio/config": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.10.4.tgz",
+          "integrity": "sha512-AjIGkQAMDduzIsl2Sz8B3YOkedf6c2gdI0GftvRSzdwke10XsJuISyP+SPvhzserxHAOIpK5u0fiWXw4x7WYbA==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "@wdio/utils": "8.10.4",
+            "decamelize": "^6.0.0",
+            "deepmerge-ts": "^5.0.0",
+            "glob": "^10.2.2",
+            "import-meta-resolve": "^3.0.0",
+            "read-pkg-up": "^9.1.0"
+          }
+        },
+        "@wdio/types": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.10.4.tgz",
+          "integrity": "sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==",
+          "dev": true,
+          "requires": {
+            "@types/node": "^20.1.0"
+          }
+        },
+        "@wdio/utils": {
+          "version": "8.10.4",
+          "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.10.4.tgz",
+          "integrity": "sha512-ZkUnNMuurO+Zw2Ert1V+C+W5u+aUWTPDyCb5eHMfwIIxEVis/AbwYtuFCxp0Luj5asmZbukb+UryCfoVt6kdmg==",
+          "dev": true,
+          "requires": {
+            "@wdio/logger": "8.6.6",
+            "@wdio/types": "8.10.4",
+            "import-meta-resolve": "^3.0.0",
+            "p-iteration": "^1.1.8"
+          }
+        },
+        "foreground-child": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+          "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "signal-exit": "^4.0.1"
+          }
+        },
+        "glob": {
+          "version": "10.2.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.6.tgz",
+          "integrity": "sha512-U/rnDpXJGF414QQQZv5uVsabTVxMSwzS5CH0p3DRCIV6ownl4f7PzGnkGmvlum2wB+9RlJWJZ6ACU1INnBqiPA==",
+          "dev": true,
+          "requires": {
+            "foreground-child": "^3.1.0",
+            "jackspeak": "^2.0.3",
+            "minimatch": "^9.0.1",
+            "minipass": "^5.0.0 || ^6.0.2",
+            "path-scurry": "^1.7.0"
+          }
+        },
         "is-plain-obj": {
           "version": "4.1.0",
           "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
@@ -39784,13 +41548,25 @@
           "dev": true
         },
         "minimatch": {
-          "version": "9.0.0",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
-          "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
+          "version": "9.0.1",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+          "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
           "dev": true,
           "requires": {
             "brace-expansion": "^2.0.1"
           }
+        },
+        "minipass": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+          "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+          "dev": true
+        },
+        "signal-exit": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+          "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+          "dev": true
         }
       }
     },
diff --git a/package.json b/package.json
index a60f6390..5a7fc926 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "runme",
-  "version": "1.3.1-edge.0",
+  "version": "1.3.1-edge.1",
   "publisher": "stateful",
   "displayName": "Runme",
   "description": "The next-gen Runner for dev workflows.",
@@ -554,7 +554,7 @@
   },
   "dependencies": {
     "@buf/grpc_grpc.community_timostamm-protobuf-ts": "^2.9.0-20230505202852-f6db652602f5.1",
-    "@buf/stateful_runme.community_timostamm-protobuf-ts": "^2.9.0-20230419234326-3a45ee6262e7.1",
+    "@buf/stateful_runme.community_timostamm-protobuf-ts": "^2.9.0-20230522162609-549daeeacece.1",
     "@protobuf-ts/grpc-transport": "^2.9.0",
     "@protobuf-ts/runtime": "^2.9.0",
     "@protobuf-ts/runtime-rpc": "^2.9.0",
diff --git a/src/client/components/annotations.ts b/src/client/components/annotations.ts
index fefedc3d..06d90757 100644
--- a/src/client/components/annotations.ts
+++ b/src/client/components/annotations.ts
@@ -2,11 +2,12 @@ import { LitElement, css, html } from 'lit'
 import { customElement, property } from 'lit/decorators.js'
 import { when } from 'lit/directives/when.js'
 
-import { ClientMessages } from '../../constants'
+import { ClientMessages, OutputType } from '../../constants'
 import type { ClientMessage, CellAnnotations, CellAnnotationsErrorResult } from '../../types'
-import { getContext } from '../utils'
+import { closeOutput, getContext } from '../utils'
 import { CellAnnotationsSchema, AnnotationSchema } from '../../schema'
-import '@vscode/webview-ui-toolkit/dist/data-grid/index'
+
+import './closeCellButton'
 
 type AnnotationsMutation = Partial<CellAnnotations>
 type AnnotationsKey = keyof typeof AnnotationSchema
@@ -36,7 +37,8 @@ export class Annotations extends LitElement {
       flex-direction: column;
       align-items: flex-start;
       gap: 1rem;
-      width: 94%;
+      width: inherited;
+      position: relative;
     }
 
     .annotation-container h4 {
@@ -187,7 +189,7 @@ export class Annotations extends LitElement {
       type="text"
       value="${text}"
       @change="${this.#onChange}"
-      @keyup="${ this.#onChange}"
+      @keyup="${this.#onChange}"
       placeholder=${placeHolder}
       size="50"
       class="annotation-item"
@@ -247,9 +249,16 @@ export class Annotations extends LitElement {
       </div>`
     })
 
-    return html`<section class="annotation-container ${errorCount ? 'has-errors' : ''}">
+    return html`
+    <section class="annotation-container ${errorCount ? 'has-errors' : ''}">
       <h4>Configure cell's execution behavior:</h4>
       ${markup}
+      <close-cell-button @closed="${() => {
+        return closeOutput({
+          uuid: (this.annotations && this.annotations['runme.dev/uuid']) || '',
+          outputType: OutputType.annotations
+        })
+      } }" />
       ${when(
       errorCount,
       () => html`<p class="error-item">This configuration block contains errors, using the default values instead</p>`,
diff --git a/src/client/components/closeCellButton.ts b/src/client/components/closeCellButton.ts
new file mode 100644
index 00000000..148b8ae6
--- /dev/null
+++ b/src/client/components/closeCellButton.ts
@@ -0,0 +1,98 @@
+import { LitElement, css, html } from 'lit'
+import { customElement } from 'lit/decorators.js'
+@customElement('close-cell-button')
+export class CloseCellButton extends LitElement {
+
+    /* eslint-disable */
+    static styles = css`
+        :host {
+            --button-icon-hover-background: var(--vscode-toolbar-hoverBackground);
+            --tooltip-background: #343434;
+        }
+
+        .close-button  .control { 
+            outline: none;
+        }
+
+        .close-button {
+            position: absolute;
+            top: 5px;
+            right: 5px;
+        }
+
+        .close-button, .close-button:hover {
+            border: none;
+        }
+
+        @media (prefers-color-scheme: light) {
+            .icon-close {
+                background-image: url("data:image/svg+xml,%0A%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8.00028 8.70711L11.6467 12.3536L12.3538 11.6465L8.70739 8.00001L12.3538 4.35356L11.6467 3.64645L8.00028 7.2929L4.35384 3.64645L3.64673 4.35356L7.29317 8.00001L3.64673 11.6465L4.35384 12.3536L8.00028 8.70711Z' fill='%23424242'/%3E%3C/svg%3E%0A");
+            }
+        }
+        
+        @media (prefers-color-scheme: dark) {
+            .icon-close {
+                background-image: url("data:image/svg+xml,%0A%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8.00004 8.70711L11.6465 12.3536L12.3536 11.6465L8.70714 8.00001L12.3536 4.35356L11.6465 3.64645L8.00004 7.2929L4.35359 3.64645L3.64648 4.35356L7.29293 8.00001L3.64648 11.6465L4.35359 12.3536L8.00004 8.70711Z' fill='%23C5C5C5'/%3E%3C/svg%3E%0A");
+            }
+        }
+        
+        .tooltip .tooltiptext {
+            visibility: hidden;
+            width: 50px;
+            background-color: var(--tooltip-background);
+            color: #fff;
+            text-align: center;
+            padding: 5px 0;
+            position: absolute;
+            z-index: 1;
+            bottom: 150%;
+            right: -60%;
+            margin-left: -60px;
+            top: 126%;
+            height:15px;
+            box-shadow:2px 2px 4px -2px var(--vscode-input-border);
+        }
+        
+        .tooltip .tooltiptext::after {
+            content: " ";
+            position: absolute;
+            bottom: 100%;  /* At the top of the tooltip */
+            left: 50%;
+            margin-left: -5px;
+            border-width: 5px;
+            border-style: solid;
+            border-color: transparent transparent var(--tooltip-background) transparent;
+        }
+
+        .tooltip .tooltiptext {
+            transition-delay: 1s;
+        }
+
+        .tooltip:hover .tooltiptext {
+            visibility: visible;
+        }
+
+        .tooltip:not(:hover) .tooltiptext {
+            transition-delay: 0s;
+        }
+    `
+
+    private onClose(e: Event) {
+        if (e.defaultPrevented) {
+            e.preventDefault()
+        }
+        const event = new CustomEvent('closed')
+        this.dispatchEvent(event)
+    }
+
+    render() {
+        return html`
+        <div class='close-button tooltip'>
+            <span class="tooltiptext">Close</span>
+            <vscode-button class="control" appearance='icon' aria-label='Close' @click='${this.onClose}'>
+                <span class='icon icon-close'></span>
+            </vscode-button>
+        </div>
+        `
+    }
+}
\ No newline at end of file
diff --git a/src/client/components/outputItems.ts b/src/client/components/outputItems.ts
index 20272768..edb3d04f 100644
--- a/src/client/components/outputItems.ts
+++ b/src/client/components/outputItems.ts
@@ -3,9 +3,11 @@ import { customElement, property } from 'lit/decorators.js'
 
 import '@vscode/webview-ui-toolkit/dist/button/index'
 
-import { getContext } from '../utils'
+import { closeOutput, getContext } from '../utils'
 import { ClientMessage } from '../../types'
-import { ClientMessages } from '../../constants'
+import { ClientMessages, OutputType } from '../../constants'
+
+import './closeCellButton'
 
 @customElement('shell-output-items')
 export class ShellOutputItems extends LitElement {
@@ -37,9 +39,18 @@ export class ShellOutputItems extends LitElement {
   @property({ type: String })
   content = ''
 
+  @property({ type: String })
+  uuid?: string
+
   // Render the UI as a function of component state
   render() {
     return html`<section class="output-items">
+    <close-cell-button @closed="${() => {
+        return closeOutput({
+          uuid: this.uuid!,
+          outputType: OutputType.outputItems
+        })
+      }}" />
       <vscode-button appearance="secondary" @click="${this.#copy}">
         <svg
           class="icon" width="16" height="16" viewBox="0 0 16 16"
@@ -55,7 +66,7 @@ export class ShellOutputItems extends LitElement {
     </span>`
   }
 
-  #copy () {
+  #copy() {
     const ctx = getContext()
 
     if (!ctx.postMessage) {
diff --git a/src/client/components/terminal.ts b/src/client/components/terminal.ts
index faef5a82..8d2148de 100644
--- a/src/client/components/terminal.ts
+++ b/src/client/components/terminal.ts
@@ -7,11 +7,13 @@ import { Unicode11Addon } from 'xterm-addon-unicode11'
 import { WebLinksAddon } from 'xterm-addon-web-links'
 
 import { FitAddon, type ITerminalDimensions } from '../fitAddon'
-import { ClientMessages } from '../../constants'
-import { getContext } from '../utils'
+import { ClientMessages, OutputType } from '../../constants'
+import { closeOutput, getContext } from '../utils'
 import { onClientMessage, postClientMessage } from '../../utils/messaging'
 import { stripANSI } from '../../utils/ansi'
 
+import './closeCellButton'
+
 interface IWindowSize {
   width: number
   height: number
@@ -52,6 +54,7 @@ export class TerminalView extends LitElement {
       user-select: none;
       -ms-user-select: none;
       -webkit-user-select: none;
+      border-radius: 5px;
     }
 
     .xterm.focus,
@@ -248,6 +251,7 @@ export class TerminalView extends LitElement {
       display: flex;
       flex-direction: column;
       gap: 5px;
+      position:relative;
     }
 
     .xterm-drag-handle {
@@ -440,11 +444,13 @@ export class TerminalView extends LitElement {
     window.addEventListener('mouseup', onMouseUp)
     window.addEventListener('mousemove', onMouseMove)
 
-    this.disposables.push({dispose: () => {
-      dragHandle.removeEventListener('mousedown', onMouseDown)
-      window.removeEventListener('mouseup', onMouseUp)
-      window.removeEventListener('mousemove', onMouseMove)
-    }})
+    this.disposables.push({
+      dispose: () => {
+        dragHandle.removeEventListener('mousedown', onMouseDown)
+        window.removeEventListener('mouseup', onMouseUp)
+        window.removeEventListener('mousemove', onMouseMove)
+      }
+    })
 
     return dragHandle
   }
@@ -521,6 +527,12 @@ export class TerminalView extends LitElement {
   render() {
     return html`<section>
       <div id="terminal"></div>
+      <close-cell-button @closed="${() => {
+        return closeOutput({
+          uuid: this.uuid!,
+          outputType: OutputType.terminal
+        })
+      }}" />
       <div class="button-group">
         <vscode-button appearance="secondary" @click="${this.#copy.bind(this)}">
           <svg
@@ -556,8 +568,8 @@ export class TerminalView extends LitElement {
 
 function convertXTermDimensions(dimensions: ITerminalDimensions): TerminalDimensions
 function convertXTermDimensions(dimensions: undefined): undefined
-function convertXTermDimensions(dimensions: ITerminalDimensions|undefined): TerminalDimensions|undefined
-function convertXTermDimensions(dimensions?: ITerminalDimensions): TerminalDimensions|undefined {
+function convertXTermDimensions(dimensions: ITerminalDimensions | undefined): TerminalDimensions | undefined
+function convertXTermDimensions(dimensions?: ITerminalDimensions): TerminalDimensions | undefined {
   if (!dimensions) { return undefined }
 
   const { rows, cols } = dimensions
diff --git a/src/client/components/vercel.ts b/src/client/components/vercel.ts
index 60969c52..ee5b4d56 100644
--- a/src/client/components/vercel.ts
+++ b/src/client/components/vercel.ts
@@ -2,9 +2,11 @@ import { LitElement, css, html } from 'lit'
 import { customElement, property } from 'lit/decorators.js'
 import { when } from 'lit/directives/when.js'
 
-import { ClientMessages } from '../../constants'
+import { ClientMessages, OutputType } from '../../constants'
 import type { ClientMessage } from '../../types'
-import { getContext } from '../utils'
+import { closeOutput, getContext } from '../utils'
+
+import './closeCellButton'
 
 @customElement('vercel-output')
 export class VercelOutput extends LitElement {
@@ -26,6 +28,7 @@ export class VercelOutput extends LitElement {
       flex-direction: row;
       gap: 50px;
       align-items: flex-start;
+      position:relative;
     }
 
     img {
@@ -103,6 +106,12 @@ export class VercelOutput extends LitElement {
           👌 Promoted
         `)}
       </div>
+      <close-cell-button @closed="${() => {
+        return closeOutput({
+          uuid: this.content.payload.uuid,
+          outputType: OutputType.vercel
+        })
+      }}" />
     </section>`
   }
 
diff --git a/src/client/index.ts b/src/client/index.ts
index ad9b972f..cbb2c258 100644
--- a/src/client/index.ts
+++ b/src/client/index.ts
@@ -55,6 +55,7 @@ export const activate: ActivationFunction = (context: RendererContext<void>) =>
            * output items, e.g. copy to clipboard
            */
           const outputItemElem = document.createElement('shell-output-items')
+          outputItemElem.setAttribute('uuid', payload.output.uuid)
           outputItemElem.setAttribute('content', content)
           element.appendChild(outputItemElem)
           break
diff --git a/src/client/utils.ts b/src/client/utils.ts
index aa6d5315..b37aefcf 100644
--- a/src/client/utils.ts
+++ b/src/client/utils.ts
@@ -1,5 +1,8 @@
 import type { RendererContext } from 'vscode-notebook-renderer'
 
+import { postClientMessage } from '../utils/messaging'
+import { ClientMessages, OutputType } from '../constants'
+
 let context: RendererContext<void> | undefined
 
 export function getContext () {
@@ -11,4 +14,12 @@ export function getContext () {
 
 export function setContext (c: RendererContext<void>) {
   context = c
+}
+
+export function closeOutput({ uuid, outputType}: { uuid: string, outputType: OutputType}) {
+  const ctx = getContext()
+  ctx.postMessage && postClientMessage(ctx, ClientMessages.closeCellOutput, {
+      uuid,
+      outputType
+  })
 }
\ No newline at end of file
diff --git a/src/constants.ts b/src/constants.ts
index 602ec1a7..034df179 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -15,6 +15,7 @@ export enum OutputType {
 export enum ClientMessages {
   infoMessage = 'common:infoMessage',
   errorMessage = 'common:errorMessage',
+  closeCellOutput = 'common:closeCellOutput',
   denoUpdate = 'deno:deploymentUpdate',
   denoPromote = 'deno:promoteDeployment',
   vercelProd = 'vercel:promotePreview',
@@ -26,7 +27,7 @@ export enum ClientMessages {
   terminalFocus = 'terminal:focus',
   terminalOpen = 'terminal:open',
   openLink = 'terminal:openLink',
-  activeThemeChanged = 'theme:changed'
+  activeThemeChanged = 'theme:changed',
 }
 
 // [pretty print, languageId, destination]
diff --git a/src/extension/cell.ts b/src/extension/cell.ts
index aaa64e22..452244ac 100644
--- a/src/extension/cell.ts
+++ b/src/extension/cell.ts
@@ -2,10 +2,12 @@ import {
   Disposable,
   NotebookCell,
   NotebookCellExecution,
+  NotebookCellKind,
   NotebookCellOutput,
   NotebookCellOutputItem,
   NotebookController,
   NotebookEdit,
+  NotebookEditor,
   workspace,
   WorkspaceEdit
 } from 'vscode'
@@ -36,7 +38,7 @@ export class NotebookCellManager {
 
   registerCell(cell: NotebookCell): NotebookCellOutputManager {
     const existing = this.#data.get(cell)
-    if(existing) { return existing }
+    if (existing) { return existing }
 
     const outputs = new NotebookCellOutputManager(cell, this.controller)
     this.#data.set(cell, outputs)
@@ -51,7 +53,7 @@ export class NotebookCellManager {
 
   async getNotebookOutputs(cell: NotebookCell): Promise<NotebookCellOutputManager> {
     const outputs = this.#data.get(cell)
-    if(!outputs) {
+    if (!outputs) {
       console.error(`cell at index ${cell.index} has not been registered!`)
     }
 
@@ -60,6 +62,10 @@ export class NotebookCellManager {
 }
 
 type NotebookOutputs = NotebookCellOutput | readonly NotebookCellOutput[]
+interface ICellOption {
+  editor: NotebookEditor
+  uuid: string
+}
 
 export class NotebookCellOutputManager {
   protected outputs: readonly NotebookCellOutput[] = []
@@ -84,17 +90,18 @@ export class NotebookCellOutputManager {
     protected controller: NotebookController
   ) { }
 
-  protected generateOutputUnsafe(type: OutputType): NotebookCellOutput|undefined {
+  protected generateOutputUnsafe(type: OutputType): NotebookCellOutput | undefined {
     const cell = this.cell
     const metadata = cell.metadata as Serializer.Metadata
 
-    switch(type) {
+    switch (type) {
       case OutputType.annotations: {
         const annotationJson: CellOutputPayload<OutputType.annotations> = {
           type: OutputType.annotations,
           output: {
             annotations: getAnnotations(cell),
-            validationErrors: validateAnnotations(cell)
+            validationErrors: validateAnnotations(cell),
+            uuid: cell.metadata['runme.dev/uuid']
           },
         }
 
@@ -152,7 +159,7 @@ export class NotebookCellOutputManager {
               terminalFontFamily,
               terminalFontSize,
               content: terminalState.serialize(),
-              initialRows: getNotebookTerminalRows(),
+              initialRows: getNotebookTerminalRows()
             }
           }
 
@@ -165,6 +172,7 @@ export class NotebookCellOutputManager {
             output: {
               content: terminalState.serialize(),
               mime: 'text/plain',
+              uuid: cellId
             }
           }
 
@@ -205,7 +213,7 @@ export class NotebookCellOutputManager {
     return terminalState
   }
 
-  getCellTerminalState(): ITerminalState|undefined {
+  getCellTerminalState(): ITerminalState | undefined {
     return this.terminalState
   }
 
@@ -232,7 +240,7 @@ export class NotebookCellOutputManager {
           resolve()
         })
 
-        if(wrapper.hasEnded) {
+        if (wrapper.hasEnded) {
           resolve()
         }
       }).finally(resetExecution)
@@ -256,7 +264,7 @@ export class NotebookCellOutputManager {
     await this.showOutput(type, () => !this.hasOutputTypeUnsafe(type))
   }
 
-  async showOutput(type: OutputType, shown: boolean|(() => boolean|Promise<boolean>) = true) {
+  async showOutput(type: OutputType, shown: boolean | (() => boolean | Promise<boolean>) = true) {
     await this.refreshOutputInternal(async () => {
       this.enabledOutputs.set(type, typeof shown === 'function' ? await shown() : shown)
     })
@@ -268,7 +276,7 @@ export class NotebookCellOutputManager {
     })
   }
 
-  async showTerminal(shown: boolean|(() => boolean) = true) {
+  async showTerminal(shown: boolean | (() => boolean) = true) {
     await this.refreshOutputInternal(async () => {
       this.terminalEnabled = (typeof shown === 'function' ? shown() : shown)
     })
@@ -280,9 +288,9 @@ export class NotebookCellOutputManager {
    * @param type * If present, only refresh output list if the given OutputType(s)
    * are present in the outputs, otherwise does nothing
    */
-  async refreshOutput(type?: OutputType|OutputType[]) {
+  async refreshOutput(type?: OutputType | OutputType[]) {
     await this.refreshOutputInternal(() => {
-      if(type === undefined) { return }
+      if (type === undefined) { return }
 
       const typeSet = Array.isArray(type) ? type : [type]
       return typeSet.some(t => this.hasOutputTypeUnsafe(t))
@@ -301,10 +309,10 @@ export class NotebookCellOutputManager {
    * where the user can prevent refreshing if a certain output type is not
    * present.
    */
-  protected async refreshOutputInternal(mutater?: () => Promise<boolean|void>|boolean|void) {
+  protected async refreshOutputInternal(mutater?: () => Promise<boolean | void> | boolean | void) {
     await this.withLock(async () => {
       await this.getExecutionUnsafe(async (exec) => {
-        for(const key of [...this.enabledOutputs.keys()]) {
+        for (const key of [...this.enabledOutputs.keys()]) {
           this.enabledOutputs.set(key, this.hasOutputTypeUnsafe(key))
         }
 
@@ -321,14 +329,14 @@ export class NotebookCellOutputManager {
         let terminalCellOutput = this.terminalEnabled && terminalOutput && this.generateOutputUnsafe(terminalOutput)
 
         await replaceOutput(exec, [
-          ...[ ...this.enabledOutputs.entries() ]
+          ...[...this.enabledOutputs.entries()]
             .flatMap(([type, enabled]) => {
               if (!enabled) { return [] }
 
               const output = this.generateOutputUnsafe(type)
-              if(!output) { return [] }
+              if (!output) { return [] }
 
-              return [ output ]
+              return [output]
             }),
           ...terminalCellOutput ? [terminalCellOutput] : [],
           ...this.outputs,
@@ -337,8 +345,8 @@ export class NotebookCellOutputManager {
     })
   }
 
-  protected async getExecutionUnsafe(cb: (exec: NotebookCellExecution) => Promise<void>|void) {
-    if(this.execution) {
+  protected async getExecutionUnsafe(cb: (exec: NotebookCellExecution) => Promise<void> | void) {
+    if (this.execution) {
       await cb?.(this.execution)
       return
     }
@@ -348,7 +356,7 @@ export class NotebookCellOutputManager {
 
     try {
       await cb(exec)
-    } catch(e) {
+    } catch (e) {
       throw e
     } finally {
       exec.end(true)
@@ -357,7 +365,7 @@ export class NotebookCellOutputManager {
 }
 
 function outputsAsArray(outputs: NotebookOutputs): readonly NotebookCellOutput[] {
-  return Array.isArray(outputs) ? outputs : [ outputs ]
+  return Array.isArray(outputs) ? outputs : [outputs]
 }
 
 type OnEndCallback = (info: {
@@ -410,3 +418,25 @@ export async function updateCellMetadata(cell: NotebookCell, meta: Partial<Seria
   edit.set(cell.notebook.uri, [notebookEdit])
   await workspace.applyEdit(edit)
 }
+
+export async function getCellByUuId(options: ICellOption): Promise<NotebookCell | undefined> {
+  const { editor, uuid } = options
+  for (const document of workspace.notebookDocuments) {
+    for (const cell of document.getCells()) {
+      if (
+        cell.kind !== NotebookCellKind.Code ||
+        cell.document.uri.fsPath !== editor.notebook.uri.fsPath) {
+        continue
+      }
+
+      if (cell.metadata?.['runme.dev/uuid'] === undefined) {
+        console.error(`[Runme] Cell with index ${cell.index} lacks uuid`)
+        continue
+      }
+
+      if (cell.metadata?.['runme.dev/uuid'] === uuid) {
+        return cell
+      }
+    }
+  }
+}
diff --git a/src/extension/executors/runner.ts b/src/extension/executors/runner.ts
index 8f96c27d..c12ca44e 100644
--- a/src/extension/executors/runner.ts
+++ b/src/extension/executors/runner.ts
@@ -16,6 +16,7 @@ import {
 } from 'vscode'
 import { Subject, debounceTime } from 'rxjs'
 
+import getLogger from '../logger'
 import { ClientMessages } from '../../constants'
 import { ClientMessage } from '../../types'
 import { PLATFORM_OS } from '../constants'
@@ -41,6 +42,7 @@ import { handleVercelDeployOutput, isVercelDeployScript } from './vercel'
 
 import type { IEnvironmentManager } from '.'
 
+const log = getLogger('executeRunner')
 const LABEL_LIMIT = 15
 const BACKGROUND_TASK_HIDE_TIMEOUT = 2000
 const MIME_TYPES_WITH_CUSTOM_RENDERERS = ['text/plain']
@@ -124,6 +126,7 @@ export async function executeRunner(
     background,
     tty: interactive,
     convertEol: (!mimeType || mimeType === 'text/plain'),
+    storeLastOutput: true,
   })
 
   context.subscriptions.push(program)
@@ -229,6 +232,7 @@ export async function executeRunner(
 
         item = undefined
       } else if (MIME_TYPES_WITH_CUSTOM_RENDERERS.includes(mime)) {
+        await outputs.showTerminal()
         item = undefined
       }
 
@@ -255,7 +259,6 @@ export async function executeRunner(
     })
   } else {
     await outputs.replaceOutputs([ ])
-    await outputs.showTerminal()
 
     const taskExecution = new Task(
       { type: 'shell', name: `Runme Task (${RUNME_ID})` },
@@ -285,7 +288,8 @@ export async function executeRunner(
         // runs `program.close()` implicitly
         execution.terminate()
       } catch (err: any) {
-        throw new Error(`[Runme] Failed to terminate task: ${(err as Error).message}`)
+        log.error(`Failed to terminate task: ${(err as Error).message}`)
+        throw new Error(err)
       }
     })
 
diff --git a/src/extension/executors/shell.ts b/src/extension/executors/shell.ts
index 07ae787b..c16a1512 100644
--- a/src/extension/executors/shell.ts
+++ b/src/extension/executors/shell.ts
@@ -8,10 +8,12 @@ import { NotebookCellOutputManager } from '../cell'
 import { ENV_STORE } from '../constants'
 import type { Kernel } from '../kernel'
 import { getAnnotations } from '../utils'
+import getLogger from '../logger'
 
 import { handleVercelDeployOutput, isVercelDeployScript } from './vercel'
 
 const MIME_TYPES_WITH_CUSTOM_RENDERERS = ['text/plain']
+const log = getLogger('shellExecutor')
 
 async function shellExecutor(
   this: Kernel,
@@ -30,7 +32,7 @@ async function shellExecutor(
   }
   const outputItems: Buffer[] = []
   const child = spawn(postScript, { cwd, shell: true, env })
-  console.log(`[Runme] Started process on pid ${child.pid}`)
+  log.info(`Started process on pid ${child.pid}`)
   /**
    * this needs more work / specification
    */
diff --git a/src/extension/executors/task.ts b/src/extension/executors/task.ts
index 03f148d9..30afd599 100644
--- a/src/extension/executors/task.ts
+++ b/src/extension/executors/task.ts
@@ -6,6 +6,7 @@ import {
   ShellExecution
 } from 'vscode'
 
+import getLogger from '../logger'
 // import { ExperimentalTerminal } from "../terminal"
 import { getCmdShellSeq, getAnnotations, getTerminalRunmeId } from '../utils'
 import { PLATFORM_OS, ENV_STORE } from '../constants'
@@ -17,6 +18,7 @@ import { sh as inlineSh } from './shell'
 
 const BACKGROUND_TASK_HIDE_TIMEOUT = 2000
 const LABEL_LIMIT = 15
+const log = getLogger('taskExecutor')
 
 export function closeTerminalByEnvID (id: string, kill?: boolean) {
   const terminal = window.terminals.find(t => getTerminalRunmeId(t) === id)
@@ -99,7 +101,7 @@ async function taskExecutor(
         closeTerminalByEnvID(RUNME_ID)
         resolve(0)
       } catch (err: any) {
-        console.error(`[Runme] Failed to terminate task: ${(err as Error).message}`)
+        log.error(`Failed to terminate task: ${(err as Error).message}`)
         resolve(1)
       }
     }))
diff --git a/src/extension/executors/vercel/deploy.ts b/src/extension/executors/vercel/deploy.ts
index 84e29218..1cb8ed57 100644
--- a/src/extension/executors/vercel/deploy.ts
+++ b/src/extension/executors/vercel/deploy.ts
@@ -10,6 +10,7 @@ import { OutputType } from '../../../constants'
 import type { Kernel } from '../../kernel'
 import type { VercelState } from '../../../types'
 import { NotebookCellOutputManager, updateCellMetadata } from '../../cell'
+import getLogger from '../../logger'
 
 import { listTeams, getUser, getProject, getProjects, createProject, cancelDeployment, VercelProject } from './api'
 import { getAuthToken, quickPick, updateGitIgnore, createVercelFile } from './utils'
@@ -20,6 +21,7 @@ const LINK_OPTIONS = [
   'Link Project to existing Vercel project',
   'Create a new Vercel Project'
 ]
+const log = getLogger('Vercel - deploy')
 
 export async function deploy (
   this: Kernel,
@@ -131,7 +133,7 @@ export async function deploy (
     /**
      * deploy application
      */
-    console.log(`[Runme] Deploy project "${deployParams.name}"`)
+    log.info(`Deploy project "${deployParams.name}"`)
     let deploymentId: string | null = null
     let deployCanceled = false
     this.context.subscriptions.push(exec.token.onCancellationRequested(async () => {
diff --git a/src/extension/handler/uri.ts b/src/extension/handler/uri.ts
index c2e93322..e809a880 100644
--- a/src/extension/handler/uri.ts
+++ b/src/extension/handler/uri.ts
@@ -8,12 +8,15 @@ import got from 'got'
 import { v4 as uuidv4 } from 'uuid'
 import { TelemetryReporter } from 'vscode-telemetry'
 
+import getLogger from '../logger'
+
 import {
   getProjectDir, getTargetDirName, getSuggestedProjectName, writeBootstrapFile,
   parseParams
 } from './utils'
 
 const REGEX_WEB_RESOURCE = /^https?:\/\//
+const log = getLogger('RunmeUriHandler')
 
 export class RunmeUriHandler implements UriHandler {
   #context: ExtensionContext
@@ -22,7 +25,7 @@ export class RunmeUriHandler implements UriHandler {
   }
 
   async handleUri(uri: Uri) {
-    console.log(`[Runme] triggered RunmeUriHandler with ${uri}`)
+    log.info(`triggered RunmeUriHandler with ${uri}`)
     const params = new URLSearchParams(uri.query)
     const command = params.get('command')
 
@@ -152,7 +155,7 @@ export class RunmeUriHandler implements UriHandler {
       .then(() => writeBootstrapFile(targetDirUri, fileToOpen))
 
     progress.report({ increment: 50, message: 'Opening project...' })
-    console.log(`[Runme] Attempt to open folder ${targetDirUri.fsPath}`)
+    log.info(`Attempt to open folder ${targetDirUri.fsPath}`)
     await commands.executeCommand('vscode.openFolder', targetDirUri, {
       forceNewWindow: true
     })
diff --git a/src/extension/handler/utils.ts b/src/extension/handler/utils.ts
index 73fab07b..3db1e7e5 100644
--- a/src/extension/handler/utils.ts
+++ b/src/extension/handler/utils.ts
@@ -2,9 +2,11 @@ import url from 'node:url'
 
 import { workspace, window, Uri, ExtensionContext } from 'vscode'
 
+import getLogger from '../logger'
 import { BOOTFILE } from '../constants'
 
 const config = workspace.getConfiguration('runme.checkout')
+const log = getLogger('RunmeUriHandler')
 
 /**
  * Get the project directory from the settings object.
@@ -86,7 +88,7 @@ export async function writeBootstrapFile(targetDirUri: Uri, fileToOpen: string)
     Uri.joinPath(targetDirUri, BOOTFILE),
     enc.encode(fileToOpen)
   )
-  console.log(`[Runme] Created temporary bootstrap file to open ${fileToOpen}`)
+  log.info(`Created temporary bootstrap file to open ${fileToOpen}`)
 }
 
 /**
diff --git a/src/extension/index.ts b/src/extension/index.ts
index ff07beb3..99718704 100644
--- a/src/extension/index.ts
+++ b/src/extension/index.ts
@@ -2,25 +2,27 @@ import type { ExtensionContext } from 'vscode'
 import { TelemetryReporter } from 'vscode-telemetry'
 
 import { RunmeExtension } from './extension'
+import getLogger from './logger'
 
 declare const INSTRUMENTATION_KEY: string
 
 const ext = new RunmeExtension()
+const log = getLogger()
 
 export async function activate (context: ExtensionContext) {
   TelemetryReporter.configure(context, INSTRUMENTATION_KEY)
-  console.log('[Runme] Activating Extension')
+  log.info('Activating Extension')
   try {
     await ext.initialize(context)
-    console.log('[Runme] Extension successfully activated')
+    log.info('Extension successfully activated')
   } catch (err: any) {
-    console.log(`[Runme] Failed to initialize the extension: ${err.message}`)
+    log.error(`Failed to initialize the extension: ${err.message}`)
   }
 
   TelemetryReporter.sendTelemetryEvent('activate')
 }
 
 export function deactivate () {
-  console.log('[Runme] Deactivating Extension')
+  log.info('Deactivating Extension')
   TelemetryReporter.sendTelemetryEvent('deactivate')
 }
diff --git a/src/extension/kernel.ts b/src/extension/kernel.ts
index 7fa3fdb4..a18e5591 100644
--- a/src/extension/kernel.ts
+++ b/src/extension/kernel.ts
@@ -20,6 +20,7 @@ import { ClientMessages } from '../constants'
 import { API } from '../utils/deno/api'
 import { postClientMessage } from '../utils/messaging'
 
+import getLogger from './logger'
 import executor, { type IEnvironmentManager, ENV_STORE_MANAGER } from './executors'
 import { DENO_ACCESS_TOKEN_KEY } from './constants'
 import { resetEnv, getKey, getAnnotations, hashDocumentUri, processEnviron, isWindows } from './utils'
@@ -27,7 +28,8 @@ import './wasm/wasm_exec.js'
 import { IRunner, IRunnerEnvironment } from './runner'
 import { executeRunner } from './executors/runner'
 import { ITerminalState, NotebookTerminalType } from './terminal/terminalState'
-import { NotebookCellManager, NotebookCellOutputManager, RunmeNotebookCellExecution } from './cell'
+import { NotebookCellManager, NotebookCellOutputManager, RunmeNotebookCellExecution, getCellByUuId } from './cell'
+import { handleCellOutputMessage } from './messages/cellOutput'
 
 enum ConfirmationItems {
   Yes = 'Yes',
@@ -36,6 +38,8 @@ enum ConfirmationItems {
   Cancel = 'Cancel'
 }
 
+const log = getLogger('Kernel')
+
 export class Kernel implements Disposable {
   static readonly type = 'runme' as const
 
@@ -92,7 +96,7 @@ export class Kernel implements Disposable {
     this.runnerReadyListener?.dispose()
   }
 
-  async getTerminalState(cell: NotebookCell): Promise<ITerminalState|undefined> {
+  async getTerminalState(cell: NotebookCell): Promise<ITerminalState | undefined> {
     return (await this.getCellOutputs(cell)).getCellTerminalState()
   }
 
@@ -146,7 +150,7 @@ export class Kernel implements Disposable {
           }
 
           if (cell.metadata?.['runme.dev/uuid'] === undefined) {
-            console.error(`[Runme] Cell with index ${cell.index} lacks uuid`)
+            log.error(`Cell with index ${cell.index} lacks uuid`)
             continue
           }
 
@@ -209,13 +213,24 @@ export class Kernel implements Disposable {
       return window.showInformationMessage(message.output as string)
     } else if (message.type === ClientMessages.openLink) {
       return env.openExternal(Uri.parse(message.output))
+    } else if (message.type === ClientMessages.closeCellOutput) {
+      const cell = await getCellByUuId({ editor, uuid: message.output.uuid })
+      if (!cell) {
+        return
+      }
+      return handleCellOutputMessage({
+        message,
+        cell,
+        kernel: this,
+        outputType: message.output.outputType
+      })
     } else if (
       message.type.startsWith('terminal:')
     ) {
       return
     }
 
-    console.error(`[Runme] Unknown kernel event type: ${message.type}`)
+    log.error(`Unknown kernel event type: ${message.type}`)
   }
 
   private async _executeAll(cells: NotebookCell[]) {
@@ -308,7 +323,7 @@ export class Kernel implements Disposable {
       // TODO(mxs): support windows shells
       !isWindows()
     ) {
-      const runScript = (execKey: 'sh'|'bash' = 'bash') => executeRunner(
+      const runScript = (execKey: 'sh' | 'bash' = 'bash') => executeRunner(
         this,
         this.context,
         this.runner!,
@@ -323,7 +338,7 @@ export class Kernel implements Disposable {
       )
         .catch((e) => {
           window.showErrorMessage(`Internal failure executing runner: ${e.message}`)
-          console.error('[Runme] Internal failure executing runner', e.message)
+          log.error('Internal failure executing runner', e.message)
           return false
         })
 
@@ -338,7 +353,7 @@ export class Kernel implements Disposable {
       /**
        * check if user is running experiment to execute shell via runme cli
        */
-      successfulCellExecution =  await executor[execKey].call(this, exec, runningCell, outputs)
+      successfulCellExecution = await executor[execKey].call(this, exec, runningCell, outputs)
     }
     TelemetryReporter.sendTelemetryEvent('cell.endExecute', { 'cell.success': successfulCellExecution?.toString() })
     runmeExec.end(successfulCellExecution)
@@ -364,7 +379,7 @@ export class Kernel implements Disposable {
           this.environment = env
         } catch (e: any) {
           window.showErrorMessage(`Failed to create environment for gRPC Runner: ${e.message}`)
-          console.error('[Runme] Failed to create gRPC Runner environment', e)
+          log.error('Failed to create gRPC Runner environment', e)
         }
       })
     }
diff --git a/src/extension/logger.ts b/src/extension/logger.ts
new file mode 100644
index 00000000..a8d40677
--- /dev/null
+++ b/src/extension/logger.ts
@@ -0,0 +1,48 @@
+import util from 'node:util'
+
+import { window } from 'vscode'
+
+import { stripANSI } from '../utils/ansi'
+
+const outputChannel = window.createOutputChannel('Runme')
+
+const DEFAULT_LOG_LEVEL: LogLevel = 'info'
+
+/**
+ * VS Code currently doesn't support colors, see
+ * https://github.com/microsoft/vscode/issues/571
+ * Therefor keep this minimal.
+ */
+const colors = {
+  reset: '\x1b[0m',
+  red: '\x1b[31m',
+  green: '\x1b[32m',
+  yellow: '\x1b[33m'
+} as const
+type LogLevel = 'trace' | 'info' | 'warn' | 'error'
+
+function color (color: keyof typeof colors, text: string) {
+  return `${colors[color]}${text}${colors.reset}`
+}
+
+function log (scope?: string, logLevel: LogLevel = DEFAULT_LOG_LEVEL, ...logParams: string[]) {
+  const now = new Date()
+  const scopeAddition = scope ? color('yellow', `(${scope})`) : ''
+  const prefix = util.format(
+    `${color('green' ,'[%s]')} ${color('yellow', '%s')} Runme%s:`,
+    now.toISOString(),
+    (logLevel && logLevel.toUpperCase()) ?? '',
+    scopeAddition
+  )
+  console.log(prefix, ...logParams)
+  outputChannel.appendLine(stripANSI([prefix, ...logParams].join(' ')))
+}
+
+export default function getLogger (scope?: string) {
+  return {
+    trace: (...logParams: string[]) => log(scope, 'trace', ...logParams),
+    info: (...logParams: string[]) => log(scope, 'info', ...logParams),
+    warn: (...logParams: string[]) => log(scope, 'warn', ...logParams),
+    error: (...logParams: string[]) => log(scope, 'error', ...logParams)
+  }
+}
diff --git a/src/extension/messages/cellOutput.ts b/src/extension/messages/cellOutput.ts
new file mode 100644
index 00000000..25ab9c83
--- /dev/null
+++ b/src/extension/messages/cellOutput.ts
@@ -0,0 +1,23 @@
+import { NotebookCell } from 'vscode'
+
+import { ClientMessages, OutputType } from '../../constants'
+import { ClientMessage } from '../../types'
+import { Kernel } from '../kernel'
+
+export interface ICellOutputMessage {
+    message: ClientMessage<ClientMessages>
+    cell: NotebookCell
+    kernel: Kernel
+    outputType: OutputType
+}
+
+export async function handleCellOutputMessage(options: ICellOutputMessage): Promise<void> {
+    const { message, cell, kernel, outputType } = options
+    if (message.type === ClientMessages.closeCellOutput) {
+        const outputs = await kernel.getCellOutputs(cell)
+        if ([OutputType.terminal, OutputType.outputItems].includes(outputType)) {
+            return outputs.showTerminal(false)
+        }
+        return outputs.showOutput(outputType, false)
+    }
+}
\ No newline at end of file
diff --git a/src/extension/provider/runmeTask.ts b/src/extension/provider/runmeTask.ts
index 1c27d907..33c68ab9 100644
--- a/src/extension/provider/runmeTask.ts
+++ b/src/extension/provider/runmeTask.ts
@@ -18,6 +18,7 @@ import {
   NotebookCellData,
 } from 'vscode'
 
+import getLogger from '../logger'
 import { getAnnotations, getWorkspaceEnvs, prepareCmdSeq } from '../utils'
 import { Serializer, RunmeTaskDefinition } from '../../types'
 import { SerializerBase } from '../serializer'
@@ -26,6 +27,7 @@ import { getShellPath, parseCommandSeq } from '../executors/utils'
 import { Kernel } from '../kernel'
 
 type TaskOptions = Pick<RunmeTaskDefinition, 'closeTerminalOnSuccess' | 'isBackground' | 'cwd'>
+const log = getLogger('RunmeTaskProvider')
 
 export interface RunmeTask extends Task {
   definition: Required<RunmeTaskDefinition>
@@ -43,7 +45,7 @@ export class RunmeTaskProvider implements TaskProvider {
 
   public async provideTasks(token: CancellationToken): Promise<Task[]> {
     if(!this.runner) {
-      console.error('Tasks only supported with gRPC runner enabled')
+      log.error('Tasks only supported with gRPC runner enabled')
       return []
     }
 
@@ -61,7 +63,7 @@ export class RunmeTaskProvider implements TaskProvider {
       mdContent = (await workspace.fs.readFile(current))
     } catch (err: any) {
       if (err.code !== 'FileNotFound') {
-        console.log(err)
+        log.error(`${err.message}`)
       }
       return []
     }
@@ -135,6 +137,7 @@ export class RunmeTaskProvider implements TaskProvider {
           tty: interactive,
           convertEol: true,
           envs: Object.entries(envs).map(([k, v]) => `${k}=${v}`),
+          storeLastOutput: true,
         }
 
         const program = await runner.createProgramSession(runOpts)
diff --git a/src/extension/runner.ts b/src/extension/runner.ts
index b6d17075..c28b7a26 100644
--- a/src/extension/runner.ts
+++ b/src/extension/runner.ts
@@ -47,6 +47,7 @@ export interface RunProgramOptions {
   terminalDimensions?: TerminalDimensions
   background?: boolean
   convertEol?: boolean
+  storeLastOutput?: boolean
 }
 
 export interface IRunner extends Disposable {
@@ -688,7 +689,18 @@ export class GrpcRunnerProgramSession implements IRunnerProgramSession {
   }
 
   static runOptionsToExecuteRequest(
-    { programName, args, cwd, environment, exec, tty, envs, terminalDimensions, background }: RunProgramOptions
+    {
+      programName,
+      args,
+      cwd,
+      environment,
+      exec,
+      tty,
+      envs,
+      terminalDimensions,
+      background,
+      storeLastOutput
+    }: RunProgramOptions
   ): ExecuteRequest {
     if(environment && !(environment instanceof GrpcRunnerEnvironment)) {
       throw new Error('Expected gRPC environment!')
@@ -705,6 +717,7 @@ export class GrpcRunnerProgramSession implements IRunnerProgramSession {
       ...exec?.type === 'commands' && { commands: exec.commands },
       ...exec?.type === 'script' && { script: exec.script },
       ...terminalDimensions && { winsize: terminalDimensionsToWinsize(terminalDimensions) },
+      storeLastOutput,
     })
   }
 
diff --git a/src/extension/server/runmeServer.ts b/src/extension/server/runmeServer.ts
index 13d8f137..408ddb49 100644
--- a/src/extension/server/runmeServer.ts
+++ b/src/extension/server/runmeServer.ts
@@ -6,6 +6,7 @@ import { ChannelCredentials } from '@grpc/grpc-js'
 import { GrpcTransport } from '@protobuf-ts/grpc-transport'
 import { Disposable, Uri, EventEmitter } from 'vscode'
 
+import getLogger from '../logger'
 import {
   HealthCheckRequest,
   HealthCheckResponse_ServingStatus
@@ -34,6 +35,8 @@ export interface IServerConfig {
     }
 }
 
+const log = getLogger('RunmeServer')
+
 class RunmeServer implements Disposable {
     #port: number
     #process: ChildProcessWithoutNullStreams | undefined
@@ -195,7 +198,7 @@ class RunmeServer implements Disposable {
 
         process.on('close', (code) => {
             if (this.#loggingEnabled) {
-                console.log(`[Runme] Server process #${this.#process?.pid} closed with code ${code}`)
+                log.info(`Server process #${this.#process?.pid} closed with code ${code}`)
             }
             this.#onClose.fire({ code })
 
@@ -204,12 +207,12 @@ class RunmeServer implements Disposable {
 
 
         process.stderr.once('data', () => {
-            console.log(`[Runme] Server process #${this.#process?.pid} started on port ${this.#port}`)
+            log.info(`Server process #${this.#process?.pid} started on port ${this.#port}`)
         })
 
         process.stderr.on('data', (data) => {
             if (this.#loggingEnabled) {
-                console.log(data.toString())
+                log.info(data.toString())
             }
         })
 
diff --git a/src/extension/survey.ts b/src/extension/survey.ts
index 308df0ce..60c8d7c3 100644
--- a/src/extension/survey.ts
+++ b/src/extension/survey.ts
@@ -20,6 +20,9 @@ import { TelemetryReporter } from 'vscode-telemetry'
 
 import { Kernel } from './kernel'
 import { isWindows } from './utils'
+import getLogger from './logger'
+
+const log = getLogger('WinDefaultShell')
 
 export class WinDefaultShell implements Disposable {
   static readonly #id: string = 'runme.surveyWinDefaultShell'
@@ -85,7 +88,7 @@ export class WinDefaultShell implements Disposable {
       unlinkSync(tmpfile)
     } catch (err) {
       if (err instanceof Error) {
-        console.log(err.message)
+        log.error(`Failed to remove temporary default shell: ${err.message}`)
       }
     }
     // eslint-disable-next-line max-len
@@ -131,7 +134,7 @@ export class WinDefaultShell implements Disposable {
       unlinkSync(tmpfile)
     } catch (err) {
       if (err instanceof Error) {
-        console.log(err.message)
+        log.error(`Failed to remove temporary default shell: ${err.message}`)
       }
     }
   }
diff --git a/src/extension/utils.ts b/src/extension/utils.ts
index c36bf41d..b177f1f3 100644
--- a/src/extension/utils.ts
+++ b/src/extension/utils.ts
@@ -23,6 +23,7 @@ import { SafeCellAnnotationsSchema, CellAnnotationsSchema } from '../schema'
 import { SERVER_ADDRESS } from '../constants'
 import { getEnvLoadWorkspaceFiles, getEnvWorkspaceFileOrder, getPortNumber } from '../utils/configuration'
 
+import getLogger from './logger'
 import type executor from './executors'
 import { Kernel } from './kernel'
 import { ENV_STORE, DEFAULT_ENV } from './constants'
@@ -31,6 +32,7 @@ import { ENV_STORE, DEFAULT_ENV } from './constants'
 declare var globalThis: any
 
 const HASH_PREFIX_REGEXP = /^\s*\#\s*/g
+const log = getLogger()
 
 /**
  * Annotations are stored as subset of metadata
@@ -280,7 +282,7 @@ export async function initWasm(wasmUri: Uri) {
       go.run(result.instance)
     },
     (err: Error) => {
-      console.error(`[Runme] failed initializing WASM file: ${err.message}`)
+      log.error(`failed initializing WASM file: ${err.message}`)
       return err
     }
   )
diff --git a/src/types.ts b/src/types.ts
index 3d565fed..ed06163d 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -73,6 +73,7 @@ interface Payload {
   [OutputType.annotations]: {
     annotations?: CellAnnotations
     validationErrors?: CellAnnotationsErrorResult
+    uuid?: string
   }
   [OutputType.terminal]: {
     ['runme.dev/uuid']: string
@@ -124,11 +125,16 @@ export interface ClientMessagePayload {
   }
   [ClientMessages.activeThemeChanged]: string
   [ClientMessages.openLink]: string
+  [ClientMessages.closeCellOutput]: {
+    uuid: string
+    outputType: OutputType
+  }
 }
 
 export interface OutputItemsPayload {
   content: string
   mime: string
+  uuid: string
 }
 
 export interface RunmeTaskDefinition extends TaskDefinition {


Test patch:
diff --git a/tests/extension/configuration.test.ts b/tests/extension/configuration.test.ts
index 9ca32129..58220926 100644
--- a/tests/extension/configuration.test.ts
+++ b/tests/extension/configuration.test.ts
@@ -40,6 +40,7 @@ beforeEach(() => {
     const mocked = await import('../../__mocks__/vscode')
 
     return ({
+      ...mocked,
       workspace: {
         getConfiguration: vi.fn().mockReturnValue({
           get: (configurationName) => {
diff --git a/tests/extension/messages/cellOutput.test.ts b/tests/extension/messages/cellOutput.test.ts
new file mode 100644
index 00000000..a2c676c8
--- /dev/null
+++ b/tests/extension/messages/cellOutput.test.ts
@@ -0,0 +1,81 @@
+import { NotebookCell } from 'vscode'
+import { suite, vi, test, expect } from 'vitest'
+
+import { handleCellOutputMessage } from '../../../src/extension/messages/cellOutput'
+import { ClientMessages, OutputType } from '../../../src/constants'
+import { Kernel } from '../../../src/extension/kernel'
+
+vi.mock('vscode')
+vi.mock('vscode-telemetry')
+vi.mock('../../../src/extension/runner', () => ({}))
+
+suite('Handle CellOutput messages', () => {
+
+    const mockOutput = (type: OutputType) => {
+        const cell = {
+            outputs: [{
+                items: [
+                    { id: '', items: [], metadata: {}, mime: type }
+                ]
+            }],
+            executionSummary: {
+                success: false
+            },
+            metadata: {},
+        } as unknown as NotebookCell
+        const kernel = new Kernel({} as any)
+        const showOutput = vi.fn().mockImplementation(() => { })
+        const showTerminal = vi.fn().mockImplementation(() => { })
+        kernel.getCellOutputs = vi.fn().mockResolvedValue({
+            showTerminal,
+            showOutput,
+        })
+
+        return {
+            showTerminal,
+            showOutput,
+            kernel,
+            cell
+        }
+    }
+
+    const expectOutput = async (type: OutputType) => {
+        const { kernel, cell, showOutput, showTerminal } = mockOutput(type)
+        await handleCellOutputMessage({
+            kernel,
+            cell,
+            outputType: type,
+            message: {
+                type: ClientMessages.closeCellOutput,
+                output: {
+                    uuid: 'a17249e7-4b5f-4b40-8037-10902dd446c9',
+                    outputType: type
+                }
+            }
+        })
+        if ([OutputType.terminal, OutputType.outputItems]
+            .includes(type)) {
+            expect(showTerminal).toBeCalledTimes(1)
+            expect(showTerminal).toBeCalledWith(false)
+        } else {
+            expect(showOutput).toBeCalledTimes(1)
+            expect(showOutput).toBeCalledWith(type, false)
+        }
+    }
+
+    test('Annotations cell output', async () => {
+        return expectOutput(OutputType.annotations)
+    })
+
+    test('Terminal cell output', async () => {
+        return expectOutput(OutputType.terminal)
+    })
+
+    test('OutputItems cell output', async () => {
+        return expectOutput(OutputType.outputItems)
+    })
+
+    test('Vercel cell output', async () => {
+        return expectOutput(OutputType.vercel)
+    })
+})
\ No newline at end of file