From 9867d36d34b1fdb302751fe67d4b76fc37e4c76c Mon Sep 17 00:00:00 2001 From: Brian Leighty Date: Mon, 11 Sep 2023 14:57:25 -0400 Subject: [PATCH] Updated Node Detail Page in Scenegraph Node Inspector and Added Roku Test Automation Panel (#499) * roku automation panel progress commit, standardize event messages to contain fields inside of `context`, add support for webview-ui-toolkit in webviews * finish up roku automation panel * remove unneeded code * progress commit on new node detail page * increase screenshotOutOfDateTimeOut to 10 seconds * Move Autorun on deploy out of RokuAutomationView into view header * Add support for getting persistent keypath in more spots * Make RokuAutomatView layout responsive * Add clear button and make run and stop buttons have fixed positions * move NumberField to shared folder * automation view improvements * disable screenshotOutOfDate for now * More cleanup of NodeDetailPage * fix warning * Store autorunOnDeploy in workspaceState * fix reordering of steps * Fix colorfield updating properly * Fix NumberField stepping * fix failing unit tests * remove unneeded code * Improvements discovered while reviewing with Bronley --------- Co-authored-by: Brian Leighty Co-authored-by: Bronley Plumb --- package-lock.json | 966 ++++++++---------- package.json | 52 +- src/BrightScriptCommands.ts | 18 +- src/commands/VscodeCommand.ts | 8 +- src/extension.spec.ts | 28 +- src/extension.ts | 2 +- src/managers/RemoteControlManager.ts | 6 + src/managers/RtaManager.ts | 8 +- .../WebviewViewProviderManager.spec.ts | 11 +- src/managers/WebviewViewProviderManager.ts | 28 +- src/mockVscode.spec.ts | 10 +- src/viewProviders/BaseRdbViewProvider.ts | 80 +- src/viewProviders/BaseWebviewViewProvider.ts | 56 +- .../RokuAutomationViewViewProvider.ts | 172 ++++ .../RokuCommandsViewProvider.spec.ts | 10 +- .../RokuDeviceViewViewProvider.ts | 26 +- .../RokuRegistryViewProvider.spec.ts | 9 +- src/viewProviders/RokuRegistryViewProvider.ts | 23 +- .../SceneGraphInspectorViewProvider.ts | 14 +- src/viewProviders/ViewProviderCommand.ts | 5 +- src/viewProviders/ViewProviderEvent.ts | 5 +- src/viewProviders/ViewProviderId.ts | 3 +- webviews/package-lock.json | 2 +- webviews/package.json | 2 +- webviews/src/main.ts | 11 +- webviews/src/shared/NumberField.svelte | 46 + .../RokuAutomationView.svelte | 306 ++++++ .../RokuCommandsView/RokuCommandsView.svelte | 2 +- .../RokuDeviceView/RokuDeviceView.svelte | 19 +- .../RokuRegistryView/RokuRegistryView.svelte | 9 +- .../SceneGraphInspectorView/ColorField.svelte | 7 +- .../NodeDetailPage.svelte | 555 +++++----- .../SceneGraphInspectorView.svelte | 7 +- 33 files changed, 1560 insertions(+), 946 deletions(-) create mode 100644 src/viewProviders/RokuAutomationViewViewProvider.ts create mode 100644 webviews/src/shared/NumberField.svelte create mode 100644 webviews/src/views/RokuAutomationView/RokuAutomationView.svelte diff --git a/package-lock.json b/package-lock.json index e3bc91b7..0bbe2e10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "pretty-bytes": "^5.6.0", "roku-debug": "^0.20.3", "roku-deploy": "^3.10.3", - "roku-test-automation": "^2.0.0-beta.19", + "roku-test-automation": "^2.0.0-beta.20", "semver": "^7.1.3", "source-map": "^0.7.3", "thenby": "^1.3.4", @@ -93,15 +93,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -116,47 +107,47 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", - "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.6.tgz", - "integrity": "sha512-HPIyDa6n+HKw5dEuway3vVAhBboYCtREBMp+IWeseZy6TFtzn6MHkCH2KKYUOC/vKKwgSMHQW4htBOrmuRPXfw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.6", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2" + "json5": "^2.2.1", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -189,15 +180,23 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -205,9 +204,9 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.1", @@ -219,16 +218,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", - "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-validator-option": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1" + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -237,158 +235,152 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "yallist": "^3.0.2" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", - "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", - "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -468,9 +460,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", - "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -480,9 +472,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.11" @@ -491,34 +483,47 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", + "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", + "dev": true, + "dependencies": { + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", - "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.6", - "@babel/types": "^7.22.5", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -559,13 +564,13 @@ "dev": true }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -927,15 +932,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@nicolo-ribaudo/semver-v6": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", - "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2076,12 +2072,16 @@ } }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dev": true, "dependencies": { - "dequal": "^2.0.3" + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" } }, "node_modules/array-flat-polyfill": { @@ -2162,24 +2162,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -2246,22 +2228,19 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "node_modules/axe-core": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", - "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dev": true, - "dependencies": { - "dequal": "^2.0.3" - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true }, "node_modules/azure-devops-node-api": { "version": "11.2.0", @@ -2684,9 +2663,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "funding": [ { @@ -2696,17 +2675,13 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" }, "bin": { "browserslist": "cli.js" @@ -2863,9 +2838,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001512", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", - "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", "dev": true, "funding": [ { @@ -2875,10 +2850,6 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" } ] }, @@ -3294,6 +3265,17 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/core-js-pure": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -3627,15 +3609,6 @@ "node": ">= 0.8" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -3832,9 +3805,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.450", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", - "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, "node_modules/emitter-component": { @@ -4276,26 +4249,23 @@ "dev": true }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", - "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", "dev": true, "dependencies": { - "@babel/runtime": "^7.20.7", - "aria-query": "^5.1.3", - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", + "@babel/runtime": "^7.18.9", + "aria-query": "^4.2.2", + "array-includes": "^3.1.5", "ast-types-flow": "^0.0.7", - "axe-core": "^4.6.2", - "axobject-query": "^3.1.1", + "axe-core": "^4.4.3", + "axobject-query": "^2.2.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "has": "^1.0.3", - "jsx-ast-utils": "^3.3.3", - "language-tags": "=1.0.5", + "jsx-ast-utils": "^3.3.2", + "language-tags": "^1.0.5", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", "semver": "^6.3.0" }, "engines": { @@ -6688,12 +6658,12 @@ "dev": true }, "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", + "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", "dev": true, "dependencies": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" } }, "node_modules/latest-version": { @@ -7485,9 +7455,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "node_modules/node-ssdp": { @@ -7783,37 +7753,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", @@ -7889,17 +7828,17 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { "node": ">= 0.8.0" @@ -9269,9 +9208,9 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10853,9 +10792,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "funding": [ { @@ -10865,10 +10804,6 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" } ], "dependencies": { @@ -10876,7 +10811,7 @@ "picocolors": "^1.0.0" }, "bin": { - "update-browserslist-db": "cli.js" + "browserslist-lint": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" @@ -11395,6 +11330,15 @@ "node": ">=0.1.90" } }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", @@ -11643,12 +11587,6 @@ } }, "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -11660,41 +11598,41 @@ } }, "@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "requires": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz", - "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "dev": true }, "@babel/core": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.6.tgz", - "integrity": "sha512-HPIyDa6n+HKw5dEuway3vVAhBboYCtREBMp+IWeseZy6TFtzn6MHkCH2KKYUOC/vKKwgSMHQW4htBOrmuRPXfw==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.6", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2" + "json5": "^2.2.1", + "semver": "^6.3.0" }, "dependencies": { "debug": { @@ -11711,25 +11649,30 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, "@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "dev": true, "requires": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.20.5", "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "requires": { "@jridgewell/set-array": "^1.0.1", @@ -11740,139 +11683,129 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz", - "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-validator-option": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1" + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" }, "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true }, "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-transforms": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz", - "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" } }, "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.20.2" } }, "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" } }, "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true }, "@babel/helpers": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", - "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -11936,45 +11869,55 @@ } }, "@babel/parser": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.6.tgz", - "integrity": "sha512-EIQu22vNkceq3LbjAq7knDf/UmtI2qbcNI8GRBlijez6TpQLvSodJPYfydQmNA5buwkxxxa/PVI44jjYZ+/cLw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", "dev": true }, "@babel/runtime": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.11" + } + }, + "@babel/runtime-corejs3": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", + "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", "dev": true, "requires": { + "core-js-pure": "^3.25.1", "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.6.tgz", - "integrity": "sha512-53CijMvKlLIDlOTrdWiHileRddlIiwUIyCKqYa7lYnnPldXCG5dUSN38uT0cA6i7rHWNKJLH0VU/Kxdr1GzB3w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.6", - "@babel/types": "^7.22.5", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -12003,13 +11946,13 @@ } }, "@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -12292,12 +12235,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@nicolo-ribaudo/semver-v6": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", - "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", - "dev": true - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -13196,12 +13133,13 @@ } }, "aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dev": true, "requires": { - "dequal": "^2.0.3" + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" } }, "array-flat-polyfill": { @@ -13261,18 +13199,6 @@ "es-shim-unscopables": "^1.0.0" } }, - "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, "asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", @@ -13327,19 +13253,16 @@ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" }, "axe-core": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", - "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", "dev": true }, "axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dev": true, - "requires": { - "dequal": "^2.0.3" - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true }, "azure-devops-node-api": { "version": "11.2.0", @@ -13693,15 +13616,15 @@ "dev": true }, "browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "buffer": { @@ -13807,9 +13730,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001512", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz", - "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==", + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", "dev": true }, "caseless": { @@ -14135,6 +14058,12 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "core-js-pure": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "dev": true + }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -14391,12 +14320,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, - "dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true - }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -14543,9 +14466,9 @@ } }, "electron-to-chromium": { - "version": "1.4.450", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz", - "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==", + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, "emitter-component": { @@ -14953,26 +14876,23 @@ } }, "eslint-plugin-jsx-a11y": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz", - "integrity": "sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", "dev": true, "requires": { - "@babel/runtime": "^7.20.7", - "aria-query": "^5.1.3", - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", + "@babel/runtime": "^7.18.9", + "aria-query": "^4.2.2", + "array-includes": "^3.1.5", "ast-types-flow": "^0.0.7", - "axe-core": "^4.6.2", - "axobject-query": "^3.1.1", + "axe-core": "^4.4.3", + "axobject-query": "^2.2.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", "has": "^1.0.3", - "jsx-ast-utils": "^3.3.3", - "language-tags": "=1.0.5", + "jsx-ast-utils": "^3.3.2", + "language-tags": "^1.0.5", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", "semver": "^6.3.0" }, "dependencies": { @@ -16695,12 +16615,12 @@ "dev": true }, "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", + "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", "dev": true, "requires": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" } }, "latest-version": { @@ -17326,9 +17246,9 @@ } }, "node-releases": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", - "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "node-ssdp": { @@ -17557,28 +17477,6 @@ "object-keys": "^1.1.1" } }, - "object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, "object.values": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", @@ -17633,17 +17531,17 @@ } }, "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "ovsx": { @@ -18677,9 +18575,9 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "requires": { "lru-cache": "^6.0.0" } @@ -19891,9 +19789,9 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -20322,6 +20220,12 @@ } } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", diff --git a/package.json b/package.json index eafa0dd0..06f8fd2a 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "pretty-bytes": "^5.6.0", "roku-debug": "^0.20.3", "roku-deploy": "^3.10.3", - "roku-test-automation": "^2.0.0-beta.19", + "roku-test-automation": "^2.0.0-beta.20", "semver": "^7.1.3", "source-map": "^0.7.3", "thenby": "^1.3.4", @@ -214,6 +214,11 @@ "id": "rokuCommandsView", "name": "Roku Commands", "type": "webview" + }, + { + "id": "rokuAutomationView", + "name": "Roku Automation", + "type": "webview" } ] }, @@ -290,6 +295,26 @@ "command": "extension.brightscript.rokuDeviceView.disableNodeInspector", "when": "view == rokuDeviceView && brightscript.isOnDeviceComponentAvailable && brightscript.rokuDeviceView.isInspectingNodes", "group": "navigation@3" + }, + { + "command": "extension.brightscript.rokuAutomationView.startRecording", + "when": "view == rokuAutomationView && !brightscript.rokuAutomationView.isRecording", + "group": "navigation" + }, + { + "command": "extension.brightscript.rokuAutomationView.stopRecording", + "when": "view == rokuAutomationView && brightscript.rokuAutomationView.isRecording", + "group": "navigation" + }, + { + "command": "extension.brightscript.rokuAutomationView.enableAutorunOnDeploy", + "when": "view == rokuAutomationView && !brightscript.rokuAutomationView.autorunOnDeploy", + "group": "navigation@2" + }, + { + "command": "extension.brightscript.rokuAutomationView.disableAutorunOnDeploy", + "when": "view == rokuAutomationView && brightscript.rokuAutomationView.autorunOnDeploy", + "group": "navigation@2" } ], "commandPalette": [] @@ -2676,6 +2701,31 @@ "category": "BrighterScript", "icon": "$(arrow-up)" }, + { + "command": "extension.brightscript.rokuAutomationView.startRecording", + "title": "Start Recording", + "category": "BrighterScript", + "icon": "$(record)" + }, + { + "command": "extension.brightscript.rokuAutomationView.stopRecording", + "title": "Stop Recording", + "category": "BrighterScript", + "icon": "$(debug-stop)" + }, + + { + "command": "extension.brightscript.rokuAutomationView.enableAutorunOnDeploy", + "title": "Enable Autorun on deploy", + "category": "BrighterScript", + "icon": "$(pass)" + }, + { + "command": "extension.brightscript.rokuAutomationView.disableAutorunOnDeploy", + "title": "Disable autorun on deploy", + "category": "BrighterScript", + "icon": "$(pass-filled)" + }, { "command": "extension.brightscript.languageServer.restart", "title": "Restart Language Server", diff --git a/src/BrightScriptCommands.ts b/src/BrightScriptCommands.ts index 5a5fd6f8..b80a8374 100644 --- a/src/BrightScriptCommands.ts +++ b/src/BrightScriptCommands.ts @@ -23,6 +23,7 @@ export class BrightScriptCommands { private fileUtils: BrightScriptFileUtils; private host: string; + private keypressNotifiers = [] as ((key: string, literalCharacter: boolean) => void)[]; public registerCommands() { @@ -306,7 +307,15 @@ export class BrightScriptCommands { } } - public async sendRemoteCommand(key: string, host?: string) { + public async sendRemoteCommand(key: string, host?: string, literalCharacter = false) { + for (const notifier of this.keypressNotifiers) { + notifier(key, literalCharacter); + } + + if (literalCharacter) { + key = 'Lit_' + encodeURIComponent(key); + } + // do we have a temporary override? if (!host) { // Get the long lived host ip @@ -356,6 +365,10 @@ export class BrightScriptCommands { } } + public registerKeypressNotifier(notifier: (key: string, literalCharacter: boolean) => void) { + this.keypressNotifiers.push(notifier); + } + private registerCommand(name: string, callback: (...args: any[]) => any, thisArg?: any) { const prefix = 'extension.brightscript.'; const commandName = name.startsWith(prefix) ? name : prefix + name; @@ -363,7 +376,6 @@ export class BrightScriptCommands { } private async sendAsciiToDevice(character: string) { - let commandToSend: string = 'Lit_' + encodeURIComponent(character); - await this.sendRemoteCommand(commandToSend); + await this.sendRemoteCommand(character, undefined, true); } } diff --git a/src/commands/VscodeCommand.ts b/src/commands/VscodeCommand.ts index a9371392..4c14d3eb 100644 --- a/src/commands/VscodeCommand.ts +++ b/src/commands/VscodeCommand.ts @@ -7,5 +7,11 @@ export enum VscodeCommand { rokuRegistryExportRegistry = 'extension.brightscript.rokuRegistry.exportRegistry', rokuRegistryImportRegistry = 'extension.brightscript.rokuRegistry.importRegistry', rokuRegistryClearRegistry = 'extension.brightscript.rokuRegistry.clearRegistry', - rokuRegistryRefreshRegistry = 'extension.brightscript.rokuRegistry.refreshRegistry' + rokuRegistryRefreshRegistry = 'extension.brightscript.rokuRegistry.refreshRegistry', + rokuAutomationViewEnableAutorunOnDeploy = 'extension.brightscript.rokuAutomationView.enableAutorunOnDeploy', + rokuAutomationViewDisableAutorunOnDeploy = 'extension.brightscript.rokuAutomationView.disableAutorunOnDeploy', + rokuAutomationViewStartRecording = 'extension.brightscript.rokuAutomationView.startRecording', + rokuAutomationViewStopRecording = 'extension.brightscript.rokuAutomationView.stopRecording', + enableRemoteControlMode = 'extension.brightscript.enableRemoteControlMode', + disableRemoteControlMode = 'extension.brightscript.disableRemoteControlMode' } diff --git a/src/extension.spec.ts b/src/extension.spec.ts index 830323e7..55e3c59e 100644 --- a/src/extension.spec.ts +++ b/src/extension.spec.ts @@ -28,20 +28,6 @@ describe('extension', () => { beforeEach(() => { sinon.stub(languageServerManager, 'init').returns(Promise.resolve()); - context = { - extensionPath: '', - subscriptions: [], - asAbsolutePath: () => { }, - globalState: { - get: () => { - - }, - update: () => { - - } - } - }; - originalWebviews = extensionInstance['webviews']; extensionInstance['webviews'] = []; }); @@ -54,48 +40,48 @@ describe('extension', () => { it('registers configuration provider', async () => { let spy = sinon.spy(vscode.debug, 'registerDebugConfigurationProvider'); expect(spy.calledOnce).to.be.false; - await extension.activate(context); + await extension.activate(vscode.context); expect(spy.calledOnce).to.be.true; }); it('registers formatter', async () => { let spy = sinon.spy(vscode.languages, 'registerDocumentRangeFormattingEditProvider'); expect(spy.getCalls().length).to.equal(0); - await extension.activate(context); + await extension.activate(vscode.context); expect(spy.getCalls().length).to.be.greaterThan(1); }); it('registers definition provider', async () => { let spy = sinon.spy(vscode.languages, 'registerDefinitionProvider'); expect(spy.calledOnce).to.be.false; - await extension.activate(context); + await extension.activate(vscode.context); expect(spy.callCount).to.be.greaterThan(0); }); it('registers all commands', async () => { let stub = sinon.stub(BrightScriptCommands.prototype, 'registerCommands').callsFake(() => { }); - await extension.activate(context); + await extension.activate(vscode.context); expect(stub.callCount).to.equal(1); }); it('registers onDidStartDebugSession', async () => { let spy = sinon.spy(vscode.debug, 'onDidStartDebugSession'); expect(spy.calledOnce).to.be.false; - await extension.activate(context); + await extension.activate(vscode.context); expect(spy.calledOnce).to.be.true; }); it('registers onDidTerminateDebugSession', async () => { let spy = sinon.spy(vscode.debug, 'onDidTerminateDebugSession'); expect(spy.calledOnce).to.be.false; - await extension.activate(context); + await extension.activate(vscode.context); expect(spy.calledOnce).to.be.true; }); it('registers onDidReceiveDebugSessionCustomEvent', async () => { let spy = sinon.spy(vscode.debug, 'onDidReceiveDebugSessionCustomEvent'); expect(spy.calledOnce).to.be.false; - await extension.activate(context); + await extension.activate(vscode.context); expect(spy.getCalls().length).to.be.greaterThan(0); }); }); diff --git a/src/extension.ts b/src/extension.ts index a9becd9d..7a9eb016 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -72,7 +72,7 @@ export class Extension { ); this.rtaManager = new RtaManager(); - this.webviewViewProviderManager = new WebviewViewProviderManager(context, this.rtaManager); + this.webviewViewProviderManager = new WebviewViewProviderManager(context, this.rtaManager, this.brightScriptCommands); this.rtaManager.setWebviewViewProviderManager(this.webviewViewProviderManager); //update the tracked version of the extension diff --git a/src/managers/RemoteControlManager.ts b/src/managers/RemoteControlManager.ts index 04c764e3..2e2289d3 100644 --- a/src/managers/RemoteControlManager.ts +++ b/src/managers/RemoteControlManager.ts @@ -1,6 +1,7 @@ import * as vscode from 'vscode'; import { vscodeContextManager } from './VscodeContextManager'; import type { TelemetryManager } from './TelemetryManager'; +import { VscodeCommand } from '../commands/VscodeCommand'; export class RemoteControlManager { constructor( @@ -70,6 +71,11 @@ export class RemoteControlManager { } public async setRemoteControlMode(isEnabled: boolean, initiator: RemoteControlModeInitiator) { + if (this.isEnabled && !isEnabled) { + // Want to also stop Roku automation recording if it was running + await vscode.commands.executeCommand(VscodeCommand.rokuAutomationViewStopRecording); + } + //only send a telemetry event if we know who initiated the mode. `undefined` usually means our internal system set the value...so don't track that if (initiator) { this.telemetryManager.sendSetRemoteControlModeEvent(isEnabled, initiator); diff --git a/src/managers/RtaManager.ts b/src/managers/RtaManager.ts index 49c37fe9..140d46c9 100644 --- a/src/managers/RtaManager.ts +++ b/src/managers/RtaManager.ts @@ -13,7 +13,7 @@ export class RtaManager { public setupRtaWithConfig(config: { host: string; password: string; logLevel?: string; disableScreenSaver?: boolean; injectRdbOnDeviceComponent?: boolean }) { const enableDebugging = ['info', 'debug', 'trace'].includes(config.logLevel); - rta.odc.setConfig({ + const rtaConfig: rta.ConfigOptions = { RokuDevice: { devices: [{ host: config.host, @@ -26,7 +26,11 @@ export class RtaManager { disableTelnet: true, disableCallOriginationLine: true } - }); + }; + + rta.odc.setConfig(rtaConfig); + + rta.ecp.setConfig(rtaConfig); this.device = rta.device; diff --git a/src/managers/WebviewViewProviderManager.spec.ts b/src/managers/WebviewViewProviderManager.spec.ts index 907bc143..6e60da0a 100644 --- a/src/managers/WebviewViewProviderManager.spec.ts +++ b/src/managers/WebviewViewProviderManager.spec.ts @@ -4,6 +4,7 @@ import { vscode } from '../mockVscode.spec'; import type { BrightScriptLaunchConfiguration } from '../DebugConfigurationProvider'; import { WebviewViewProviderManager } from './WebviewViewProviderManager'; import { RtaManager } from './RtaManager'; +import { BrightScriptCommands } from '../BrightScriptCommands'; const sinon = createSandbox(); @@ -14,6 +15,7 @@ describe('WebviewViewProviderManager', () => { const config = {} as BrightScriptLaunchConfiguration; let webviewViewProviderManager: WebviewViewProviderManager; let rtaManager: RtaManager; + const brightScriptCommands = new BrightScriptCommands({} as any, {} as any, {} as any, {} as any); before(() => { context = { @@ -46,16 +48,17 @@ describe('WebviewViewProviderManager', () => { before(() => { spy = sinon.spy(vscode.window, 'registerWebviewViewProvider'); rtaManager = new RtaManager(); - webviewViewProviderManager = new WebviewViewProviderManager(context, rtaManager); + webviewViewProviderManager = new WebviewViewProviderManager(context, rtaManager, brightScriptCommands); }); it('initializes webview providers and calls registerWebviewViewProvider for each', () => { expect(spy.callCount).to.equal(webviewViewProviderManager.getWebviewViewProviders().length); }); - it('assigns RtaManager to each webviewViewProvider', () => { + it('assigns dependencies to each webviewViewProvider', () => { for (const webviewViewProvider of webviewViewProviderManager.getWebviewViewProviders()) { - expect(webviewViewProvider['rtaManager']).to.equal(rtaManager); + expect(webviewViewProvider['dependencies']['rtaManager']).to.equal(rtaManager); + expect(webviewViewProvider['dependencies']['brightScriptCommands']).to.equal(brightScriptCommands); } expect(spy.callCount).to.equal(webviewViewProviderManager.getWebviewViewProviders().length); }); @@ -74,7 +77,7 @@ describe('WebviewViewProviderManager', () => { }; rtaManager = new RtaManager(); - webviewViewProviderManager = new WebviewViewProviderManager(context, rtaManager); + webviewViewProviderManager = new WebviewViewProviderManager(context, rtaManager, brightScriptCommands); rtaManager.setWebviewViewProviderManager(webviewViewProviderManager); }); diff --git a/src/managers/WebviewViewProviderManager.ts b/src/managers/WebviewViewProviderManager.ts index 5bec92b4..26c9ff5f 100644 --- a/src/managers/WebviewViewProviderManager.ts +++ b/src/managers/WebviewViewProviderManager.ts @@ -1,33 +1,34 @@ import type { ChannelPublishedEvent } from 'roku-debug'; import type { BrightScriptLaunchConfiguration } from '../DebugConfigurationProvider'; import type { RtaManager } from './RtaManager'; +import type { BrightScriptCommands } from '../BrightScriptCommands'; import * as vscode from 'vscode'; import { RokuCommandsViewProvider } from '../viewProviders/RokuCommandsViewProvider'; import { RokuDeviceViewViewProvider } from '../viewProviders/RokuDeviceViewViewProvider'; import { RokuRegistryViewProvider } from '../viewProviders/RokuRegistryViewProvider'; import { SceneGraphInspectorViewProvider } from '../viewProviders/SceneGraphInspectorViewProvider'; - +import { RokuAutomationViewViewProvider } from '../viewProviders/RokuAutomationViewViewProvider'; export class WebviewViewProviderManager { - constructor(context: vscode.ExtensionContext, rtaManager: RtaManager) { - this.rtaManager = rtaManager; + constructor( + private context: vscode.ExtensionContext, + private rtaManager: RtaManager, + private brightScriptCommands: BrightScriptCommands + ) { for (const webview of this.webviewViews) { if (!webview.provider) { - webview.provider = new webview.constructor(context); + webview.provider = new webview.constructor(context, { + rtaManager: rtaManager, + brightScriptCommands: brightScriptCommands + }); vscode.window.registerWebviewViewProvider(webview.provider.id, webview.provider); webview.provider.setWebviewViewProviderManager(this); - - if (typeof webview.provider.setRtaManager === 'function') { - webview.provider.setRtaManager(this.rtaManager); - } } } } - private rtaManager?: RtaManager; - private webviewViews = [{ constructor: SceneGraphInspectorViewProvider, provider: undefined as SceneGraphInspectorViewProvider @@ -40,6 +41,9 @@ export class WebviewViewProviderManager { }, { constructor: RokuDeviceViewViewProvider, provider: undefined as RokuDeviceViewViewProvider + }, { + constructor: RokuAutomationViewViewProvider, + provider: undefined as RokuAutomationViewViewProvider }]; public getWebviewViewProviders() { @@ -54,6 +58,10 @@ export class WebviewViewProviderManager { public onChannelPublishedEvent(e: ChannelPublishedEvent) { const config = e.body.launchConfiguration as BrightScriptLaunchConfiguration; this.rtaManager.setupRtaWithConfig(config); + + for (const webview of this.webviewViews) { + void webview.provider.onChannelPublishedEvent(e); + } } // Mainly for communicating between webviews diff --git a/src/mockVscode.spec.ts b/src/mockVscode.spec.ts index 27115bdf..17ba818f 100644 --- a/src/mockVscode.spec.ts +++ b/src/mockVscode.spec.ts @@ -83,8 +83,16 @@ export let vscode = { return this._data[key]; } } as any, + workspaceState: { + _data: {}, + update: function(key: string, value: any) { + this._data[key] = value; + }, + get: function(key: string) { + return this._data[key]; + } + } as any, globalStorageUri: undefined as Uri, - workspaceState: {} as any, environmentVariableCollection: {} as any, logUri: undefined as Uri, logPath: '', diff --git a/src/viewProviders/BaseRdbViewProvider.ts b/src/viewProviders/BaseRdbViewProvider.ts index c2146c2b..0b8a804b 100644 --- a/src/viewProviders/BaseRdbViewProvider.ts +++ b/src/viewProviders/BaseRdbViewProvider.ts @@ -11,78 +11,50 @@ import { ViewProviderCommand } from './ViewProviderCommand'; export abstract class BaseRdbViewProvider extends BaseWebviewViewProvider { - protected rtaManager?: RtaManager; - protected odcCommands: Array; - constructor(context: vscode.ExtensionContext) { - super(context); + constructor(context: vscode.ExtensionContext, dependencies) { + super(context, dependencies); const requestTypesPath = path.join(rta.utils.getClientFilesPath(), 'requestTypes.schema.json'); const json = JSON.parse(fsExtra.readFileSync(requestTypesPath, 'utf8')); this.odcCommands = Object.values(json.enum); - } - public setRtaManager(rtaManager?: RtaManager) { - this.rtaManager = rtaManager; + this.setupCommandObservers(); } public updateDeviceAvailability() { - this.postOrQueueMessage({ - event: ViewProviderEvent.onDeviceAvailabilityChange, - odcAvailable: !!this.rtaManager.onDeviceComponent, - deviceAvailable: !!this.rtaManager.device + const message = this.createEventMessage(ViewProviderEvent.onDeviceAvailabilityChange, { + odcAvailable: !!this.dependencies.rtaManager.onDeviceComponent, + deviceAvailable: !!this.dependencies.rtaManager.device }); - } - protected onViewReady() { - // Always post back the device status so we make sure the client doesn't miss it if it got refreshed - this.updateDeviceAvailability(); + this.postOrQueueMessage(message); } - protected async handleViewMessage(message) { - const { command, context } = message; - if (this.odcCommands.includes(command)) { - const response = await this.rtaManager.sendOdcRequest(this.id, command, context); - this.postOrQueueMessage({ - ...message, - response: response - }); - return true; - } else if (command === ViewProviderCommand.getStoredNodeReferences) { - const response = this.rtaManager.getStoredNodeReferences(); - this.postOrQueueMessage({ - ...message, - response: response + protected setupCommandObservers() { + for (const command of this.odcCommands) { + this.addMessageCommandCallback(command, async (message) => { + const { command, context } = message; + const response = await this.dependencies.rtaManager.sendOdcRequest(this.id, command, context); + this.postOrQueueMessage({ + ...message, + response: response + }); + return true; }); + } - return true; - } else if (command === ViewProviderCommand.setManualIpAddress) { - this.rtaManager.setupRtaWithConfig({ + this.addMessageCommandCallback(ViewProviderCommand.setManualIpAddress, (message) => { + this.dependencies.rtaManager.setupRtaWithConfig({ ...message.context, injectRdbOnDeviceComponent: true }); - return true; - } else if (command === ViewProviderCommand.getScreenshot) { - try { - const result = await this.rtaManager.device.getScreenshot(); - this.postOrQueueMessage({ - ...message, - response: { - success: true, - arrayBuffer: result.buffer.buffer - } - }); - } catch (e) { - this.postOrQueueMessage({ - ...message, - response: { - success: false - } - }); - } - return true; - } + return Promise.resolve(true); + }); + } - return false; + protected onViewReady() { + // Always post back the device status so we make sure the client doesn't miss it if it got refreshed + this.updateDeviceAvailability(); } } diff --git a/src/viewProviders/BaseWebviewViewProvider.ts b/src/viewProviders/BaseWebviewViewProvider.ts index e7d47dd6..9e6955b3 100644 --- a/src/viewProviders/BaseWebviewViewProvider.ts +++ b/src/viewProviders/BaseWebviewViewProvider.ts @@ -1,17 +1,28 @@ import * as vscode from 'vscode'; import * as path from 'path'; import * as fsExtra from 'fs-extra'; +import type { RequestType } from 'roku-test-automation'; import type { AsyncSubscription, Event } from '@parcel/watcher'; +import type { ChannelPublishedEvent } from 'roku-debug'; import { vscodeContextManager } from '../managers/VscodeContextManager'; -import { util } from '../util'; import type { WebviewViewProviderManager } from '../managers/WebviewViewProviderManager'; import { ViewProviderEvent } from './ViewProviderEvent'; import { ViewProviderCommand } from './ViewProviderCommand'; +import type { VscodeCommand } from '../commands/VscodeCommand'; +import type { RtaManager } from '../managers/RtaManager'; +import type { BrightScriptCommands } from '../BrightScriptCommands'; export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvider, vscode.Disposable { - constructor(context: vscode.ExtensionContext) { - this.webviewBasePath = path.join(context.extensionPath, 'dist', 'webviews'); - context.subscriptions.push(this); + constructor( + protected extensionContext: vscode.ExtensionContext, + protected dependencies: { + rtaManager: RtaManager; + brightscriptCommands: BrightScriptCommands; + } + ) { + this.webviewBasePath = path.join(extensionContext.extensionPath, 'dist', 'webviews'); + extensionContext.subscriptions.push(this); + this.extensionContext = extensionContext; } /** @@ -26,6 +37,7 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi private viewReady = false; private queuedMessages = []; private webviewViewProviderManager: WebviewViewProviderManager; + private messageCommandCallbacks = {} as Record Promise>; public dispose() { void this.outDirWatcher?.unsubscribe(); @@ -35,6 +47,26 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi this.webviewViewProviderManager = manager; } + public onChannelPublishedEvent(e: ChannelPublishedEvent) { + // Can be overwritten in a child to notify on channel publish + } + + public createCommandMessage(command: VscodeCommand | ViewProviderCommand, context = {}) { + const message = { + command: command, + context: context + }; + return message; + } + + public createEventMessage(event: ViewProviderEvent, context = {}) { + const message = { + event: event, + context: context + }; + return message; + } + public postOrQueueMessage(message) { if (this.viewReady) { this.postMessage(message); @@ -55,6 +87,10 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi } } + protected addMessageCommandCallback(command: ViewProviderCommand | VscodeCommand | RequestType, callback: (message) => Promise) { + this.messageCommandCallbacks[command] = callback; + } + private setupViewMessageObserver(webview: vscode.Webview) { webview.onDidReceiveMessage(async (message) => { try { @@ -71,7 +107,8 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi const context = message.context; this.webviewViewProviderManager.sendMessageToWebviews(context.viewIds, context.message); } else { - if (!await this.handleViewMessage(message)) { + const callback = this.messageCommandCallbacks[command]; + if (!callback || !await callback(message)) { console.warn('Did not handle message', message); } } @@ -87,16 +124,13 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi }); } - protected handleViewMessage(message): Promise | boolean { - return false; - } - protected registerCommandWithWebViewNotifier(context: vscode.ExtensionContext, command: string) { context.subscriptions.push(vscode.commands.registerCommand(command, () => { - this.postOrQueueMessage({ - event: ViewProviderEvent.onVscodeCommandReceived, + const message = this.createEventMessage(ViewProviderEvent.onVscodeCommandReceived, { commandName: command }); + + this.postOrQueueMessage(message); })); } diff --git a/src/viewProviders/RokuAutomationViewViewProvider.ts b/src/viewProviders/RokuAutomationViewViewProvider.ts new file mode 100644 index 00000000..9d99006f --- /dev/null +++ b/src/viewProviders/RokuAutomationViewViewProvider.ts @@ -0,0 +1,172 @@ +import * as vscode from 'vscode'; +import type { ChannelPublishedEvent } from 'roku-debug'; +import { utils, ecp } from 'roku-test-automation'; +import { vscodeContextManager } from '../managers/VscodeContextManager'; +import type { BrightScriptCommands } from '../BrightScriptCommands'; +import { VscodeCommand } from '../commands/VscodeCommand'; +import { BaseRdbViewProvider } from './BaseRdbViewProvider'; +import { ViewProviderId } from './ViewProviderId'; +import { ViewProviderCommand } from './ViewProviderCommand'; +import { ViewProviderEvent } from './ViewProviderEvent'; + +export class RokuAutomationViewViewProvider extends BaseRdbViewProvider { + public readonly id = ViewProviderId.rokuAutomationView; + + constructor(context: vscode.ExtensionContext, dependencies) { + super(context, dependencies); + + this.context = context; + + this.addMessageCommandCallback(ViewProviderCommand.storeRokuAutomationConfigs, async (message) => { + this.rokuAutomationConfigs = message.context.configs; + // Make sure to use JSON.stringify or weird stuff happens + await context.workspaceState.update(this.configStorageKey, JSON.stringify(message.context)); + return true; + }); + + this.addMessageCommandCallback(ViewProviderCommand.runRokuAutomationConfig, async (message) => { + const index = message.context.configIndex; + await this.runRokuAutomationConfig(index); + return true; + }); + + const brightScriptCommands = dependencies.brightScriptCommands as BrightScriptCommands; + brightScriptCommands.registerKeypressNotifier((key, literalCharacter) => { + if (this.isRecording) { + const message = this.createEventMessage(ViewProviderEvent.onRokuAutomationKeyPressed, { + key: key, + literalCharacter: literalCharacter + }); + + this.postOrQueueMessage(message); + } + }); + + const subscriptions = context.subscriptions; + + subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuAutomationViewStartRecording, async () => { + if (this.currentRunningStep === -1) { + // Only allow recording when we aren't currently running + await this.setIsRecording(true); + await vscode.commands.executeCommand(VscodeCommand.enableRemoteControlMode); + + // We reset the current step to update the timestamp of the first sleep + this.updateCurrentRunningStep(-1); + } + })); + + subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuAutomationViewStopRecording, async () => { + if (this.isRecording) { + await this.setIsRecording(false); + await vscode.commands.executeCommand(VscodeCommand.disableRemoteControlMode); + } + })); + + subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuAutomationViewEnableAutorunOnDeploy, async () => { + await this.setAutorunOnDeploy(true); + })); + + subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuAutomationViewDisableAutorunOnDeploy, async () => { + await this.setAutorunOnDeploy(false); + })); + + let autorunOnDeploy: boolean = this.extensionContext.workspaceState.get(this.autorunOnDeployStorageKey); + // Default to true if not set + if (autorunOnDeploy !== false) { + autorunOnDeploy = true; + } + void this.setAutorunOnDeploy(autorunOnDeploy); + } + + private async setIsRecording(isRecording) { + this.isRecording = isRecording; + await vscodeContextManager.set('brightscript.rokuAutomationView.isRecording', isRecording); + } + + private async setAutorunOnDeploy(autorunOnDeploy: boolean) { + this.rokuAutomationAutorunOnDeploy = autorunOnDeploy; + await vscodeContextManager.set('brightscript.rokuAutomationView.autorunOnDeploy', autorunOnDeploy); + await this.context.workspaceState.update(this.autorunOnDeployStorageKey, autorunOnDeploy); + } + + private context: vscode.ExtensionContext; + + private isRecording = false; + private configStorageKey = 'rokuAutomationConfigs'; + private rokuAutomationConfigs: { + name: string; + steps: { + type: string; + value: string; + }[]; + }[]; + + private autorunOnDeployStorageKey = 'rokuAutomationAutorunOnDeploy'; + private rokuAutomationAutorunOnDeploy = false; + + private currentRunningStep = -1; + + public async runRokuAutomationConfig(index) { + let stopRunning = false; + this.addMessageCommandCallback(ViewProviderCommand.stopRokuAutomationConfig, (message) => { + stopRunning = true; + return Promise.resolve(true); + }); + + const config = this.rokuAutomationConfigs[index]; + for (const [index, step] of config.steps.entries()) { + if (stopRunning) { + break; + } + + this.updateCurrentRunningStep(index); + switch (step.type) { + case 'sleep': + await utils.sleep(+step.value * 1000); + break; + case 'sendText': + await ecp.sendText(step.value); + break; + case 'sendKeyPress': + await ecp.sendKeyPress(step.value as any); + break; + } + } + + // Let the view know we're done running + this.updateCurrentRunningStep(-1); + } + + public onChannelPublishedEvent(e: ChannelPublishedEvent) { + if (this.rokuAutomationAutorunOnDeploy) { + return this.runRokuAutomationConfig(0); + } + } + + protected updateCurrentRunningStep(step = this.currentRunningStep) { + const message = this.createEventMessage(ViewProviderEvent.onRokuAutomationConfigStepChange, { + step: step + }); + + this.postOrQueueMessage(message); + } + + protected onViewReady() { + // Always post back the device status so we make sure the client doesn't miss it if it got refreshed + this.updateDeviceAvailability(); + + const json = this.extensionContext.workspaceState.get(this.configStorageKey); + if (typeof json === 'string') { + const result = JSON.parse(json); + this.rokuAutomationConfigs = result.configs; + } + + const message = this.createEventMessage(ViewProviderEvent.onRokuAutomationConfigsLoaded, { + configs: this.rokuAutomationConfigs + }); + + this.postOrQueueMessage(message); + + this.updateCurrentRunningStep(); + } +} diff --git a/src/viewProviders/RokuCommandsViewProvider.spec.ts b/src/viewProviders/RokuCommandsViewProvider.spec.ts index c8c2f79b..aeecb48e 100644 --- a/src/viewProviders/RokuCommandsViewProvider.spec.ts +++ b/src/viewProviders/RokuCommandsViewProvider.spec.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import * as sinonImport from 'sinon'; import { vscode } from '../mockVscode.spec'; import { RokuCommandsViewProvider } from './RokuCommandsViewProvider'; +import { VscodeCommand } from '../commands/VscodeCommand'; let Module = require('module'); const { require: oldRequire } = Module.prototype; @@ -29,7 +30,7 @@ beforeEach(() => { show: () => { } }; - provider = new RokuCommandsViewProvider(vscode.context) as any; + provider = new RokuCommandsViewProvider(vscode.context, {}) as any; }); afterEach(() => { provider.dispose(); @@ -51,12 +52,13 @@ describe('RokuCommandsViewProvider', () => { await provider['resolveWebviewView'](view, {} as any, {} as any); expect(typeof callback).to.equal('function'); - const spy = sinon.spy(provider as any, 'handleViewMessage'); + const fake = sinonImport.fake.returns(Promise.resolve(true)); + provider['addMessageCommandCallback'](VscodeCommand.rokuRegistryImportRegistry, fake); callback({ - command: 'importRegistry', + command: VscodeCommand.rokuRegistryImportRegistry, context: {} }); - expect(spy.calledOnce).to.be.true; + expect(fake.calledOnce).to.be.true; }); }); }); diff --git a/src/viewProviders/RokuDeviceViewViewProvider.ts b/src/viewProviders/RokuDeviceViewViewProvider.ts index 9cab6128..4b6e6332 100644 --- a/src/viewProviders/RokuDeviceViewViewProvider.ts +++ b/src/viewProviders/RokuDeviceViewViewProvider.ts @@ -2,17 +2,39 @@ import type * as vscode from 'vscode'; import { VscodeCommand } from '../commands/VscodeCommand'; import { BaseRdbViewProvider } from './BaseRdbViewProvider'; import { ViewProviderId } from './ViewProviderId'; +import { ViewProviderCommand } from './ViewProviderCommand'; export class RokuDeviceViewViewProvider extends BaseRdbViewProvider { public readonly id = ViewProviderId.rokuDeviceView; - constructor(context: vscode.ExtensionContext) { - super(context); + constructor(context: vscode.ExtensionContext, dependencies) { + super(context, dependencies); this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewEnableNodeInspector); this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewDisableNodeInspector); this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewRefreshScreenshot); this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewPauseScreenshotCapture); this.registerCommandWithWebViewNotifier(context, VscodeCommand.rokuDeviceViewResumeScreenshotCapture); + + this.addMessageCommandCallback(ViewProviderCommand.getScreenshot, async (message) => { + try { + const result = await this.dependencies.rtaManager.device.getScreenshot(); + this.postOrQueueMessage({ + ...message, + response: { + success: true, + arrayBuffer: result.buffer.buffer + } + }); + } catch (e) { + this.postOrQueueMessage({ + ...message, + response: { + success: false + } + }); + } + return true; + }); } } diff --git a/src/viewProviders/RokuRegistryViewProvider.spec.ts b/src/viewProviders/RokuRegistryViewProvider.spec.ts index 7f093de8..48db4ad3 100644 --- a/src/viewProviders/RokuRegistryViewProvider.spec.ts +++ b/src/viewProviders/RokuRegistryViewProvider.spec.ts @@ -35,14 +35,15 @@ afterEach(() => { }); describe('RokuRegistryViewProvider', () => { - const provider = new RokuRegistryViewProvider(vscode.context); const rtaManager = new RtaManager(); - provider.setRtaManager(rtaManager); + const provider = new RokuRegistryViewProvider(vscode.context, { + rtaManager: rtaManager + }); describe('sendRegistryUpdated', () => { - it('Triggers postOrQueueMessage to send message to web view that the registry was updated', async () => { + it('Triggers postOrQueueMessage to send message to web view that the registry was updated', () => { const spy = sinon.stub(provider as any, 'postOrQueueMessage'); - await provider['sendRegistryUpdated'](); + provider['sendRegistryUpdated'](); expect(spy.calledOnce).to.be.true; }); }); diff --git a/src/viewProviders/RokuRegistryViewProvider.ts b/src/viewProviders/RokuRegistryViewProvider.ts index 187b31e3..5568c3d4 100644 --- a/src/viewProviders/RokuRegistryViewProvider.ts +++ b/src/viewProviders/RokuRegistryViewProvider.ts @@ -7,14 +7,14 @@ import { ViewProviderId } from './ViewProviderId'; export class RokuRegistryViewProvider extends BaseRdbViewProvider { public readonly id = ViewProviderId.rokuRegistryView; - constructor(context: vscode.ExtensionContext) { - super(context); + constructor(context: vscode.ExtensionContext, dependencies) { + super(context, dependencies); const subscriptions = context.subscriptions; subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuRegistryExportRegistry, async () => { await vscode.window.showSaveDialog({ saveLabel: 'Save' }).then(async (uri) => { - const result = await this.rtaManager.onDeviceComponent?.readRegistry(); + const result = await this.dependencies.rtaManager.onDeviceComponent?.readRegistry(); await vscode.workspace.fs.writeFile(uri, Buffer.from(JSON.stringify(result?.values), 'utf8')); }); })); @@ -30,12 +30,12 @@ export class RokuRegistryViewProvider extends BaseRdbViewProvider { })); subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuRegistryClearRegistry, async () => { - await this.rtaManager.onDeviceComponent.deleteEntireRegistry(); - await this.sendRegistryUpdated(); + await this.dependencies.rtaManager.onDeviceComponent.deleteEntireRegistry(); + this.sendRegistryUpdated(); })); - subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuRegistryRefreshRegistry, async () => { - await this.sendRegistryUpdated(); + subscriptions.push(vscode.commands.registerCommand(VscodeCommand.rokuRegistryRefreshRegistry, () => { + this.sendRegistryUpdated(); })); } @@ -44,15 +44,14 @@ export class RokuRegistryViewProvider extends BaseRdbViewProvider { const input = await vscode.workspace.fs.readFile(uri[0]); const data = JSON.parse(Buffer.from(input).toString('utf8')); - await this.rtaManager.onDeviceComponent?.writeRegistry({ + await this.dependencies.rtaManager.onDeviceComponent?.writeRegistry({ values: data }); - await this.sendRegistryUpdated(); + this.sendRegistryUpdated(); } } - protected async sendRegistryUpdated() { - const result = await this.rtaManager.onDeviceComponent?.readRegistry(); - this.postOrQueueMessage({ name: ViewProviderEvent.onRegistryUpdated, values: result?.values }); + protected sendRegistryUpdated() { + this.postOrQueueMessage(this.createEventMessage(ViewProviderEvent.onRegistryUpdated)); } } diff --git a/src/viewProviders/SceneGraphInspectorViewProvider.ts b/src/viewProviders/SceneGraphInspectorViewProvider.ts index 53ef47de..73485d8c 100644 --- a/src/viewProviders/SceneGraphInspectorViewProvider.ts +++ b/src/viewProviders/SceneGraphInspectorViewProvider.ts @@ -1,13 +1,23 @@ import type * as vscode from 'vscode'; import { BaseRdbViewProvider } from './BaseRdbViewProvider'; import { ViewProviderId } from './ViewProviderId'; +import { ViewProviderCommand } from './ViewProviderCommand'; export class SceneGraphInspectorViewProvider extends BaseRdbViewProvider { public readonly id = ViewProviderId.sceneGraphInspectorView; - constructor(context: vscode.ExtensionContext) { - super(context); + constructor(context: vscode.ExtensionContext, dependencies) { + super(context, dependencies); this.registerCommandWithWebViewNotifier(context, 'extension.brightscript.sceneGraphInspectorView.refreshNodeTree'); + + this.addMessageCommandCallback(ViewProviderCommand.getStoredNodeReferences, (message) => { + const response = this.dependencies.rtaManager.getStoredNodeReferences(); + this.postOrQueueMessage({ + ...message, + response: response + }); + return Promise.resolve(true); + }); } } diff --git a/src/viewProviders/ViewProviderCommand.ts b/src/viewProviders/ViewProviderCommand.ts index 329d3e08..65621e3b 100644 --- a/src/viewProviders/ViewProviderCommand.ts +++ b/src/viewProviders/ViewProviderCommand.ts @@ -4,5 +4,8 @@ export enum ViewProviderCommand { getScreenshot = 'getScreenshot', setManualIpAddress = 'setManualIpAddress', sendMessageToWebviews = 'sendMessageToWebviews', - setVscodeContext = 'setVscodeContext' + setVscodeContext = 'setVscodeContext', + storeRokuAutomationConfigs = 'storeRokuAutomationConfigs', + runRokuAutomationConfig = 'runRokuAutomationConfig', + stopRokuAutomationConfig = 'stopRokuAutomationConfig' } diff --git a/src/viewProviders/ViewProviderEvent.ts b/src/viewProviders/ViewProviderEvent.ts index b761cced..1a475902 100644 --- a/src/viewProviders/ViewProviderEvent.ts +++ b/src/viewProviders/ViewProviderEvent.ts @@ -3,5 +3,8 @@ export enum ViewProviderEvent { onDeviceAvailabilityChange = 'onDeviceAvailabilityChange', onVscodeCommandReceived = 'onVscodeCommandReceived', onRegistryUpdated = 'onRegistryUpdated', - onStoredNodeReferencesUpdated = 'onStoredNodeReferencesUpdated' + onStoredNodeReferencesUpdated = 'onStoredNodeReferencesUpdated', + onRokuAutomationConfigsLoaded = 'onRokuAutomationConfigsLoaded', + onRokuAutomationConfigStepChange = 'onRokuAutomationConfigStepChange', + onRokuAutomationKeyPressed = 'onRokuAutomationKeyPressed' } diff --git a/src/viewProviders/ViewProviderId.ts b/src/viewProviders/ViewProviderId.ts index a5d76c39..4a4ab12f 100644 --- a/src/viewProviders/ViewProviderId.ts +++ b/src/viewProviders/ViewProviderId.ts @@ -4,5 +4,6 @@ export enum ViewProviderId { sceneGraphInspectorView = 'sceneGraphInspectorView', rokuDeviceView = 'rokuDeviceView', rokuRegistryView = 'rokuRegistryView', - rokuCommandsView = 'rokuCommandsView' + rokuCommandsView = 'rokuCommandsView', + rokuAutomationView = 'rokuAutomationView' } diff --git a/webviews/package-lock.json b/webviews/package-lock.json index 749527c0..bb537a99 100644 --- a/webviews/package-lock.json +++ b/webviews/package-lock.json @@ -10,7 +10,7 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.0", "@tsconfig/svelte": "^3.0.0", - "@vscode/webview-ui-toolkit": "^1.0.0", + "@vscode/webview-ui-toolkit": "^1.2.2", "svelte": "^3.54.0", "svelte-check": "^2.10.0", "svelte-codicons": "^0.10.1", diff --git a/webviews/package.json b/webviews/package.json index 1ddf5522..d24ae45e 100644 --- a/webviews/package.json +++ b/webviews/package.json @@ -11,7 +11,7 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^2.0.0", "@tsconfig/svelte": "^3.0.0", - "@vscode/webview-ui-toolkit": "^1.0.0", + "@vscode/webview-ui-toolkit": "^1.2.2", "svelte": "^3.54.0", "svelte-check": "^2.10.0", "svelte-codicons": "^0.10.1", diff --git a/webviews/src/main.ts b/webviews/src/main.ts index 9e35a81f..ce404989 100644 --- a/webviews/src/main.ts +++ b/webviews/src/main.ts @@ -3,12 +3,20 @@ import rokuRegistryView from './views/RokuRegistryView/RokuRegistryView.svelte'; import rokuCommandsView from './views/RokuCommandsView/RokuCommandsView.svelte'; import rokuDeviceView from './views/RokuDeviceView/RokuDeviceView.svelte'; import sceneGraphInspectorView from './views/SceneGraphInspectorView/SceneGraphInspectorView.svelte'; +import rokuAutomationView from './views/RokuAutomationView/RokuAutomationView.svelte'; +import { provideVSCodeDesignSystem, allComponents } from '@vscode/webview-ui-toolkit'; + import './style.css'; //write toolkit to window this to prevent svelte from tree-shaking it import * as toolkit from '@vscode/webview-ui-toolkit/dist/toolkit'; (window as any).___toolkit = toolkit; +// In order to use the Webview UI Toolkit web components they +// must be registered with the browser (i.e. webview) using the +// syntax below. +provideVSCodeDesignSystem().register(allComponents); + // Provided by ViewProviders declare const viewName; @@ -17,7 +25,8 @@ const views = { rokuRegistryView, rokuCommandsView, rokuDeviceView, - sceneGraphInspectorView + sceneGraphInspectorView, + rokuAutomationView }; const app = new views[viewName]({ diff --git a/webviews/src/shared/NumberField.svelte b/webviews/src/shared/NumberField.svelte new file mode 100644 index 00000000..988113bd --- /dev/null +++ b/webviews/src/shared/NumberField.svelte @@ -0,0 +1,46 @@ + + + + + + + + diff --git a/webviews/src/views/RokuAutomationView/RokuAutomationView.svelte b/webviews/src/views/RokuAutomationView/RokuAutomationView.svelte new file mode 100644 index 00000000..0b3a5c2e --- /dev/null +++ b/webviews/src/views/RokuAutomationView/RokuAutomationView.svelte @@ -0,0 +1,306 @@ + + + + + + + +
+ + {#each steps as step, index} + + + + + + + + + {/each} + + + +
+ {#if index > 0} + + + + {/if} + {#if index < steps.length - 1} + + + + {/if} + + + {#each Object.entries(stepTypes) as [stepType, stepTypeParams]} + {stepTypeParams.name} + {/each} + + + {#if step.type === stepTypes.sleep.type} + + {:else if step.type === stepTypes.sendKeyPress.type} + + {#each Object.entries(availableKeys) as [key, text]} + {text} + {/each} + + {:else if step.type === stepTypes.sendText.type} + + {/if} + + {#if currentRunningStep === -1} + + {:else if currentRunningStep === index} + + {/if} +
+ +
+ +
+
+ +
+ {#if currentRunningStep >= 0} + Stop + {:else} + Run + Clear + {/if} +
diff --git a/webviews/src/views/RokuCommandsView/RokuCommandsView.svelte b/webviews/src/views/RokuCommandsView/RokuCommandsView.svelte index 2bcdbd37..2c387a4e 100644 --- a/webviews/src/views/RokuCommandsView/RokuCommandsView.svelte +++ b/webviews/src/views/RokuCommandsView/RokuCommandsView.svelte @@ -92,7 +92,7 @@ let odcAvailable = true; intermediary.observeEvent(ViewProviderEvent.onDeviceAvailabilityChange, (message) => { - odcAvailable = message.odcAvailable; + odcAvailable = message.context.odcAvailable; }); // Required by any view so we can know that the view is ready to receive messages diff --git a/webviews/src/views/RokuDeviceView/RokuDeviceView.svelte b/webviews/src/views/RokuDeviceView/RokuDeviceView.svelte index ca7ceecd..f2368686 100644 --- a/webviews/src/views/RokuDeviceView/RokuDeviceView.svelte +++ b/webviews/src/views/RokuDeviceView/RokuDeviceView.svelte @@ -15,7 +15,7 @@ let deviceAvailable = false; intermediary.observeEvent(ViewProviderEvent.onDeviceAvailabilityChange, (message) => { - deviceAvailable = message.deviceAvailable; + deviceAvailable = message.context.deviceAvailable; requestScreenshot(); }); @@ -79,16 +79,18 @@ ref: focusedTreeNode.ref } - intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, { - event: ViewProviderEvent.onTreeNodeFocused, + const message = intermediary.createEventMessage(ViewProviderEvent.onTreeNodeFocused, { treeNode: treeNode }); + + intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, message); } } else { - intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, { - event: ViewProviderEvent.onTreeNodeFocused, + const message = intermediary.createEventMessage(ViewProviderEvent.onTreeNodeFocused, { treeNode: null }); + + intermediary.sendMessageToWebviews(ViewProviderId.sceneGraphInspectorView, message); } } } @@ -183,7 +185,7 @@ } intermediary.observeEvent(ViewProviderEvent.onVscodeCommandReceived, async (message) => { - const name = message.commandName; + const name = message.context.commandName; if (name === VscodeCommand.rokuDeviceViewEnableNodeInspector) { wasRunningScreenshotCaptureBeforeInspect = enableScreenshotCapture; isInspectingNodes = true; @@ -242,8 +244,9 @@ } else { if (!screenshotOutOfDateTimeOut) { screenshotOutOfDateTimeOut = setTimeout(() => { - screenshotOutOfDate = true; - }, 2000); + // screenshotOutOfDate = true; + console.log('screenshot out of date') + }, 10000); } setTimeout(() => { requestScreenshot(); diff --git a/webviews/src/views/RokuRegistryView/RokuRegistryView.svelte b/webviews/src/views/RokuRegistryView/RokuRegistryView.svelte index 2853c811..d00fc0ae 100644 --- a/webviews/src/views/RokuRegistryView/RokuRegistryView.svelte +++ b/webviews/src/views/RokuRegistryView/RokuRegistryView.svelte @@ -14,7 +14,7 @@ let odcAvailable = false; intermediary.observeEvent(ViewProviderEvent.onDeviceAvailabilityChange, async (message) => { - odcAvailable = message.odcAvailable; + odcAvailable = message.context.odcAvailable; if (odcAvailable) { loading = true; const { values } = await odc.readRegistry(); @@ -25,8 +25,11 @@ } }); - intermediary.observeEvent(ViewProviderEvent.onRegistryUpdated, (message) => { - registryValues = registryView.formatValues(message.values); + intermediary.observeEvent(ViewProviderEvent.onRegistryUpdated, async (message) => { + loading = true; + const { values } = await odc.readRegistry(); + registryValues = registryView.formatValues(values); + loading = false; }); // Required by any view so we can know that the view is ready to receive messages diff --git a/webviews/src/views/SceneGraphInspectorView/ColorField.svelte b/webviews/src/views/SceneGraphInspectorView/ColorField.svelte index d4a64ddc..ad3dd294 100644 --- a/webviews/src/views/SceneGraphInspectorView/ColorField.svelte +++ b/webviews/src/views/SceneGraphInspectorView/ColorField.svelte @@ -31,10 +31,13 @@ value = hexColor; // Triggers update to be sent to parent's on:input dispatch('input'); - } catch {} + } catch(e) { + console.log('convert failed', e) + } } let textColor: string; + export let self = null; -
diff --git a/webviews/src/views/SceneGraphInspectorView/NodeDetailPage.svelte b/webviews/src/views/SceneGraphInspectorView/NodeDetailPage.svelte index 9630d824..37dec305 100644 --- a/webviews/src/views/SceneGraphInspectorView/NodeDetailPage.svelte +++ b/webviews/src/views/SceneGraphInspectorView/NodeDetailPage.svelte @@ -4,20 +4,35 @@ import { odc } from '../../ExtensionIntermediary'; import { utils } from '../../utils'; import ColorField from './ColorField.svelte'; + import NumberField from '../../shared/NumberField.svelte'; import Chevron from '../../shared/Chevron.svelte'; import { Refresh, Discard, ArrowLeft, Move, Key } from 'svelte-codicons'; export let inspectNodeSubtype: string; + // Key path for pulling info export let inspectNodeBaseKeyPath: BaseKeyPath | null; export let inspectNodeTreeNode: TreeNode | null; + $: { + // Updated persistentBaseKeyPath whenever inspectNodeTreeNode changes + if (inspectNodeTreeNode) { + persistentBaseKeyPath = { + keyPath: inspectNodeTreeNode.keyPath + }; + } + } + // Key path for use in automated tests where it must persist across runs + export let persistentBaseKeyPath: BaseKeyPath | null = null; let inspectChildNodeSubtype: string; let inspectChildNodeBaseKeyPath: BaseKeyPath | null; + let persistentChildBaseKeyPath: BaseKeyPath | null; let showKeyPathInfo = utils.getStorageBooleanValue('showKeyPathInfo'); $: { utils.setStorageValue('showKeyPathInfo', showKeyPathInfo); } + let expandedCollectionFields = {}; + function close() { if (autoRefreshInterval) { @@ -26,7 +41,7 @@ inspectNodeBaseKeyPath = null; } - let numberInputsStep = 1; + let numberInputsStep = '1'; let fields = {} as { [key: string]: { @@ -78,19 +93,19 @@ function onNumberFieldChange() { const value = Number(this.value); - handleResetValueButtonDisplay(this, value); + handleResetValueButtonDisplay(this.self, value); setValue(this.id, value); } function onVector2dFieldChange() { const id = this.id; const values = []; - for (const element of this.parentElement.children) { + for (const element of this.self.parentElement.children) { if (element.id === id) { values.push(Number(element.value)); } } - handleResetValueButtonDisplay(this, values); + handleResetValueButtonDisplay(this.self, values); setValue(id, values); } @@ -100,7 +115,7 @@ } function onColorFieldChange() { - handleResetValueButtonDisplay(this); + handleResetValueButtonDisplay(this.self); setValue(this.id, this.value); } @@ -114,6 +129,10 @@ function onNodeClicked() { inspectChildNodeSubtype = this.textContent; + + persistentChildBaseKeyPath = { + keyPath: persistentBaseKeyPath.keyPath ? persistentBaseKeyPath.keyPath + '.' + this.id : this.id + } inspectChildNodeBaseKeyPath = { ...inspectNodeBaseKeyPath, keyPath: inspectNodeBaseKeyPath.keyPath ? inspectNodeBaseKeyPath.keyPath + '.' + this.id : this.id @@ -126,7 +145,7 @@ } const id = element.id; - let valueChanged = (newValue !== fields[id].value); + let valueChanged = (newValue !== fields[id]?.value); if (newValue instanceof Array) { valueChanged = false; for (const [i, item] of newValue.entries()) { @@ -136,7 +155,8 @@ } } } - for (const child of element.parentElement.children) { + + for (const child of element.parentElement.previousElementSibling.children) { if (child.classList.contains('resetValueButton')) { if (valueChanged) { child.classList.remove('hide'); @@ -151,7 +171,7 @@ function onResetValueButtonClicked() { const elements = []; // Find the elements we want to reset based on their relationship to the reset button - for (const child of this.parentElement.children) { + for (const child of this.parentElement.nextElementSibling.children) { if (child.classList.contains('fieldValue')) { elements.push(child); }; @@ -161,15 +181,17 @@ // If we got one then it's a standard value const element = elements[0] const id = element.id; - let eventType = 'input'; - if (element.type === 'checkbox') { - eventType = 'click'; + if (element.checked === true || element.checked === false) { element.checked = fields[id].value; + // If we dispatch the event like before the new value gets overwritten + onBooleanFieldClick.call(element); } else { element.value = fields[id].value; + // Have to manually trigger the observer + element.dispatchEvent(new Event('input')); } - // Have to manually trigger the observer - element.dispatchEvent(new Event(eventType)); + + } else if (elements.length === 2) { // If we got two then it's for vector2d field and so we have to update both inputs const xElement = elements[0]; @@ -194,7 +216,7 @@ close(); break; case 'Shift': - numberInputsStep = 15; + numberInputsStep = '15'; break; } } @@ -203,7 +225,7 @@ const key = event.key; switch (key) { case 'Shift': - numberInputsStep = 1; + numberInputsStep = '1'; break; } } @@ -247,7 +269,27 @@ } function toggleShowingBraceOrBracketContent() { - this.nextElementSibling.classList.toggle('hide'); + expandedCollectionFields[this.id] = !expandedCollectionFields[this.id]; + } + + + function formatFieldTitle(input) { + let output = ""; + let word = ""; + + for (let i = 0; i < input.length; i++) { + if (i > 0 && input[i] === input[i].toUpperCase() && input[i - 1] !== " ") { + output += `${word}`; + word = ""; + } + word += input[i]; + } + + if (word !== "") { + output += `${word}:`; + } + + return output; } @@ -276,16 +318,6 @@ border-bottom: 2px solid rgb(190, 190, 190); } - button { - padding: 2px 5px; - font-size: 12px; - border: none; - margin: 0; - cursor: pointer; - outline: none; - display: inline-block; - } - #baseKeyPathContainer { padding: 3px 10px; border-bottom: 2px solid rgb(190, 190, 190); @@ -309,52 +341,36 @@ #nodeSubtype { user-select: text; + padding: 0 10px 0 5px; } - ul { - margin: 5px; - list-style: none; - padding: 0; - } - - li { - padding: 0 5px 10px; + table { + border-spacing: 0; + width: 100%; } - label { - font-weight: bold; - padding-right: 5px; + td { + --input-min-width: 30px; + padding: 5px 3px 3px 5px; } - input[type='number'] { - width: 50px; + tr:nth-child(even) { + background-color: var(--vscode-editorInlayHint-parameterBackground); } - input[type='checkbox'] { - position: relative; - top: 2px; - } - - .inline { - display: inline; - width: auto; - } - - .collectionItems { - padding: 3px 0 3px 15px; - display: block; + label { + font-weight: bold; } - .collectionItems .collectionItemId { - font-weight: bold; + .collectionItem { + background-color: var(--vscode-editor-background); } - button { - cursor: pointer; + vscode-button, vscode-text-field { + vertical-align: middle; } - .openingBrace, - .openingBracket { + .braceOrBracket { cursor: pointer; user-select: none; } @@ -370,245 +386,268 @@
-{#if showKeyPathInfo && inspectNodeTreeNode} +{#if showKeyPathInfo && persistentBaseKeyPath}
"base": "scene",
- "keyPath": "{inspectNodeTreeNode.keyPath}" + "keyPath": "{persistentBaseKeyPath.keyPath}"
{/if} - - - {#if children.length > 0} -
- - - -
children ({children.length})
-
-
- {#each children as child, i} -
{i}: -
- {/each} -
+{#if children.length > 0} +
+ + + +
children ({children.length})
+
+
+ {#each children as child, i} +
+ {i}: + {child.subtype} +
+ {/each}
- {/if} +
+{/if} -
    + {#each Object.entries(fields) as [id, field]} -
  • - - +
  • + + +
    + + + + + + + {#if field.value === null} Invalid {:else if field.fieldType === 'vector2d'} - - - - {#if id !== 'scale'} - - - - {/if} - - - - + + + {#if id !== 'scale'} + + + + {/if} {:else if field.fieldType === 'color'} {:else if field.type === 'roBoolean'} - {:else if field.type === 'roFloat' || field.type === 'roInt'} - {:else if field.type === 'roAssociativeArray'} { -
    - {#each Object.entries(field.value) as [collectionItemId, item]} -
    - {collectionItemId}: - {#if utils.isObjectWithProperty(item, 'subtype')} - {:else if typeof item === 'boolean'} - {:else if typeof item === 'object'} - {JSON.stringify( - item - )}{:else if typeof item === 'number'} - {:else} - {/if}{#if Object.entries(field.value).pop()[0] !== collectionItemId},{/if} - - - -
    - {/each} -
    - } + {id} + class="braceOrBracket" + on:click={toggleShowingBraceOrBracketContent}> + { + {#if !expandedCollectionFields[id]}}{/if} + {:else if field.type === 'roArray'} [ - {#each field.value as item, collectionItemId} -
    - {collectionItemId}: - {#if utils.isObjectWithProperty(item, 'subtype')} - {:else if typeof item === 'object'} - {JSON.stringify( - item - )}{:else if typeof item === 'number'} - {:else if typeof item === 'boolean'} - {:else} - {/if}{#if collectionItemId + 1 < field.value.length},{/if} - - - -
    - {/each} - ] + {id} + class="braceOrBracket" + on:click={toggleShowingBraceOrBracketContent}> + [ + {#if !expandedCollectionFields[id]}]{/if} + {:else if field.type === 'roSGNode' || field.fieldType === 'node'} - + {field.value.subtype} {:else if field.type === 'roString' || field.fieldType == 'string'} - {:else} -