├── .eslintrc.cjs ├── .github └── workflows │ └── companion-module-checks.yaml ├── .gitignore ├── .prettierignore ├── HELP.md ├── LICENSE ├── README.md ├── companion ├── HELP.md └── manifest.json ├── index.js ├── package-lock.json ├── package.json ├── src ├── actions.js ├── feedback.js ├── presets.js ├── tcp.js ├── timer.js ├── upgrades.js └── utils.js └── utils ├── README.md ├── companion steps.png └── launch_h2r.ahk /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: './node_modules/@companion-module/tools/eslint/main.cjs', 3 | } 4 | -------------------------------------------------------------------------------- /.github/workflows/companion-module-checks.yaml: -------------------------------------------------------------------------------- 1 | name: Companion Module Checks 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | check: 8 | name: Check module 9 | 10 | if: ${{ !contains(github.repository, 'companion-module-template-') }} 11 | 12 | permissions: 13 | packages: read 14 | 15 | uses: bitfocus/actions/.github/workflows/module-checks.yaml@main 16 | # with: 17 | # upload-artifact: true # uncomment this to upload the built package as an artifact to this workflow that you can download and share with others 18 | 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /pkg 3 | /pkg.tgz 4 | DEBUG-PACKAGED -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | package.json 2 | pkg -------------------------------------------------------------------------------- /HELP.md: -------------------------------------------------------------------------------- 1 | ## H2R Graphics v2 2 | 3 | Use this module to send commands to H2R Graphics. Be sure to check your IP address, Port and Project ID all from the H2R Graphics launcher. 4 | 5 | **Available commands** 6 | 7 | - Run 8 | - Hide all 9 | - Show/Hide graphics 10 | - Update contents of graphics 11 | - Change Position, Offset and scale 12 | - Set custom themes to each graphic 13 | 14 | ## H2R Graphics v1 15 | 16 | Use this module to send OSC messages to your H2R Graphics software. By default, the OSC listening port of the software is 8181. 17 | 18 | **Available commands** 19 | 20 | - Clear all graphics 21 | - Lower Thirds - Show 22 | - Lower Thirds - Hide 23 | - Ticker Show/Hide 24 | - Timer - Pause/Resume 25 | - Timer Show/Hide 26 | - Timer - Custom UP 27 | - Timer - Custom DOWN 28 | - Timer - Custom Down to Time of Day 29 | - Timer - Current Time of Day 30 | - Timer - Set pre-timer message 31 | - Stopwatch 32 | - Logo Show/Hide 33 | - Message Show/Hide 34 | - Message - Set a custom message 35 | - Break Show/Hide 36 | - Chat Hide 37 | - Image Next/Previous/hide 38 | - Image - Show Specific 39 | - Score Show/Hide 40 | - Score - Increase/Decrease specific team by specific amount 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Bitfocus AS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # companion-module-h2r-graphics 2 | 3 | See HELP.md and LICENSE 4 | 5 | # Module Development 6 | 7 | ## Pushing changes for inclusion in the beta 8 | 9 | 1) Push all changes to the repo 10 | 2) Use `npm version major|minor|patch` to bump the version number 11 | 3) Use `git push --follow-tags` to push the new version number. 12 | 4) Reach out on the `#module-development` channel in Slack to get the new changes included in the next beta. 13 | 14 | ## Changelog 15 | 16 | **v3.7.0** 17 | 18 | - New: Refresh Webpage graphic action. 19 | - New: Use internal variable in `addVariableSelectRow` action. 20 | 21 | **v3.6.0** 22 | 23 | - New: Score variables added for each score level and a collective team score. 24 | - New: Draw on screen presets added. 25 | - Fix: List "Add row" and "Select row" now accept variables as the list number. 26 | 27 | **v3.5.0** 28 | 29 | - New: Use Companion variables when setting `text.x` values. 30 | - New: Use Companion variables when adding rows to lists. 31 | - New: Parse `[listX.rowY.cellZ]` variables and show them on Companion buttons. 32 | - New: Use graphic `labels` on presets (option in settings). 33 | - New: `Toggle Cue on/off` status change for graphics. 34 | 35 | **v3.4.0** 36 | 37 | - New: Social variables added. 38 | - New: Clear Map pins action. 39 | - Fix: PNG toggle in config now working as expected. 40 | 41 | **v3.3.0** 42 | 43 | - New: Show/Hide graphic (using Text or Variable). 44 | - New: Autohotkey instructions added for automating and launching H2R Graphics. 45 | - New: Preset updates for Big timers and Image Sequence graphics. 46 | - Fix: Timer logic refactored. 47 | 48 | **v3.2.0** 49 | 50 | - New: New timer graphics added. 51 | - New: Set transition override for any graphic. 52 | - New: Set and show Speaker Timer message. 53 | - Fix: Lower Third animated Line Two not working as expected. 54 | 55 | **v3.1.1** 56 | 57 | - Package.json cleanup 58 | - Remove pkg from Github 59 | 60 | **v3.1.0** 61 | 62 | - Support for new Utility graphics 63 | - Fix for crashing when user's project had no Dynamic Text 64 | 65 | **v3.0.1** 66 | 67 | - Cleanup and help.md improvements 68 | 69 | **v3.0.0** 70 | 71 | - Support for Companion v3.x 72 | - Removal of H2R Graphics v1 support. 73 | 74 | **v2.2.0** 75 | 76 | - Now supporting `Text` and `List` variables. 77 | - Added `Now next then`, `Map`, `Checklist` and `QR code icons`. 78 | - Fix: Select List index when setting and adding to Varaible Lists. 79 | 80 | **v2.1.0** 81 | 82 | - Support for more graphic types. 83 | - Rename "Two Line" to "Animated Lower Third". 84 | - Hiding some error logs for failed feedbacks. 85 | 86 | **v2.0.0** 87 | 88 | - Completely re-written to allow for switching between H2R Graphics v1 and v2 89 | -------------------------------------------------------------------------------- /companion/HELP.md: -------------------------------------------------------------------------------- 1 | ## H2R Graphics 2 | 3 | Use this module to send commands to H2R Graphics. Be sure to check your IP address, Port and Project ID all from the H2R Graphics launcher. 4 | 5 | **Available commands** 6 | 7 | - Run 8 | - Hide all 9 | - Show/Hide graphics 10 | - Update contents of graphics 11 | - Change Position, Offset and scale 12 | - Set custom themes to each graphic 13 | - Use H2R Graphics `text` and `list` variables within your Companion UI 14 | -------------------------------------------------------------------------------- /companion/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "h2r-graphics", 3 | "name": "h2r-graphics", 4 | "shortname": "H2R Graphics", 5 | "description": "H2R Graphics module for Companion", 6 | "version": "0.0.0", 7 | "license": "MIT", 8 | "repository": "git+https://github.com/bitfocus/companion-module-h2r-graphics.git", 9 | "bugs": "https://github.com/bitfocus/companion-module-h2r-graphics/issues", 10 | "maintainers": [ 11 | { 12 | "name": "John Barker", 13 | "email": "john@heretorecord.com" 14 | } 15 | ], 16 | "legacyIds": ["graphics"], 17 | "runtime": { 18 | "type": "node18", 19 | "api": "nodejs-ipc", 20 | "apiVersion": "0.0.0", 21 | "entrypoint": "../index.js" 22 | }, 23 | "manufacturer": "Here to Record", 24 | "products": ["H2R Graphics"], 25 | "keywords": ["Graphics", "Overlays"] 26 | } 27 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import { InstanceBase, runEntrypoint } from '@companion-module/base' 2 | import { upgrade } from './src/upgrades.js' 3 | import { init_http } from './src/tcp.js' 4 | import { actionsV2 } from './src/actions.js' 5 | import { initPresets } from './src/presets.js' 6 | import { initFeedbacks } from './src/feedback.js' 7 | 8 | class H2RGraphicsInstance extends InstanceBase { 9 | constructor(internal) { 10 | super(internal) 11 | } 12 | 13 | async init(config) { 14 | this.config = config 15 | 16 | this.updateActions() 17 | 18 | init_http(this) 19 | } 20 | // When module gets deleted 21 | async destroy() { 22 | this.log('debug', 'destroy') 23 | } 24 | 25 | async configUpdated(config) { 26 | this.config = config 27 | } 28 | 29 | // Return config fields for web config 30 | getConfigFields() { 31 | return [ 32 | { 33 | type: 'textinput', 34 | id: 'host', 35 | label: 'Target IP', 36 | width: 6, 37 | default: '127.0.0.1', 38 | regex: this.REGEX_IP, 39 | }, 40 | { 41 | type: 'textinput', 42 | id: 'portV2', 43 | label: 'Target Port', 44 | width: 3, 45 | default: '4001', 46 | regex: this.REGEX_PORT, 47 | }, 48 | { 49 | type: 'textinput', 50 | id: 'projectId', 51 | label: 'Project ID', 52 | width: 3, 53 | default: 'ABCD', 54 | }, 55 | { 56 | type: 'dropdown', 57 | id: 'usePngForPresets', 58 | label: 'Show PNG heading on Presets', 59 | width: 6, 60 | default: 'true', 61 | choices: [ 62 | { id: 'true', label: 'Yes' }, 63 | { id: 'false', label: 'No' }, 64 | ], 65 | }, 66 | { 67 | type: 'dropdown', 68 | id: 'useLabelForPresets', 69 | label: 'Use graphic label on Presets', 70 | width: 6, 71 | default: 'false', 72 | choices: [ 73 | { id: 'true', label: 'Yes' }, 74 | { id: 'false', label: 'No' }, 75 | ], 76 | }, 77 | { 78 | type: 'dropdown', 79 | id: 'presetButtonTextSize', 80 | label: 'Preset Button Text Size', 81 | width: 6, 82 | default: '18', 83 | allowCustom: true, 84 | regex: '/^(?:[0-9]+|auto)$/', 85 | choices: [ 86 | { id: 'auto', label: 'Auto' }, 87 | { id: '7', label: '7pt' }, 88 | { id: '14', label: '14pt' }, 89 | { id: '18', label: '18pt' }, 90 | { id: '24', label: '24pt' }, 91 | { id: '30', label: '30pt' }, 92 | { id: '33', label: '44pt' }, 93 | ], 94 | }, 95 | { 96 | type: 'dropdown', 97 | id: 'lowerThirdPresetLabelSource', 98 | label: 'Text Format for Lower Third Preset Buttons', 99 | width: 6, 100 | default: 'contents', 101 | choices: [ 102 | { id: 'contents', label: 'Line 1, Line 2' }, 103 | { id: 'first_line', label: 'Line 1' }, 104 | { id: 'label', label: 'Label (shows ID if label is empty)' }, 105 | ], 106 | }, 107 | ] 108 | } 109 | 110 | updateActions() { 111 | this.setActionDefinitions(actionsV2(this)) 112 | } 113 | 114 | updatePresets() { 115 | const presets = initPresets(this) 116 | this.setPresetDefinitions(presets) 117 | } 118 | updateFeedbacks() { 119 | const feedbacks = initFeedbacks(this) 120 | this.log('debug', JSON.stringify(feedbacks)) 121 | this.setFeedbackDefinitions(feedbacks) 122 | } 123 | } 124 | 125 | runEntrypoint(H2RGraphicsInstance, upgrade) 126 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "h2r-graphics", 3 | "version": "3.7.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "h2r-graphics", 9 | "version": "3.7.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@companion-module/base": "^1.11.3", 13 | "got": "^13.0.0", 14 | "socket.io-client": "^4.6.0" 15 | }, 16 | "devDependencies": { 17 | "@companion-module/tools": "^2.2.2", 18 | "eslint": "^9.23.0" 19 | } 20 | }, 21 | "node_modules/@aashutoshrathi/word-wrap": { 22 | "version": "1.2.6", 23 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", 24 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", 25 | "dev": true, 26 | "engines": { 27 | "node": ">=0.10.0" 28 | } 29 | }, 30 | "node_modules/@companion-module/base": { 31 | "version": "1.11.3", 32 | "resolved": "https://registry.npmjs.org/@companion-module/base/-/base-1.11.3.tgz", 33 | "integrity": "sha512-6oVmvtLguDly+zcSN86D0Z++yI60oeH3X/gumJ1FdBkZjdozlKFAsSykIvYQ0QIs+SMFRh1C9M/F6egOVT/RMA==", 34 | "dependencies": { 35 | "ajv": "^8.17.1", 36 | "colord": "^2.9.3", 37 | "ejson": "^2.2.3", 38 | "eventemitter3": "^5.0.1", 39 | "mimic-fn": "^3.1.0", 40 | "nanoid": "^3.3.8", 41 | "p-queue": "^6.6.2", 42 | "p-timeout": "^4.1.0", 43 | "tslib": "^2.8.1" 44 | }, 45 | "engines": { 46 | "node": "^18.12 || ^22.8" 47 | } 48 | }, 49 | "node_modules/@companion-module/base/node_modules/eventemitter3": { 50 | "version": "5.0.1", 51 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", 52 | "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" 53 | }, 54 | "node_modules/@companion-module/tools": { 55 | "version": "2.2.2", 56 | "resolved": "https://registry.npmjs.org/@companion-module/tools/-/tools-2.2.2.tgz", 57 | "integrity": "sha512-zaNLqb8fnGZxzDaF6w08Q7nczpyNwp5/bMc1WxKV5A/HSChGAFUSQi5NbH11kMavVvw7pqG8o1wagQZ7sPARKg==", 58 | "dev": true, 59 | "dependencies": { 60 | "@eslint/js": "^9.19.0", 61 | "eslint-config-prettier": "^10.0.1", 62 | "eslint-plugin-n": "^17.15.1", 63 | "eslint-plugin-prettier": "^5.2.3", 64 | "find-up": "^7.0.0", 65 | "parse-author": "^2.0.0", 66 | "semver": "^7.7.1", 67 | "tar": "^7.4.3", 68 | "webpack": "^5.97.1", 69 | "webpack-cli": "^6.0.1", 70 | "zx": "^8.3.2" 71 | }, 72 | "bin": { 73 | "companion-generate-manifest": "scripts/generate-manifest.js", 74 | "companion-module-build": "scripts/build.js", 75 | "companion-module-check": "scripts/check.js" 76 | }, 77 | "engines": { 78 | "node": "^18.18 || ^22.8" 79 | }, 80 | "peerDependencies": { 81 | "@companion-module/base": "^1.11.0", 82 | "eslint": "^9.0.0", 83 | "prettier": "^3.0.0", 84 | "typescript-eslint": "^8.2.0" 85 | }, 86 | "peerDependenciesMeta": { 87 | "eslint": { 88 | "optional": true 89 | }, 90 | "prettier": { 91 | "optional": true 92 | }, 93 | "typescript-eslint": { 94 | "optional": true 95 | } 96 | } 97 | }, 98 | "node_modules/@discoveryjs/json-ext": { 99 | "version": "0.6.3", 100 | "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", 101 | "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", 102 | "dev": true, 103 | "engines": { 104 | "node": ">=14.17.0" 105 | } 106 | }, 107 | "node_modules/@eslint-community/eslint-utils": { 108 | "version": "4.5.1", 109 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz", 110 | "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==", 111 | "dev": true, 112 | "dependencies": { 113 | "eslint-visitor-keys": "^3.4.3" 114 | }, 115 | "engines": { 116 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 117 | }, 118 | "funding": { 119 | "url": "https://opencollective.com/eslint" 120 | }, 121 | "peerDependencies": { 122 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" 123 | } 124 | }, 125 | "node_modules/@eslint-community/regexpp": { 126 | "version": "4.12.1", 127 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", 128 | "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", 129 | "dev": true, 130 | "engines": { 131 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0" 132 | } 133 | }, 134 | "node_modules/@eslint/config-array": { 135 | "version": "0.19.2", 136 | "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", 137 | "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", 138 | "dev": true, 139 | "dependencies": { 140 | "@eslint/object-schema": "^2.1.6", 141 | "debug": "^4.3.1", 142 | "minimatch": "^3.1.2" 143 | }, 144 | "engines": { 145 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 146 | } 147 | }, 148 | "node_modules/@eslint/config-helpers": { 149 | "version": "0.2.1", 150 | "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.1.tgz", 151 | "integrity": "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==", 152 | "dev": true, 153 | "engines": { 154 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 155 | } 156 | }, 157 | "node_modules/@eslint/core": { 158 | "version": "0.12.0", 159 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", 160 | "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", 161 | "dev": true, 162 | "dependencies": { 163 | "@types/json-schema": "^7.0.15" 164 | }, 165 | "engines": { 166 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 167 | } 168 | }, 169 | "node_modules/@eslint/eslintrc": { 170 | "version": "3.3.1", 171 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", 172 | "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", 173 | "dev": true, 174 | "dependencies": { 175 | "ajv": "^6.12.4", 176 | "debug": "^4.3.2", 177 | "espree": "^10.0.1", 178 | "globals": "^14.0.0", 179 | "ignore": "^5.2.0", 180 | "import-fresh": "^3.2.1", 181 | "js-yaml": "^4.1.0", 182 | "minimatch": "^3.1.2", 183 | "strip-json-comments": "^3.1.1" 184 | }, 185 | "engines": { 186 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 187 | }, 188 | "funding": { 189 | "url": "https://opencollective.com/eslint" 190 | } 191 | }, 192 | "node_modules/@eslint/eslintrc/node_modules/ajv": { 193 | "version": "6.12.6", 194 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 195 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 196 | "dev": true, 197 | "dependencies": { 198 | "fast-deep-equal": "^3.1.1", 199 | "fast-json-stable-stringify": "^2.0.0", 200 | "json-schema-traverse": "^0.4.1", 201 | "uri-js": "^4.2.2" 202 | }, 203 | "funding": { 204 | "type": "github", 205 | "url": "https://github.com/sponsors/epoberezkin" 206 | } 207 | }, 208 | "node_modules/@eslint/eslintrc/node_modules/globals": { 209 | "version": "14.0.0", 210 | "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", 211 | "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", 212 | "dev": true, 213 | "engines": { 214 | "node": ">=18" 215 | }, 216 | "funding": { 217 | "url": "https://github.com/sponsors/sindresorhus" 218 | } 219 | }, 220 | "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { 221 | "version": "0.4.1", 222 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 223 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 224 | "dev": true 225 | }, 226 | "node_modules/@eslint/js": { 227 | "version": "9.23.0", 228 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.23.0.tgz", 229 | "integrity": "sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==", 230 | "dev": true, 231 | "engines": { 232 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 233 | } 234 | }, 235 | "node_modules/@eslint/object-schema": { 236 | "version": "2.1.6", 237 | "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", 238 | "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", 239 | "dev": true, 240 | "engines": { 241 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 242 | } 243 | }, 244 | "node_modules/@eslint/plugin-kit": { 245 | "version": "0.2.8", 246 | "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", 247 | "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", 248 | "dev": true, 249 | "dependencies": { 250 | "@eslint/core": "^0.13.0", 251 | "levn": "^0.4.1" 252 | }, 253 | "engines": { 254 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 255 | } 256 | }, 257 | "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { 258 | "version": "0.13.0", 259 | "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", 260 | "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", 261 | "dev": true, 262 | "dependencies": { 263 | "@types/json-schema": "^7.0.15" 264 | }, 265 | "engines": { 266 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 267 | } 268 | }, 269 | "node_modules/@humanfs/core": { 270 | "version": "0.19.1", 271 | "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", 272 | "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", 273 | "dev": true, 274 | "engines": { 275 | "node": ">=18.18.0" 276 | } 277 | }, 278 | "node_modules/@humanfs/node": { 279 | "version": "0.16.6", 280 | "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", 281 | "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", 282 | "dev": true, 283 | "dependencies": { 284 | "@humanfs/core": "^0.19.1", 285 | "@humanwhocodes/retry": "^0.3.0" 286 | }, 287 | "engines": { 288 | "node": ">=18.18.0" 289 | } 290 | }, 291 | "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { 292 | "version": "0.3.1", 293 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", 294 | "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", 295 | "dev": true, 296 | "engines": { 297 | "node": ">=18.18" 298 | }, 299 | "funding": { 300 | "type": "github", 301 | "url": "https://github.com/sponsors/nzakas" 302 | } 303 | }, 304 | "node_modules/@humanwhocodes/module-importer": { 305 | "version": "1.0.1", 306 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", 307 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", 308 | "dev": true, 309 | "engines": { 310 | "node": ">=12.22" 311 | }, 312 | "funding": { 313 | "type": "github", 314 | "url": "https://github.com/sponsors/nzakas" 315 | } 316 | }, 317 | "node_modules/@humanwhocodes/retry": { 318 | "version": "0.4.2", 319 | "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", 320 | "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", 321 | "dev": true, 322 | "engines": { 323 | "node": ">=18.18" 324 | }, 325 | "funding": { 326 | "type": "github", 327 | "url": "https://github.com/sponsors/nzakas" 328 | } 329 | }, 330 | "node_modules/@isaacs/fs-minipass": { 331 | "version": "4.0.1", 332 | "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", 333 | "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", 334 | "dev": true, 335 | "dependencies": { 336 | "minipass": "^7.0.4" 337 | }, 338 | "engines": { 339 | "node": ">=18.0.0" 340 | } 341 | }, 342 | "node_modules/@jridgewell/gen-mapping": { 343 | "version": "0.3.8", 344 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", 345 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", 346 | "dev": true, 347 | "dependencies": { 348 | "@jridgewell/set-array": "^1.2.1", 349 | "@jridgewell/sourcemap-codec": "^1.4.10", 350 | "@jridgewell/trace-mapping": "^0.3.24" 351 | }, 352 | "engines": { 353 | "node": ">=6.0.0" 354 | } 355 | }, 356 | "node_modules/@jridgewell/resolve-uri": { 357 | "version": "3.1.2", 358 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 359 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 360 | "dev": true, 361 | "engines": { 362 | "node": ">=6.0.0" 363 | } 364 | }, 365 | "node_modules/@jridgewell/set-array": { 366 | "version": "1.2.1", 367 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 368 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 369 | "dev": true, 370 | "engines": { 371 | "node": ">=6.0.0" 372 | } 373 | }, 374 | "node_modules/@jridgewell/source-map": { 375 | "version": "0.3.6", 376 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", 377 | "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", 378 | "dev": true, 379 | "dependencies": { 380 | "@jridgewell/gen-mapping": "^0.3.5", 381 | "@jridgewell/trace-mapping": "^0.3.25" 382 | } 383 | }, 384 | "node_modules/@jridgewell/sourcemap-codec": { 385 | "version": "1.5.0", 386 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 387 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 388 | "dev": true 389 | }, 390 | "node_modules/@jridgewell/trace-mapping": { 391 | "version": "0.3.25", 392 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 393 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 394 | "dev": true, 395 | "dependencies": { 396 | "@jridgewell/resolve-uri": "^3.1.0", 397 | "@jridgewell/sourcemap-codec": "^1.4.14" 398 | } 399 | }, 400 | "node_modules/@pkgr/core": { 401 | "version": "0.2.0", 402 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.0.tgz", 403 | "integrity": "sha512-vsJDAkYR6qCPu+ioGScGiMYR7LvZYIXh/dlQeviqoTWNCVfKTLYD/LkNWH4Mxsv2a5vpIRc77FN5DnmK1eBggQ==", 404 | "dev": true, 405 | "engines": { 406 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0" 407 | }, 408 | "funding": { 409 | "url": "https://opencollective.com/unts" 410 | } 411 | }, 412 | "node_modules/@sindresorhus/is": { 413 | "version": "5.6.0", 414 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", 415 | "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", 416 | "engines": { 417 | "node": ">=14.16" 418 | }, 419 | "funding": { 420 | "url": "https://github.com/sindresorhus/is?sponsor=1" 421 | } 422 | }, 423 | "node_modules/@socket.io/component-emitter": { 424 | "version": "3.1.0", 425 | "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", 426 | "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" 427 | }, 428 | "node_modules/@szmarczak/http-timer": { 429 | "version": "5.0.1", 430 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", 431 | "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", 432 | "dependencies": { 433 | "defer-to-connect": "^2.0.1" 434 | }, 435 | "engines": { 436 | "node": ">=14.16" 437 | } 438 | }, 439 | "node_modules/@types/eslint": { 440 | "version": "9.6.1", 441 | "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", 442 | "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", 443 | "dev": true, 444 | "dependencies": { 445 | "@types/estree": "*", 446 | "@types/json-schema": "*" 447 | } 448 | }, 449 | "node_modules/@types/eslint-scope": { 450 | "version": "3.7.7", 451 | "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", 452 | "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", 453 | "dev": true, 454 | "dependencies": { 455 | "@types/eslint": "*", 456 | "@types/estree": "*" 457 | } 458 | }, 459 | "node_modules/@types/estree": { 460 | "version": "1.0.7", 461 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", 462 | "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", 463 | "dev": true 464 | }, 465 | "node_modules/@types/http-cache-semantics": { 466 | "version": "4.0.4", 467 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", 468 | "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" 469 | }, 470 | "node_modules/@types/json-schema": { 471 | "version": "7.0.15", 472 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", 473 | "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", 474 | "dev": true 475 | }, 476 | "node_modules/@types/node": { 477 | "version": "22.13.17", 478 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.17.tgz", 479 | "integrity": "sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==", 480 | "dev": true, 481 | "dependencies": { 482 | "undici-types": "~6.20.0" 483 | } 484 | }, 485 | "node_modules/@webassemblyjs/ast": { 486 | "version": "1.14.1", 487 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", 488 | "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", 489 | "dev": true, 490 | "dependencies": { 491 | "@webassemblyjs/helper-numbers": "1.13.2", 492 | "@webassemblyjs/helper-wasm-bytecode": "1.13.2" 493 | } 494 | }, 495 | "node_modules/@webassemblyjs/floating-point-hex-parser": { 496 | "version": "1.13.2", 497 | "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", 498 | "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", 499 | "dev": true 500 | }, 501 | "node_modules/@webassemblyjs/helper-api-error": { 502 | "version": "1.13.2", 503 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", 504 | "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", 505 | "dev": true 506 | }, 507 | "node_modules/@webassemblyjs/helper-buffer": { 508 | "version": "1.14.1", 509 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", 510 | "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", 511 | "dev": true 512 | }, 513 | "node_modules/@webassemblyjs/helper-numbers": { 514 | "version": "1.13.2", 515 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", 516 | "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", 517 | "dev": true, 518 | "dependencies": { 519 | "@webassemblyjs/floating-point-hex-parser": "1.13.2", 520 | "@webassemblyjs/helper-api-error": "1.13.2", 521 | "@xtuc/long": "4.2.2" 522 | } 523 | }, 524 | "node_modules/@webassemblyjs/helper-wasm-bytecode": { 525 | "version": "1.13.2", 526 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", 527 | "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", 528 | "dev": true 529 | }, 530 | "node_modules/@webassemblyjs/helper-wasm-section": { 531 | "version": "1.14.1", 532 | "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", 533 | "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", 534 | "dev": true, 535 | "dependencies": { 536 | "@webassemblyjs/ast": "1.14.1", 537 | "@webassemblyjs/helper-buffer": "1.14.1", 538 | "@webassemblyjs/helper-wasm-bytecode": "1.13.2", 539 | "@webassemblyjs/wasm-gen": "1.14.1" 540 | } 541 | }, 542 | "node_modules/@webassemblyjs/ieee754": { 543 | "version": "1.13.2", 544 | "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", 545 | "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", 546 | "dev": true, 547 | "dependencies": { 548 | "@xtuc/ieee754": "^1.2.0" 549 | } 550 | }, 551 | "node_modules/@webassemblyjs/leb128": { 552 | "version": "1.13.2", 553 | "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", 554 | "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", 555 | "dev": true, 556 | "dependencies": { 557 | "@xtuc/long": "4.2.2" 558 | } 559 | }, 560 | "node_modules/@webassemblyjs/utf8": { 561 | "version": "1.13.2", 562 | "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", 563 | "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", 564 | "dev": true 565 | }, 566 | "node_modules/@webassemblyjs/wasm-edit": { 567 | "version": "1.14.1", 568 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", 569 | "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", 570 | "dev": true, 571 | "dependencies": { 572 | "@webassemblyjs/ast": "1.14.1", 573 | "@webassemblyjs/helper-buffer": "1.14.1", 574 | "@webassemblyjs/helper-wasm-bytecode": "1.13.2", 575 | "@webassemblyjs/helper-wasm-section": "1.14.1", 576 | "@webassemblyjs/wasm-gen": "1.14.1", 577 | "@webassemblyjs/wasm-opt": "1.14.1", 578 | "@webassemblyjs/wasm-parser": "1.14.1", 579 | "@webassemblyjs/wast-printer": "1.14.1" 580 | } 581 | }, 582 | "node_modules/@webassemblyjs/wasm-gen": { 583 | "version": "1.14.1", 584 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", 585 | "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", 586 | "dev": true, 587 | "dependencies": { 588 | "@webassemblyjs/ast": "1.14.1", 589 | "@webassemblyjs/helper-wasm-bytecode": "1.13.2", 590 | "@webassemblyjs/ieee754": "1.13.2", 591 | "@webassemblyjs/leb128": "1.13.2", 592 | "@webassemblyjs/utf8": "1.13.2" 593 | } 594 | }, 595 | "node_modules/@webassemblyjs/wasm-opt": { 596 | "version": "1.14.1", 597 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", 598 | "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", 599 | "dev": true, 600 | "dependencies": { 601 | "@webassemblyjs/ast": "1.14.1", 602 | "@webassemblyjs/helper-buffer": "1.14.1", 603 | "@webassemblyjs/wasm-gen": "1.14.1", 604 | "@webassemblyjs/wasm-parser": "1.14.1" 605 | } 606 | }, 607 | "node_modules/@webassemblyjs/wasm-parser": { 608 | "version": "1.14.1", 609 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", 610 | "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", 611 | "dev": true, 612 | "dependencies": { 613 | "@webassemblyjs/ast": "1.14.1", 614 | "@webassemblyjs/helper-api-error": "1.13.2", 615 | "@webassemblyjs/helper-wasm-bytecode": "1.13.2", 616 | "@webassemblyjs/ieee754": "1.13.2", 617 | "@webassemblyjs/leb128": "1.13.2", 618 | "@webassemblyjs/utf8": "1.13.2" 619 | } 620 | }, 621 | "node_modules/@webassemblyjs/wast-printer": { 622 | "version": "1.14.1", 623 | "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", 624 | "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", 625 | "dev": true, 626 | "dependencies": { 627 | "@webassemblyjs/ast": "1.14.1", 628 | "@xtuc/long": "4.2.2" 629 | } 630 | }, 631 | "node_modules/@webpack-cli/configtest": { 632 | "version": "3.0.1", 633 | "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", 634 | "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", 635 | "dev": true, 636 | "engines": { 637 | "node": ">=18.12.0" 638 | }, 639 | "peerDependencies": { 640 | "webpack": "^5.82.0", 641 | "webpack-cli": "6.x.x" 642 | } 643 | }, 644 | "node_modules/@webpack-cli/info": { 645 | "version": "3.0.1", 646 | "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", 647 | "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", 648 | "dev": true, 649 | "engines": { 650 | "node": ">=18.12.0" 651 | }, 652 | "peerDependencies": { 653 | "webpack": "^5.82.0", 654 | "webpack-cli": "6.x.x" 655 | } 656 | }, 657 | "node_modules/@webpack-cli/serve": { 658 | "version": "3.0.1", 659 | "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", 660 | "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", 661 | "dev": true, 662 | "engines": { 663 | "node": ">=18.12.0" 664 | }, 665 | "peerDependencies": { 666 | "webpack": "^5.82.0", 667 | "webpack-cli": "6.x.x" 668 | }, 669 | "peerDependenciesMeta": { 670 | "webpack-dev-server": { 671 | "optional": true 672 | } 673 | } 674 | }, 675 | "node_modules/@xtuc/ieee754": { 676 | "version": "1.2.0", 677 | "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", 678 | "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", 679 | "dev": true 680 | }, 681 | "node_modules/@xtuc/long": { 682 | "version": "4.2.2", 683 | "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", 684 | "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", 685 | "dev": true 686 | }, 687 | "node_modules/acorn": { 688 | "version": "8.14.1", 689 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", 690 | "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", 691 | "dev": true, 692 | "bin": { 693 | "acorn": "bin/acorn" 694 | }, 695 | "engines": { 696 | "node": ">=0.4.0" 697 | } 698 | }, 699 | "node_modules/acorn-jsx": { 700 | "version": "5.3.2", 701 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 702 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 703 | "dev": true, 704 | "peerDependencies": { 705 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" 706 | } 707 | }, 708 | "node_modules/ajv": { 709 | "version": "8.17.1", 710 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", 711 | "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", 712 | "dependencies": { 713 | "fast-deep-equal": "^3.1.3", 714 | "fast-uri": "^3.0.1", 715 | "json-schema-traverse": "^1.0.0", 716 | "require-from-string": "^2.0.2" 717 | }, 718 | "funding": { 719 | "type": "github", 720 | "url": "https://github.com/sponsors/epoberezkin" 721 | } 722 | }, 723 | "node_modules/ajv-formats": { 724 | "version": "2.1.1", 725 | "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", 726 | "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", 727 | "dev": true, 728 | "dependencies": { 729 | "ajv": "^8.0.0" 730 | }, 731 | "peerDependencies": { 732 | "ajv": "^8.0.0" 733 | }, 734 | "peerDependenciesMeta": { 735 | "ajv": { 736 | "optional": true 737 | } 738 | } 739 | }, 740 | "node_modules/ajv-keywords": { 741 | "version": "5.1.0", 742 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", 743 | "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", 744 | "dev": true, 745 | "dependencies": { 746 | "fast-deep-equal": "^3.1.3" 747 | }, 748 | "peerDependencies": { 749 | "ajv": "^8.8.2" 750 | } 751 | }, 752 | "node_modules/ansi-styles": { 753 | "version": "4.3.0", 754 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 755 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 756 | "dev": true, 757 | "dependencies": { 758 | "color-convert": "^2.0.1" 759 | }, 760 | "engines": { 761 | "node": ">=8" 762 | }, 763 | "funding": { 764 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 765 | } 766 | }, 767 | "node_modules/argparse": { 768 | "version": "2.0.1", 769 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 770 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 771 | "dev": true 772 | }, 773 | "node_modules/author-regex": { 774 | "version": "1.0.0", 775 | "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", 776 | "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", 777 | "dev": true, 778 | "engines": { 779 | "node": ">=0.8" 780 | } 781 | }, 782 | "node_modules/balanced-match": { 783 | "version": "1.0.2", 784 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 785 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 786 | "dev": true 787 | }, 788 | "node_modules/brace-expansion": { 789 | "version": "1.1.11", 790 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 791 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 792 | "dev": true, 793 | "dependencies": { 794 | "balanced-match": "^1.0.0", 795 | "concat-map": "0.0.1" 796 | } 797 | }, 798 | "node_modules/browserslist": { 799 | "version": "4.24.4", 800 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", 801 | "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", 802 | "dev": true, 803 | "funding": [ 804 | { 805 | "type": "opencollective", 806 | "url": "https://opencollective.com/browserslist" 807 | }, 808 | { 809 | "type": "tidelift", 810 | "url": "https://tidelift.com/funding/github/npm/browserslist" 811 | }, 812 | { 813 | "type": "github", 814 | "url": "https://github.com/sponsors/ai" 815 | } 816 | ], 817 | "dependencies": { 818 | "caniuse-lite": "^1.0.30001688", 819 | "electron-to-chromium": "^1.5.73", 820 | "node-releases": "^2.0.19", 821 | "update-browserslist-db": "^1.1.1" 822 | }, 823 | "bin": { 824 | "browserslist": "cli.js" 825 | }, 826 | "engines": { 827 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 828 | } 829 | }, 830 | "node_modules/buffer-from": { 831 | "version": "1.1.2", 832 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 833 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 834 | "dev": true 835 | }, 836 | "node_modules/cacheable-lookup": { 837 | "version": "7.0.0", 838 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", 839 | "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", 840 | "engines": { 841 | "node": ">=14.16" 842 | } 843 | }, 844 | "node_modules/cacheable-request": { 845 | "version": "10.2.14", 846 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", 847 | "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", 848 | "dependencies": { 849 | "@types/http-cache-semantics": "^4.0.2", 850 | "get-stream": "^6.0.1", 851 | "http-cache-semantics": "^4.1.1", 852 | "keyv": "^4.5.3", 853 | "mimic-response": "^4.0.0", 854 | "normalize-url": "^8.0.0", 855 | "responselike": "^3.0.0" 856 | }, 857 | "engines": { 858 | "node": ">=14.16" 859 | } 860 | }, 861 | "node_modules/callsites": { 862 | "version": "3.1.0", 863 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 864 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 865 | "dev": true, 866 | "engines": { 867 | "node": ">=6" 868 | } 869 | }, 870 | "node_modules/caniuse-lite": { 871 | "version": "1.0.30001707", 872 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz", 873 | "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==", 874 | "dev": true, 875 | "funding": [ 876 | { 877 | "type": "opencollective", 878 | "url": "https://opencollective.com/browserslist" 879 | }, 880 | { 881 | "type": "tidelift", 882 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 883 | }, 884 | { 885 | "type": "github", 886 | "url": "https://github.com/sponsors/ai" 887 | } 888 | ] 889 | }, 890 | "node_modules/chalk": { 891 | "version": "4.1.2", 892 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 893 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 894 | "dev": true, 895 | "dependencies": { 896 | "ansi-styles": "^4.1.0", 897 | "supports-color": "^7.1.0" 898 | }, 899 | "engines": { 900 | "node": ">=10" 901 | }, 902 | "funding": { 903 | "url": "https://github.com/chalk/chalk?sponsor=1" 904 | } 905 | }, 906 | "node_modules/chownr": { 907 | "version": "3.0.0", 908 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", 909 | "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", 910 | "dev": true, 911 | "engines": { 912 | "node": ">=18" 913 | } 914 | }, 915 | "node_modules/chrome-trace-event": { 916 | "version": "1.0.4", 917 | "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", 918 | "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", 919 | "dev": true, 920 | "engines": { 921 | "node": ">=6.0" 922 | } 923 | }, 924 | "node_modules/clone-deep": { 925 | "version": "4.0.1", 926 | "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", 927 | "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", 928 | "dev": true, 929 | "dependencies": { 930 | "is-plain-object": "^2.0.4", 931 | "kind-of": "^6.0.2", 932 | "shallow-clone": "^3.0.0" 933 | }, 934 | "engines": { 935 | "node": ">=6" 936 | } 937 | }, 938 | "node_modules/color-convert": { 939 | "version": "2.0.1", 940 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 941 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 942 | "dev": true, 943 | "dependencies": { 944 | "color-name": "~1.1.4" 945 | }, 946 | "engines": { 947 | "node": ">=7.0.0" 948 | } 949 | }, 950 | "node_modules/color-name": { 951 | "version": "1.1.4", 952 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 953 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 954 | "dev": true 955 | }, 956 | "node_modules/colord": { 957 | "version": "2.9.3", 958 | "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", 959 | "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" 960 | }, 961 | "node_modules/colorette": { 962 | "version": "2.0.20", 963 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", 964 | "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", 965 | "dev": true 966 | }, 967 | "node_modules/commander": { 968 | "version": "2.20.3", 969 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 970 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 971 | "dev": true 972 | }, 973 | "node_modules/concat-map": { 974 | "version": "0.0.1", 975 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 976 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 977 | "dev": true 978 | }, 979 | "node_modules/cross-spawn": { 980 | "version": "7.0.6", 981 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 982 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 983 | "dev": true, 984 | "dependencies": { 985 | "path-key": "^3.1.0", 986 | "shebang-command": "^2.0.0", 987 | "which": "^2.0.1" 988 | }, 989 | "engines": { 990 | "node": ">= 8" 991 | } 992 | }, 993 | "node_modules/debug": { 994 | "version": "4.3.4", 995 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 996 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 997 | "dependencies": { 998 | "ms": "2.1.2" 999 | }, 1000 | "engines": { 1001 | "node": ">=6.0" 1002 | }, 1003 | "peerDependenciesMeta": { 1004 | "supports-color": { 1005 | "optional": true 1006 | } 1007 | } 1008 | }, 1009 | "node_modules/decompress-response": { 1010 | "version": "6.0.0", 1011 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 1012 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 1013 | "dependencies": { 1014 | "mimic-response": "^3.1.0" 1015 | }, 1016 | "engines": { 1017 | "node": ">=10" 1018 | }, 1019 | "funding": { 1020 | "url": "https://github.com/sponsors/sindresorhus" 1021 | } 1022 | }, 1023 | "node_modules/decompress-response/node_modules/mimic-response": { 1024 | "version": "3.1.0", 1025 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 1026 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 1027 | "engines": { 1028 | "node": ">=10" 1029 | }, 1030 | "funding": { 1031 | "url": "https://github.com/sponsors/sindresorhus" 1032 | } 1033 | }, 1034 | "node_modules/deep-is": { 1035 | "version": "0.1.4", 1036 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 1037 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 1038 | "dev": true 1039 | }, 1040 | "node_modules/defer-to-connect": { 1041 | "version": "2.0.1", 1042 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 1043 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 1044 | "engines": { 1045 | "node": ">=10" 1046 | } 1047 | }, 1048 | "node_modules/ejson": { 1049 | "version": "2.2.3", 1050 | "resolved": "https://registry.npmjs.org/ejson/-/ejson-2.2.3.tgz", 1051 | "integrity": "sha512-hsFvJp6OpGxFRQfBR3PSxFpaPALdHDY+SB3TRbMpLWNhvu8GzLiZutof5+/DFd2QekZo3KyXau75ngdJqQUSrw==" 1052 | }, 1053 | "node_modules/electron-to-chromium": { 1054 | "version": "1.5.129", 1055 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.129.tgz", 1056 | "integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==", 1057 | "dev": true 1058 | }, 1059 | "node_modules/engine.io-client": { 1060 | "version": "6.5.4", 1061 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz", 1062 | "integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==", 1063 | "dependencies": { 1064 | "@socket.io/component-emitter": "~3.1.0", 1065 | "debug": "~4.3.1", 1066 | "engine.io-parser": "~5.2.1", 1067 | "ws": "~8.17.1", 1068 | "xmlhttprequest-ssl": "~2.0.0" 1069 | } 1070 | }, 1071 | "node_modules/engine.io-parser": { 1072 | "version": "5.2.1", 1073 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", 1074 | "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", 1075 | "engines": { 1076 | "node": ">=10.0.0" 1077 | } 1078 | }, 1079 | "node_modules/enhanced-resolve": { 1080 | "version": "5.18.1", 1081 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", 1082 | "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", 1083 | "dev": true, 1084 | "dependencies": { 1085 | "graceful-fs": "^4.2.4", 1086 | "tapable": "^2.2.0" 1087 | }, 1088 | "engines": { 1089 | "node": ">=10.13.0" 1090 | } 1091 | }, 1092 | "node_modules/envinfo": { 1093 | "version": "7.14.0", 1094 | "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", 1095 | "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", 1096 | "dev": true, 1097 | "bin": { 1098 | "envinfo": "dist/cli.js" 1099 | }, 1100 | "engines": { 1101 | "node": ">=4" 1102 | } 1103 | }, 1104 | "node_modules/es-module-lexer": { 1105 | "version": "1.6.0", 1106 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", 1107 | "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", 1108 | "dev": true 1109 | }, 1110 | "node_modules/escalade": { 1111 | "version": "3.2.0", 1112 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 1113 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1114 | "dev": true, 1115 | "engines": { 1116 | "node": ">=6" 1117 | } 1118 | }, 1119 | "node_modules/escape-string-regexp": { 1120 | "version": "4.0.0", 1121 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1122 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1123 | "dev": true, 1124 | "engines": { 1125 | "node": ">=10" 1126 | }, 1127 | "funding": { 1128 | "url": "https://github.com/sponsors/sindresorhus" 1129 | } 1130 | }, 1131 | "node_modules/eslint": { 1132 | "version": "9.23.0", 1133 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.23.0.tgz", 1134 | "integrity": "sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==", 1135 | "dev": true, 1136 | "dependencies": { 1137 | "@eslint-community/eslint-utils": "^4.2.0", 1138 | "@eslint-community/regexpp": "^4.12.1", 1139 | "@eslint/config-array": "^0.19.2", 1140 | "@eslint/config-helpers": "^0.2.0", 1141 | "@eslint/core": "^0.12.0", 1142 | "@eslint/eslintrc": "^3.3.1", 1143 | "@eslint/js": "9.23.0", 1144 | "@eslint/plugin-kit": "^0.2.7", 1145 | "@humanfs/node": "^0.16.6", 1146 | "@humanwhocodes/module-importer": "^1.0.1", 1147 | "@humanwhocodes/retry": "^0.4.2", 1148 | "@types/estree": "^1.0.6", 1149 | "@types/json-schema": "^7.0.15", 1150 | "ajv": "^6.12.4", 1151 | "chalk": "^4.0.0", 1152 | "cross-spawn": "^7.0.6", 1153 | "debug": "^4.3.2", 1154 | "escape-string-regexp": "^4.0.0", 1155 | "eslint-scope": "^8.3.0", 1156 | "eslint-visitor-keys": "^4.2.0", 1157 | "espree": "^10.3.0", 1158 | "esquery": "^1.5.0", 1159 | "esutils": "^2.0.2", 1160 | "fast-deep-equal": "^3.1.3", 1161 | "file-entry-cache": "^8.0.0", 1162 | "find-up": "^5.0.0", 1163 | "glob-parent": "^6.0.2", 1164 | "ignore": "^5.2.0", 1165 | "imurmurhash": "^0.1.4", 1166 | "is-glob": "^4.0.0", 1167 | "json-stable-stringify-without-jsonify": "^1.0.1", 1168 | "lodash.merge": "^4.6.2", 1169 | "minimatch": "^3.1.2", 1170 | "natural-compare": "^1.4.0", 1171 | "optionator": "^0.9.3" 1172 | }, 1173 | "bin": { 1174 | "eslint": "bin/eslint.js" 1175 | }, 1176 | "engines": { 1177 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1178 | }, 1179 | "funding": { 1180 | "url": "https://eslint.org/donate" 1181 | }, 1182 | "peerDependencies": { 1183 | "jiti": "*" 1184 | }, 1185 | "peerDependenciesMeta": { 1186 | "jiti": { 1187 | "optional": true 1188 | } 1189 | } 1190 | }, 1191 | "node_modules/eslint-compat-utils": { 1192 | "version": "0.5.1", 1193 | "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", 1194 | "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", 1195 | "dev": true, 1196 | "dependencies": { 1197 | "semver": "^7.5.4" 1198 | }, 1199 | "engines": { 1200 | "node": ">=12" 1201 | }, 1202 | "peerDependencies": { 1203 | "eslint": ">=6.0.0" 1204 | } 1205 | }, 1206 | "node_modules/eslint-config-prettier": { 1207 | "version": "10.1.1", 1208 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.1.tgz", 1209 | "integrity": "sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==", 1210 | "dev": true, 1211 | "bin": { 1212 | "eslint-config-prettier": "bin/cli.js" 1213 | }, 1214 | "peerDependencies": { 1215 | "eslint": ">=7.0.0" 1216 | } 1217 | }, 1218 | "node_modules/eslint-plugin-es-x": { 1219 | "version": "7.8.0", 1220 | "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", 1221 | "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", 1222 | "dev": true, 1223 | "funding": [ 1224 | "https://github.com/sponsors/ota-meshi", 1225 | "https://opencollective.com/eslint" 1226 | ], 1227 | "dependencies": { 1228 | "@eslint-community/eslint-utils": "^4.1.2", 1229 | "@eslint-community/regexpp": "^4.11.0", 1230 | "eslint-compat-utils": "^0.5.1" 1231 | }, 1232 | "engines": { 1233 | "node": "^14.18.0 || >=16.0.0" 1234 | }, 1235 | "peerDependencies": { 1236 | "eslint": ">=8" 1237 | } 1238 | }, 1239 | "node_modules/eslint-plugin-n": { 1240 | "version": "17.17.0", 1241 | "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.17.0.tgz", 1242 | "integrity": "sha512-2VvPK7Mo73z1rDFb6pTvkH6kFibAmnTubFq5l83vePxu0WiY1s0LOtj2WHb6Sa40R3w4mnh8GFYbHBQyMlotKw==", 1243 | "dev": true, 1244 | "dependencies": { 1245 | "@eslint-community/eslint-utils": "^4.5.0", 1246 | "enhanced-resolve": "^5.17.1", 1247 | "eslint-plugin-es-x": "^7.8.0", 1248 | "get-tsconfig": "^4.8.1", 1249 | "globals": "^15.11.0", 1250 | "ignore": "^5.3.2", 1251 | "minimatch": "^9.0.5", 1252 | "semver": "^7.6.3" 1253 | }, 1254 | "engines": { 1255 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1256 | }, 1257 | "funding": { 1258 | "url": "https://opencollective.com/eslint" 1259 | }, 1260 | "peerDependencies": { 1261 | "eslint": ">=8.23.0" 1262 | } 1263 | }, 1264 | "node_modules/eslint-plugin-n/node_modules/brace-expansion": { 1265 | "version": "2.0.1", 1266 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1267 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1268 | "dev": true, 1269 | "dependencies": { 1270 | "balanced-match": "^1.0.0" 1271 | } 1272 | }, 1273 | "node_modules/eslint-plugin-n/node_modules/minimatch": { 1274 | "version": "9.0.5", 1275 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1276 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1277 | "dev": true, 1278 | "dependencies": { 1279 | "brace-expansion": "^2.0.1" 1280 | }, 1281 | "engines": { 1282 | "node": ">=16 || 14 >=14.17" 1283 | }, 1284 | "funding": { 1285 | "url": "https://github.com/sponsors/isaacs" 1286 | } 1287 | }, 1288 | "node_modules/eslint-plugin-prettier": { 1289 | "version": "5.2.5", 1290 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.5.tgz", 1291 | "integrity": "sha512-IKKP8R87pJyMl7WWamLgPkloB16dagPIdd2FjBDbyRYPKo93wS/NbCOPh6gH+ieNLC+XZrhJt/kWj0PS/DFdmg==", 1292 | "dev": true, 1293 | "dependencies": { 1294 | "prettier-linter-helpers": "^1.0.0", 1295 | "synckit": "^0.10.2" 1296 | }, 1297 | "engines": { 1298 | "node": "^14.18.0 || >=16.0.0" 1299 | }, 1300 | "funding": { 1301 | "url": "https://opencollective.com/eslint-plugin-prettier" 1302 | }, 1303 | "peerDependencies": { 1304 | "@types/eslint": ">=8.0.0", 1305 | "eslint": ">=8.0.0", 1306 | "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", 1307 | "prettier": ">=3.0.0" 1308 | }, 1309 | "peerDependenciesMeta": { 1310 | "@types/eslint": { 1311 | "optional": true 1312 | }, 1313 | "eslint-config-prettier": { 1314 | "optional": true 1315 | } 1316 | } 1317 | }, 1318 | "node_modules/eslint-scope": { 1319 | "version": "5.1.1", 1320 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 1321 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 1322 | "dev": true, 1323 | "dependencies": { 1324 | "esrecurse": "^4.3.0", 1325 | "estraverse": "^4.1.1" 1326 | }, 1327 | "engines": { 1328 | "node": ">=8.0.0" 1329 | } 1330 | }, 1331 | "node_modules/eslint-visitor-keys": { 1332 | "version": "3.4.3", 1333 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", 1334 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", 1335 | "dev": true, 1336 | "engines": { 1337 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 1338 | }, 1339 | "funding": { 1340 | "url": "https://opencollective.com/eslint" 1341 | } 1342 | }, 1343 | "node_modules/eslint/node_modules/ajv": { 1344 | "version": "6.12.6", 1345 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 1346 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 1347 | "dev": true, 1348 | "dependencies": { 1349 | "fast-deep-equal": "^3.1.1", 1350 | "fast-json-stable-stringify": "^2.0.0", 1351 | "json-schema-traverse": "^0.4.1", 1352 | "uri-js": "^4.2.2" 1353 | }, 1354 | "funding": { 1355 | "type": "github", 1356 | "url": "https://github.com/sponsors/epoberezkin" 1357 | } 1358 | }, 1359 | "node_modules/eslint/node_modules/eslint-scope": { 1360 | "version": "8.3.0", 1361 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", 1362 | "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", 1363 | "dev": true, 1364 | "dependencies": { 1365 | "esrecurse": "^4.3.0", 1366 | "estraverse": "^5.2.0" 1367 | }, 1368 | "engines": { 1369 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1370 | }, 1371 | "funding": { 1372 | "url": "https://opencollective.com/eslint" 1373 | } 1374 | }, 1375 | "node_modules/eslint/node_modules/eslint-visitor-keys": { 1376 | "version": "4.2.0", 1377 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 1378 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 1379 | "dev": true, 1380 | "engines": { 1381 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1382 | }, 1383 | "funding": { 1384 | "url": "https://opencollective.com/eslint" 1385 | } 1386 | }, 1387 | "node_modules/eslint/node_modules/estraverse": { 1388 | "version": "5.3.0", 1389 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1390 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1391 | "dev": true, 1392 | "engines": { 1393 | "node": ">=4.0" 1394 | } 1395 | }, 1396 | "node_modules/eslint/node_modules/find-up": { 1397 | "version": "5.0.0", 1398 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1399 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1400 | "dev": true, 1401 | "dependencies": { 1402 | "locate-path": "^6.0.0", 1403 | "path-exists": "^4.0.0" 1404 | }, 1405 | "engines": { 1406 | "node": ">=10" 1407 | }, 1408 | "funding": { 1409 | "url": "https://github.com/sponsors/sindresorhus" 1410 | } 1411 | }, 1412 | "node_modules/eslint/node_modules/json-schema-traverse": { 1413 | "version": "0.4.1", 1414 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1415 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1416 | "dev": true 1417 | }, 1418 | "node_modules/eslint/node_modules/locate-path": { 1419 | "version": "6.0.0", 1420 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1421 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1422 | "dev": true, 1423 | "dependencies": { 1424 | "p-locate": "^5.0.0" 1425 | }, 1426 | "engines": { 1427 | "node": ">=10" 1428 | }, 1429 | "funding": { 1430 | "url": "https://github.com/sponsors/sindresorhus" 1431 | } 1432 | }, 1433 | "node_modules/eslint/node_modules/p-limit": { 1434 | "version": "3.1.0", 1435 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1436 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1437 | "dev": true, 1438 | "dependencies": { 1439 | "yocto-queue": "^0.1.0" 1440 | }, 1441 | "engines": { 1442 | "node": ">=10" 1443 | }, 1444 | "funding": { 1445 | "url": "https://github.com/sponsors/sindresorhus" 1446 | } 1447 | }, 1448 | "node_modules/eslint/node_modules/p-locate": { 1449 | "version": "5.0.0", 1450 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1451 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1452 | "dev": true, 1453 | "dependencies": { 1454 | "p-limit": "^3.0.2" 1455 | }, 1456 | "engines": { 1457 | "node": ">=10" 1458 | }, 1459 | "funding": { 1460 | "url": "https://github.com/sponsors/sindresorhus" 1461 | } 1462 | }, 1463 | "node_modules/eslint/node_modules/path-exists": { 1464 | "version": "4.0.0", 1465 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1466 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1467 | "dev": true, 1468 | "engines": { 1469 | "node": ">=8" 1470 | } 1471 | }, 1472 | "node_modules/eslint/node_modules/yocto-queue": { 1473 | "version": "0.1.0", 1474 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1475 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1476 | "dev": true, 1477 | "engines": { 1478 | "node": ">=10" 1479 | }, 1480 | "funding": { 1481 | "url": "https://github.com/sponsors/sindresorhus" 1482 | } 1483 | }, 1484 | "node_modules/espree": { 1485 | "version": "10.3.0", 1486 | "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", 1487 | "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", 1488 | "dev": true, 1489 | "dependencies": { 1490 | "acorn": "^8.14.0", 1491 | "acorn-jsx": "^5.3.2", 1492 | "eslint-visitor-keys": "^4.2.0" 1493 | }, 1494 | "engines": { 1495 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1496 | }, 1497 | "funding": { 1498 | "url": "https://opencollective.com/eslint" 1499 | } 1500 | }, 1501 | "node_modules/espree/node_modules/eslint-visitor-keys": { 1502 | "version": "4.2.0", 1503 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", 1504 | "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", 1505 | "dev": true, 1506 | "engines": { 1507 | "node": "^18.18.0 || ^20.9.0 || >=21.1.0" 1508 | }, 1509 | "funding": { 1510 | "url": "https://opencollective.com/eslint" 1511 | } 1512 | }, 1513 | "node_modules/esquery": { 1514 | "version": "1.5.0", 1515 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", 1516 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", 1517 | "dev": true, 1518 | "dependencies": { 1519 | "estraverse": "^5.1.0" 1520 | }, 1521 | "engines": { 1522 | "node": ">=0.10" 1523 | } 1524 | }, 1525 | "node_modules/esquery/node_modules/estraverse": { 1526 | "version": "5.3.0", 1527 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1528 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1529 | "dev": true, 1530 | "engines": { 1531 | "node": ">=4.0" 1532 | } 1533 | }, 1534 | "node_modules/esrecurse": { 1535 | "version": "4.3.0", 1536 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1537 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1538 | "dev": true, 1539 | "dependencies": { 1540 | "estraverse": "^5.2.0" 1541 | }, 1542 | "engines": { 1543 | "node": ">=4.0" 1544 | } 1545 | }, 1546 | "node_modules/esrecurse/node_modules/estraverse": { 1547 | "version": "5.3.0", 1548 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 1549 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 1550 | "dev": true, 1551 | "engines": { 1552 | "node": ">=4.0" 1553 | } 1554 | }, 1555 | "node_modules/estraverse": { 1556 | "version": "4.3.0", 1557 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 1558 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 1559 | "dev": true, 1560 | "engines": { 1561 | "node": ">=4.0" 1562 | } 1563 | }, 1564 | "node_modules/esutils": { 1565 | "version": "2.0.3", 1566 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1567 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1568 | "dev": true, 1569 | "engines": { 1570 | "node": ">=0.10.0" 1571 | } 1572 | }, 1573 | "node_modules/eventemitter3": { 1574 | "version": "4.0.7", 1575 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", 1576 | "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" 1577 | }, 1578 | "node_modules/events": { 1579 | "version": "3.3.0", 1580 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 1581 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 1582 | "dev": true, 1583 | "engines": { 1584 | "node": ">=0.8.x" 1585 | } 1586 | }, 1587 | "node_modules/fast-deep-equal": { 1588 | "version": "3.1.3", 1589 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1590 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" 1591 | }, 1592 | "node_modules/fast-diff": { 1593 | "version": "1.3.0", 1594 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", 1595 | "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", 1596 | "dev": true 1597 | }, 1598 | "node_modules/fast-json-stable-stringify": { 1599 | "version": "2.1.0", 1600 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1601 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1602 | "dev": true 1603 | }, 1604 | "node_modules/fast-levenshtein": { 1605 | "version": "2.0.6", 1606 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1607 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 1608 | "dev": true 1609 | }, 1610 | "node_modules/fast-uri": { 1611 | "version": "3.0.6", 1612 | "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", 1613 | "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", 1614 | "funding": [ 1615 | { 1616 | "type": "github", 1617 | "url": "https://github.com/sponsors/fastify" 1618 | }, 1619 | { 1620 | "type": "opencollective", 1621 | "url": "https://opencollective.com/fastify" 1622 | } 1623 | ] 1624 | }, 1625 | "node_modules/fastest-levenshtein": { 1626 | "version": "1.0.16", 1627 | "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", 1628 | "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", 1629 | "dev": true, 1630 | "engines": { 1631 | "node": ">= 4.9.1" 1632 | } 1633 | }, 1634 | "node_modules/file-entry-cache": { 1635 | "version": "8.0.0", 1636 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", 1637 | "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", 1638 | "dev": true, 1639 | "dependencies": { 1640 | "flat-cache": "^4.0.0" 1641 | }, 1642 | "engines": { 1643 | "node": ">=16.0.0" 1644 | } 1645 | }, 1646 | "node_modules/find-up": { 1647 | "version": "7.0.0", 1648 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", 1649 | "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", 1650 | "dev": true, 1651 | "dependencies": { 1652 | "locate-path": "^7.2.0", 1653 | "path-exists": "^5.0.0", 1654 | "unicorn-magic": "^0.1.0" 1655 | }, 1656 | "engines": { 1657 | "node": ">=18" 1658 | }, 1659 | "funding": { 1660 | "url": "https://github.com/sponsors/sindresorhus" 1661 | } 1662 | }, 1663 | "node_modules/flat": { 1664 | "version": "5.0.2", 1665 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 1666 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 1667 | "dev": true, 1668 | "bin": { 1669 | "flat": "cli.js" 1670 | } 1671 | }, 1672 | "node_modules/flat-cache": { 1673 | "version": "4.0.1", 1674 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", 1675 | "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", 1676 | "dev": true, 1677 | "dependencies": { 1678 | "flatted": "^3.2.9", 1679 | "keyv": "^4.5.4" 1680 | }, 1681 | "engines": { 1682 | "node": ">=16" 1683 | } 1684 | }, 1685 | "node_modules/flatted": { 1686 | "version": "3.3.3", 1687 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", 1688 | "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", 1689 | "dev": true 1690 | }, 1691 | "node_modules/form-data-encoder": { 1692 | "version": "2.1.4", 1693 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", 1694 | "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", 1695 | "engines": { 1696 | "node": ">= 14.17" 1697 | } 1698 | }, 1699 | "node_modules/function-bind": { 1700 | "version": "1.1.2", 1701 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1702 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1703 | "dev": true, 1704 | "funding": { 1705 | "url": "https://github.com/sponsors/ljharb" 1706 | } 1707 | }, 1708 | "node_modules/get-stream": { 1709 | "version": "6.0.1", 1710 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", 1711 | "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", 1712 | "engines": { 1713 | "node": ">=10" 1714 | }, 1715 | "funding": { 1716 | "url": "https://github.com/sponsors/sindresorhus" 1717 | } 1718 | }, 1719 | "node_modules/get-tsconfig": { 1720 | "version": "4.10.0", 1721 | "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz", 1722 | "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==", 1723 | "dev": true, 1724 | "dependencies": { 1725 | "resolve-pkg-maps": "^1.0.0" 1726 | }, 1727 | "funding": { 1728 | "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" 1729 | } 1730 | }, 1731 | "node_modules/glob-parent": { 1732 | "version": "6.0.2", 1733 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", 1734 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", 1735 | "dev": true, 1736 | "dependencies": { 1737 | "is-glob": "^4.0.3" 1738 | }, 1739 | "engines": { 1740 | "node": ">=10.13.0" 1741 | } 1742 | }, 1743 | "node_modules/glob-to-regexp": { 1744 | "version": "0.4.1", 1745 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", 1746 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", 1747 | "dev": true 1748 | }, 1749 | "node_modules/globals": { 1750 | "version": "15.15.0", 1751 | "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", 1752 | "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", 1753 | "dev": true, 1754 | "engines": { 1755 | "node": ">=18" 1756 | }, 1757 | "funding": { 1758 | "url": "https://github.com/sponsors/sindresorhus" 1759 | } 1760 | }, 1761 | "node_modules/got": { 1762 | "version": "13.0.0", 1763 | "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz", 1764 | "integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==", 1765 | "dependencies": { 1766 | "@sindresorhus/is": "^5.2.0", 1767 | "@szmarczak/http-timer": "^5.0.1", 1768 | "cacheable-lookup": "^7.0.0", 1769 | "cacheable-request": "^10.2.8", 1770 | "decompress-response": "^6.0.0", 1771 | "form-data-encoder": "^2.1.2", 1772 | "get-stream": "^6.0.1", 1773 | "http2-wrapper": "^2.1.10", 1774 | "lowercase-keys": "^3.0.0", 1775 | "p-cancelable": "^3.0.0", 1776 | "responselike": "^3.0.0" 1777 | }, 1778 | "engines": { 1779 | "node": ">=16" 1780 | }, 1781 | "funding": { 1782 | "url": "https://github.com/sindresorhus/got?sponsor=1" 1783 | } 1784 | }, 1785 | "node_modules/graceful-fs": { 1786 | "version": "4.2.11", 1787 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1788 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1789 | "dev": true 1790 | }, 1791 | "node_modules/has-flag": { 1792 | "version": "4.0.0", 1793 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1794 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1795 | "dev": true, 1796 | "engines": { 1797 | "node": ">=8" 1798 | } 1799 | }, 1800 | "node_modules/hasown": { 1801 | "version": "2.0.2", 1802 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1803 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1804 | "dev": true, 1805 | "dependencies": { 1806 | "function-bind": "^1.1.2" 1807 | }, 1808 | "engines": { 1809 | "node": ">= 0.4" 1810 | } 1811 | }, 1812 | "node_modules/http-cache-semantics": { 1813 | "version": "4.1.1", 1814 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", 1815 | "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" 1816 | }, 1817 | "node_modules/http2-wrapper": { 1818 | "version": "2.2.1", 1819 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", 1820 | "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", 1821 | "dependencies": { 1822 | "quick-lru": "^5.1.1", 1823 | "resolve-alpn": "^1.2.0" 1824 | }, 1825 | "engines": { 1826 | "node": ">=10.19.0" 1827 | } 1828 | }, 1829 | "node_modules/ignore": { 1830 | "version": "5.3.2", 1831 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", 1832 | "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", 1833 | "dev": true, 1834 | "engines": { 1835 | "node": ">= 4" 1836 | } 1837 | }, 1838 | "node_modules/import-fresh": { 1839 | "version": "3.3.1", 1840 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", 1841 | "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", 1842 | "dev": true, 1843 | "dependencies": { 1844 | "parent-module": "^1.0.0", 1845 | "resolve-from": "^4.0.0" 1846 | }, 1847 | "engines": { 1848 | "node": ">=6" 1849 | }, 1850 | "funding": { 1851 | "url": "https://github.com/sponsors/sindresorhus" 1852 | } 1853 | }, 1854 | "node_modules/import-local": { 1855 | "version": "3.2.0", 1856 | "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", 1857 | "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", 1858 | "dev": true, 1859 | "dependencies": { 1860 | "pkg-dir": "^4.2.0", 1861 | "resolve-cwd": "^3.0.0" 1862 | }, 1863 | "bin": { 1864 | "import-local-fixture": "fixtures/cli.js" 1865 | }, 1866 | "engines": { 1867 | "node": ">=8" 1868 | }, 1869 | "funding": { 1870 | "url": "https://github.com/sponsors/sindresorhus" 1871 | } 1872 | }, 1873 | "node_modules/imurmurhash": { 1874 | "version": "0.1.4", 1875 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1876 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1877 | "dev": true, 1878 | "engines": { 1879 | "node": ">=0.8.19" 1880 | } 1881 | }, 1882 | "node_modules/interpret": { 1883 | "version": "3.1.1", 1884 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", 1885 | "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", 1886 | "dev": true, 1887 | "engines": { 1888 | "node": ">=10.13.0" 1889 | } 1890 | }, 1891 | "node_modules/is-core-module": { 1892 | "version": "2.16.1", 1893 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 1894 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 1895 | "dev": true, 1896 | "dependencies": { 1897 | "hasown": "^2.0.2" 1898 | }, 1899 | "engines": { 1900 | "node": ">= 0.4" 1901 | }, 1902 | "funding": { 1903 | "url": "https://github.com/sponsors/ljharb" 1904 | } 1905 | }, 1906 | "node_modules/is-extglob": { 1907 | "version": "2.1.1", 1908 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1909 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1910 | "dev": true, 1911 | "engines": { 1912 | "node": ">=0.10.0" 1913 | } 1914 | }, 1915 | "node_modules/is-glob": { 1916 | "version": "4.0.3", 1917 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1918 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1919 | "dev": true, 1920 | "dependencies": { 1921 | "is-extglob": "^2.1.1" 1922 | }, 1923 | "engines": { 1924 | "node": ">=0.10.0" 1925 | } 1926 | }, 1927 | "node_modules/is-plain-object": { 1928 | "version": "2.0.4", 1929 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", 1930 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", 1931 | "dev": true, 1932 | "dependencies": { 1933 | "isobject": "^3.0.1" 1934 | }, 1935 | "engines": { 1936 | "node": ">=0.10.0" 1937 | } 1938 | }, 1939 | "node_modules/isexe": { 1940 | "version": "2.0.0", 1941 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1942 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1943 | "dev": true 1944 | }, 1945 | "node_modules/isobject": { 1946 | "version": "3.0.1", 1947 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", 1948 | "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", 1949 | "dev": true, 1950 | "engines": { 1951 | "node": ">=0.10.0" 1952 | } 1953 | }, 1954 | "node_modules/jest-worker": { 1955 | "version": "27.5.1", 1956 | "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", 1957 | "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", 1958 | "dev": true, 1959 | "dependencies": { 1960 | "@types/node": "*", 1961 | "merge-stream": "^2.0.0", 1962 | "supports-color": "^8.0.0" 1963 | }, 1964 | "engines": { 1965 | "node": ">= 10.13.0" 1966 | } 1967 | }, 1968 | "node_modules/jest-worker/node_modules/supports-color": { 1969 | "version": "8.1.1", 1970 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1971 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1972 | "dev": true, 1973 | "dependencies": { 1974 | "has-flag": "^4.0.0" 1975 | }, 1976 | "engines": { 1977 | "node": ">=10" 1978 | }, 1979 | "funding": { 1980 | "url": "https://github.com/chalk/supports-color?sponsor=1" 1981 | } 1982 | }, 1983 | "node_modules/js-yaml": { 1984 | "version": "4.1.0", 1985 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1986 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1987 | "dev": true, 1988 | "dependencies": { 1989 | "argparse": "^2.0.1" 1990 | }, 1991 | "bin": { 1992 | "js-yaml": "bin/js-yaml.js" 1993 | } 1994 | }, 1995 | "node_modules/json-buffer": { 1996 | "version": "3.0.1", 1997 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 1998 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 1999 | }, 2000 | "node_modules/json-parse-even-better-errors": { 2001 | "version": "2.3.1", 2002 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", 2003 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", 2004 | "dev": true 2005 | }, 2006 | "node_modules/json-schema-traverse": { 2007 | "version": "1.0.0", 2008 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 2009 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" 2010 | }, 2011 | "node_modules/json-stable-stringify-without-jsonify": { 2012 | "version": "1.0.1", 2013 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 2014 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 2015 | "dev": true 2016 | }, 2017 | "node_modules/keyv": { 2018 | "version": "4.5.4", 2019 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", 2020 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", 2021 | "dependencies": { 2022 | "json-buffer": "3.0.1" 2023 | } 2024 | }, 2025 | "node_modules/kind-of": { 2026 | "version": "6.0.3", 2027 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", 2028 | "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", 2029 | "dev": true, 2030 | "engines": { 2031 | "node": ">=0.10.0" 2032 | } 2033 | }, 2034 | "node_modules/levn": { 2035 | "version": "0.4.1", 2036 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 2037 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 2038 | "dev": true, 2039 | "dependencies": { 2040 | "prelude-ls": "^1.2.1", 2041 | "type-check": "~0.4.0" 2042 | }, 2043 | "engines": { 2044 | "node": ">= 0.8.0" 2045 | } 2046 | }, 2047 | "node_modules/loader-runner": { 2048 | "version": "4.3.0", 2049 | "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", 2050 | "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", 2051 | "dev": true, 2052 | "engines": { 2053 | "node": ">=6.11.5" 2054 | } 2055 | }, 2056 | "node_modules/locate-path": { 2057 | "version": "7.2.0", 2058 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", 2059 | "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", 2060 | "dev": true, 2061 | "dependencies": { 2062 | "p-locate": "^6.0.0" 2063 | }, 2064 | "engines": { 2065 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2066 | }, 2067 | "funding": { 2068 | "url": "https://github.com/sponsors/sindresorhus" 2069 | } 2070 | }, 2071 | "node_modules/lodash.merge": { 2072 | "version": "4.6.2", 2073 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 2074 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 2075 | "dev": true 2076 | }, 2077 | "node_modules/lowercase-keys": { 2078 | "version": "3.0.0", 2079 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", 2080 | "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", 2081 | "engines": { 2082 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2083 | }, 2084 | "funding": { 2085 | "url": "https://github.com/sponsors/sindresorhus" 2086 | } 2087 | }, 2088 | "node_modules/merge-stream": { 2089 | "version": "2.0.0", 2090 | "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", 2091 | "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", 2092 | "dev": true 2093 | }, 2094 | "node_modules/mime-db": { 2095 | "version": "1.52.0", 2096 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 2097 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 2098 | "dev": true, 2099 | "engines": { 2100 | "node": ">= 0.6" 2101 | } 2102 | }, 2103 | "node_modules/mime-types": { 2104 | "version": "2.1.35", 2105 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 2106 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 2107 | "dev": true, 2108 | "dependencies": { 2109 | "mime-db": "1.52.0" 2110 | }, 2111 | "engines": { 2112 | "node": ">= 0.6" 2113 | } 2114 | }, 2115 | "node_modules/mimic-fn": { 2116 | "version": "3.1.0", 2117 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", 2118 | "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", 2119 | "engines": { 2120 | "node": ">=8" 2121 | } 2122 | }, 2123 | "node_modules/mimic-response": { 2124 | "version": "4.0.0", 2125 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", 2126 | "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", 2127 | "engines": { 2128 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2129 | }, 2130 | "funding": { 2131 | "url": "https://github.com/sponsors/sindresorhus" 2132 | } 2133 | }, 2134 | "node_modules/minimatch": { 2135 | "version": "3.1.2", 2136 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 2137 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 2138 | "dev": true, 2139 | "dependencies": { 2140 | "brace-expansion": "^1.1.7" 2141 | }, 2142 | "engines": { 2143 | "node": "*" 2144 | } 2145 | }, 2146 | "node_modules/minipass": { 2147 | "version": "7.1.2", 2148 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 2149 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 2150 | "dev": true, 2151 | "engines": { 2152 | "node": ">=16 || 14 >=14.17" 2153 | } 2154 | }, 2155 | "node_modules/minizlib": { 2156 | "version": "3.0.2", 2157 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", 2158 | "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", 2159 | "dev": true, 2160 | "dependencies": { 2161 | "minipass": "^7.1.2" 2162 | }, 2163 | "engines": { 2164 | "node": ">= 18" 2165 | } 2166 | }, 2167 | "node_modules/mkdirp": { 2168 | "version": "3.0.1", 2169 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", 2170 | "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", 2171 | "dev": true, 2172 | "bin": { 2173 | "mkdirp": "dist/cjs/src/bin.js" 2174 | }, 2175 | "engines": { 2176 | "node": ">=10" 2177 | }, 2178 | "funding": { 2179 | "url": "https://github.com/sponsors/isaacs" 2180 | } 2181 | }, 2182 | "node_modules/ms": { 2183 | "version": "2.1.2", 2184 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2185 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2186 | }, 2187 | "node_modules/nanoid": { 2188 | "version": "3.3.11", 2189 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", 2190 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", 2191 | "funding": [ 2192 | { 2193 | "type": "github", 2194 | "url": "https://github.com/sponsors/ai" 2195 | } 2196 | ], 2197 | "bin": { 2198 | "nanoid": "bin/nanoid.cjs" 2199 | }, 2200 | "engines": { 2201 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 2202 | } 2203 | }, 2204 | "node_modules/natural-compare": { 2205 | "version": "1.4.0", 2206 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 2207 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 2208 | "dev": true 2209 | }, 2210 | "node_modules/neo-async": { 2211 | "version": "2.6.2", 2212 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 2213 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", 2214 | "dev": true 2215 | }, 2216 | "node_modules/node-releases": { 2217 | "version": "2.0.19", 2218 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", 2219 | "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", 2220 | "dev": true 2221 | }, 2222 | "node_modules/normalize-url": { 2223 | "version": "8.0.0", 2224 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", 2225 | "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", 2226 | "engines": { 2227 | "node": ">=14.16" 2228 | }, 2229 | "funding": { 2230 | "url": "https://github.com/sponsors/sindresorhus" 2231 | } 2232 | }, 2233 | "node_modules/optionator": { 2234 | "version": "0.9.3", 2235 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", 2236 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", 2237 | "dev": true, 2238 | "dependencies": { 2239 | "@aashutoshrathi/word-wrap": "^1.2.3", 2240 | "deep-is": "^0.1.3", 2241 | "fast-levenshtein": "^2.0.6", 2242 | "levn": "^0.4.1", 2243 | "prelude-ls": "^1.2.1", 2244 | "type-check": "^0.4.0" 2245 | }, 2246 | "engines": { 2247 | "node": ">= 0.8.0" 2248 | } 2249 | }, 2250 | "node_modules/p-cancelable": { 2251 | "version": "3.0.0", 2252 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", 2253 | "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", 2254 | "engines": { 2255 | "node": ">=12.20" 2256 | } 2257 | }, 2258 | "node_modules/p-finally": { 2259 | "version": "1.0.0", 2260 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 2261 | "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", 2262 | "engines": { 2263 | "node": ">=4" 2264 | } 2265 | }, 2266 | "node_modules/p-limit": { 2267 | "version": "4.0.0", 2268 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", 2269 | "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", 2270 | "dev": true, 2271 | "dependencies": { 2272 | "yocto-queue": "^1.0.0" 2273 | }, 2274 | "engines": { 2275 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2276 | }, 2277 | "funding": { 2278 | "url": "https://github.com/sponsors/sindresorhus" 2279 | } 2280 | }, 2281 | "node_modules/p-locate": { 2282 | "version": "6.0.0", 2283 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", 2284 | "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", 2285 | "dev": true, 2286 | "dependencies": { 2287 | "p-limit": "^4.0.0" 2288 | }, 2289 | "engines": { 2290 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2291 | }, 2292 | "funding": { 2293 | "url": "https://github.com/sponsors/sindresorhus" 2294 | } 2295 | }, 2296 | "node_modules/p-queue": { 2297 | "version": "6.6.2", 2298 | "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", 2299 | "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", 2300 | "dependencies": { 2301 | "eventemitter3": "^4.0.4", 2302 | "p-timeout": "^3.2.0" 2303 | }, 2304 | "engines": { 2305 | "node": ">=8" 2306 | }, 2307 | "funding": { 2308 | "url": "https://github.com/sponsors/sindresorhus" 2309 | } 2310 | }, 2311 | "node_modules/p-queue/node_modules/p-timeout": { 2312 | "version": "3.2.0", 2313 | "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", 2314 | "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", 2315 | "dependencies": { 2316 | "p-finally": "^1.0.0" 2317 | }, 2318 | "engines": { 2319 | "node": ">=8" 2320 | } 2321 | }, 2322 | "node_modules/p-timeout": { 2323 | "version": "4.1.0", 2324 | "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", 2325 | "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==", 2326 | "engines": { 2327 | "node": ">=10" 2328 | } 2329 | }, 2330 | "node_modules/p-try": { 2331 | "version": "2.2.0", 2332 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 2333 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 2334 | "dev": true, 2335 | "engines": { 2336 | "node": ">=6" 2337 | } 2338 | }, 2339 | "node_modules/parent-module": { 2340 | "version": "1.0.1", 2341 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 2342 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 2343 | "dev": true, 2344 | "dependencies": { 2345 | "callsites": "^3.0.0" 2346 | }, 2347 | "engines": { 2348 | "node": ">=6" 2349 | } 2350 | }, 2351 | "node_modules/parse-author": { 2352 | "version": "2.0.0", 2353 | "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", 2354 | "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", 2355 | "dev": true, 2356 | "dependencies": { 2357 | "author-regex": "^1.0.0" 2358 | }, 2359 | "engines": { 2360 | "node": ">=0.10.0" 2361 | } 2362 | }, 2363 | "node_modules/path-exists": { 2364 | "version": "5.0.0", 2365 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", 2366 | "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", 2367 | "dev": true, 2368 | "engines": { 2369 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0" 2370 | } 2371 | }, 2372 | "node_modules/path-key": { 2373 | "version": "3.1.1", 2374 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2375 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2376 | "dev": true, 2377 | "engines": { 2378 | "node": ">=8" 2379 | } 2380 | }, 2381 | "node_modules/path-parse": { 2382 | "version": "1.0.7", 2383 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 2384 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 2385 | "dev": true 2386 | }, 2387 | "node_modules/picocolors": { 2388 | "version": "1.1.1", 2389 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 2390 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 2391 | "dev": true 2392 | }, 2393 | "node_modules/pkg-dir": { 2394 | "version": "4.2.0", 2395 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", 2396 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", 2397 | "dev": true, 2398 | "dependencies": { 2399 | "find-up": "^4.0.0" 2400 | }, 2401 | "engines": { 2402 | "node": ">=8" 2403 | } 2404 | }, 2405 | "node_modules/pkg-dir/node_modules/find-up": { 2406 | "version": "4.1.0", 2407 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", 2408 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", 2409 | "dev": true, 2410 | "dependencies": { 2411 | "locate-path": "^5.0.0", 2412 | "path-exists": "^4.0.0" 2413 | }, 2414 | "engines": { 2415 | "node": ">=8" 2416 | } 2417 | }, 2418 | "node_modules/pkg-dir/node_modules/locate-path": { 2419 | "version": "5.0.0", 2420 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", 2421 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", 2422 | "dev": true, 2423 | "dependencies": { 2424 | "p-locate": "^4.1.0" 2425 | }, 2426 | "engines": { 2427 | "node": ">=8" 2428 | } 2429 | }, 2430 | "node_modules/pkg-dir/node_modules/p-limit": { 2431 | "version": "2.3.0", 2432 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 2433 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 2434 | "dev": true, 2435 | "dependencies": { 2436 | "p-try": "^2.0.0" 2437 | }, 2438 | "engines": { 2439 | "node": ">=6" 2440 | }, 2441 | "funding": { 2442 | "url": "https://github.com/sponsors/sindresorhus" 2443 | } 2444 | }, 2445 | "node_modules/pkg-dir/node_modules/p-locate": { 2446 | "version": "4.1.0", 2447 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", 2448 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", 2449 | "dev": true, 2450 | "dependencies": { 2451 | "p-limit": "^2.2.0" 2452 | }, 2453 | "engines": { 2454 | "node": ">=8" 2455 | } 2456 | }, 2457 | "node_modules/pkg-dir/node_modules/path-exists": { 2458 | "version": "4.0.0", 2459 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 2460 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 2461 | "dev": true, 2462 | "engines": { 2463 | "node": ">=8" 2464 | } 2465 | }, 2466 | "node_modules/prelude-ls": { 2467 | "version": "1.2.1", 2468 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 2469 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 2470 | "dev": true, 2471 | "engines": { 2472 | "node": ">= 0.8.0" 2473 | } 2474 | }, 2475 | "node_modules/prettier": { 2476 | "version": "3.5.3", 2477 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", 2478 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 2479 | "dev": true, 2480 | "peer": true, 2481 | "bin": { 2482 | "prettier": "bin/prettier.cjs" 2483 | }, 2484 | "engines": { 2485 | "node": ">=14" 2486 | }, 2487 | "funding": { 2488 | "url": "https://github.com/prettier/prettier?sponsor=1" 2489 | } 2490 | }, 2491 | "node_modules/prettier-linter-helpers": { 2492 | "version": "1.0.0", 2493 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 2494 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 2495 | "dev": true, 2496 | "dependencies": { 2497 | "fast-diff": "^1.1.2" 2498 | }, 2499 | "engines": { 2500 | "node": ">=6.0.0" 2501 | } 2502 | }, 2503 | "node_modules/punycode": { 2504 | "version": "2.3.1", 2505 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 2506 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 2507 | "dev": true, 2508 | "engines": { 2509 | "node": ">=6" 2510 | } 2511 | }, 2512 | "node_modules/quick-lru": { 2513 | "version": "5.1.1", 2514 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 2515 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 2516 | "engines": { 2517 | "node": ">=10" 2518 | }, 2519 | "funding": { 2520 | "url": "https://github.com/sponsors/sindresorhus" 2521 | } 2522 | }, 2523 | "node_modules/randombytes": { 2524 | "version": "2.1.0", 2525 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 2526 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 2527 | "dev": true, 2528 | "dependencies": { 2529 | "safe-buffer": "^5.1.0" 2530 | } 2531 | }, 2532 | "node_modules/rechoir": { 2533 | "version": "0.8.0", 2534 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", 2535 | "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", 2536 | "dev": true, 2537 | "dependencies": { 2538 | "resolve": "^1.20.0" 2539 | }, 2540 | "engines": { 2541 | "node": ">= 10.13.0" 2542 | } 2543 | }, 2544 | "node_modules/require-from-string": { 2545 | "version": "2.0.2", 2546 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 2547 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 2548 | "engines": { 2549 | "node": ">=0.10.0" 2550 | } 2551 | }, 2552 | "node_modules/resolve": { 2553 | "version": "1.22.10", 2554 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 2555 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 2556 | "dev": true, 2557 | "dependencies": { 2558 | "is-core-module": "^2.16.0", 2559 | "path-parse": "^1.0.7", 2560 | "supports-preserve-symlinks-flag": "^1.0.0" 2561 | }, 2562 | "bin": { 2563 | "resolve": "bin/resolve" 2564 | }, 2565 | "engines": { 2566 | "node": ">= 0.4" 2567 | }, 2568 | "funding": { 2569 | "url": "https://github.com/sponsors/ljharb" 2570 | } 2571 | }, 2572 | "node_modules/resolve-alpn": { 2573 | "version": "1.2.1", 2574 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 2575 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 2576 | }, 2577 | "node_modules/resolve-cwd": { 2578 | "version": "3.0.0", 2579 | "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", 2580 | "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", 2581 | "dev": true, 2582 | "dependencies": { 2583 | "resolve-from": "^5.0.0" 2584 | }, 2585 | "engines": { 2586 | "node": ">=8" 2587 | } 2588 | }, 2589 | "node_modules/resolve-cwd/node_modules/resolve-from": { 2590 | "version": "5.0.0", 2591 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", 2592 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", 2593 | "dev": true, 2594 | "engines": { 2595 | "node": ">=8" 2596 | } 2597 | }, 2598 | "node_modules/resolve-from": { 2599 | "version": "4.0.0", 2600 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2601 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2602 | "dev": true, 2603 | "engines": { 2604 | "node": ">=4" 2605 | } 2606 | }, 2607 | "node_modules/resolve-pkg-maps": { 2608 | "version": "1.0.0", 2609 | "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", 2610 | "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", 2611 | "dev": true, 2612 | "funding": { 2613 | "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" 2614 | } 2615 | }, 2616 | "node_modules/responselike": { 2617 | "version": "3.0.0", 2618 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", 2619 | "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", 2620 | "dependencies": { 2621 | "lowercase-keys": "^3.0.0" 2622 | }, 2623 | "engines": { 2624 | "node": ">=14.16" 2625 | }, 2626 | "funding": { 2627 | "url": "https://github.com/sponsors/sindresorhus" 2628 | } 2629 | }, 2630 | "node_modules/safe-buffer": { 2631 | "version": "5.2.1", 2632 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 2633 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 2634 | "dev": true, 2635 | "funding": [ 2636 | { 2637 | "type": "github", 2638 | "url": "https://github.com/sponsors/feross" 2639 | }, 2640 | { 2641 | "type": "patreon", 2642 | "url": "https://www.patreon.com/feross" 2643 | }, 2644 | { 2645 | "type": "consulting", 2646 | "url": "https://feross.org/support" 2647 | } 2648 | ] 2649 | }, 2650 | "node_modules/schema-utils": { 2651 | "version": "4.3.0", 2652 | "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", 2653 | "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", 2654 | "dev": true, 2655 | "dependencies": { 2656 | "@types/json-schema": "^7.0.9", 2657 | "ajv": "^8.9.0", 2658 | "ajv-formats": "^2.1.1", 2659 | "ajv-keywords": "^5.1.0" 2660 | }, 2661 | "engines": { 2662 | "node": ">= 10.13.0" 2663 | }, 2664 | "funding": { 2665 | "type": "opencollective", 2666 | "url": "https://opencollective.com/webpack" 2667 | } 2668 | }, 2669 | "node_modules/semver": { 2670 | "version": "7.7.1", 2671 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", 2672 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", 2673 | "dev": true, 2674 | "bin": { 2675 | "semver": "bin/semver.js" 2676 | }, 2677 | "engines": { 2678 | "node": ">=10" 2679 | } 2680 | }, 2681 | "node_modules/serialize-javascript": { 2682 | "version": "6.0.2", 2683 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 2684 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 2685 | "dev": true, 2686 | "dependencies": { 2687 | "randombytes": "^2.1.0" 2688 | } 2689 | }, 2690 | "node_modules/shallow-clone": { 2691 | "version": "3.0.1", 2692 | "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", 2693 | "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", 2694 | "dev": true, 2695 | "dependencies": { 2696 | "kind-of": "^6.0.2" 2697 | }, 2698 | "engines": { 2699 | "node": ">=8" 2700 | } 2701 | }, 2702 | "node_modules/shebang-command": { 2703 | "version": "2.0.0", 2704 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2705 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2706 | "dev": true, 2707 | "dependencies": { 2708 | "shebang-regex": "^3.0.0" 2709 | }, 2710 | "engines": { 2711 | "node": ">=8" 2712 | } 2713 | }, 2714 | "node_modules/shebang-regex": { 2715 | "version": "3.0.0", 2716 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2717 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2718 | "dev": true, 2719 | "engines": { 2720 | "node": ">=8" 2721 | } 2722 | }, 2723 | "node_modules/socket.io-client": { 2724 | "version": "4.7.4", 2725 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.4.tgz", 2726 | "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==", 2727 | "dependencies": { 2728 | "@socket.io/component-emitter": "~3.1.0", 2729 | "debug": "~4.3.2", 2730 | "engine.io-client": "~6.5.2", 2731 | "socket.io-parser": "~4.2.4" 2732 | }, 2733 | "engines": { 2734 | "node": ">=10.0.0" 2735 | } 2736 | }, 2737 | "node_modules/socket.io-parser": { 2738 | "version": "4.2.4", 2739 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", 2740 | "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", 2741 | "dependencies": { 2742 | "@socket.io/component-emitter": "~3.1.0", 2743 | "debug": "~4.3.1" 2744 | }, 2745 | "engines": { 2746 | "node": ">=10.0.0" 2747 | } 2748 | }, 2749 | "node_modules/source-map": { 2750 | "version": "0.6.1", 2751 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2752 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2753 | "dev": true, 2754 | "engines": { 2755 | "node": ">=0.10.0" 2756 | } 2757 | }, 2758 | "node_modules/source-map-support": { 2759 | "version": "0.5.21", 2760 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 2761 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 2762 | "dev": true, 2763 | "dependencies": { 2764 | "buffer-from": "^1.0.0", 2765 | "source-map": "^0.6.0" 2766 | } 2767 | }, 2768 | "node_modules/strip-json-comments": { 2769 | "version": "3.1.1", 2770 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2771 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2772 | "dev": true, 2773 | "engines": { 2774 | "node": ">=8" 2775 | }, 2776 | "funding": { 2777 | "url": "https://github.com/sponsors/sindresorhus" 2778 | } 2779 | }, 2780 | "node_modules/supports-color": { 2781 | "version": "7.2.0", 2782 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2783 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2784 | "dev": true, 2785 | "dependencies": { 2786 | "has-flag": "^4.0.0" 2787 | }, 2788 | "engines": { 2789 | "node": ">=8" 2790 | } 2791 | }, 2792 | "node_modules/supports-preserve-symlinks-flag": { 2793 | "version": "1.0.0", 2794 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2795 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2796 | "dev": true, 2797 | "engines": { 2798 | "node": ">= 0.4" 2799 | }, 2800 | "funding": { 2801 | "url": "https://github.com/sponsors/ljharb" 2802 | } 2803 | }, 2804 | "node_modules/synckit": { 2805 | "version": "0.10.3", 2806 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.10.3.tgz", 2807 | "integrity": "sha512-R1urvuyiTaWfeCggqEvpDJwAlDVdsT9NM+IP//Tk2x7qHCkSvBk/fwFgw/TLAHzZlrAnnazMcRw0ZD8HlYFTEQ==", 2808 | "dev": true, 2809 | "dependencies": { 2810 | "@pkgr/core": "^0.2.0", 2811 | "tslib": "^2.8.1" 2812 | }, 2813 | "engines": { 2814 | "node": "^14.18.0 || >=16.0.0" 2815 | }, 2816 | "funding": { 2817 | "url": "https://opencollective.com/unts" 2818 | } 2819 | }, 2820 | "node_modules/tapable": { 2821 | "version": "2.2.1", 2822 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", 2823 | "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", 2824 | "dev": true, 2825 | "engines": { 2826 | "node": ">=6" 2827 | } 2828 | }, 2829 | "node_modules/tar": { 2830 | "version": "7.4.3", 2831 | "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", 2832 | "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", 2833 | "dev": true, 2834 | "dependencies": { 2835 | "@isaacs/fs-minipass": "^4.0.0", 2836 | "chownr": "^3.0.0", 2837 | "minipass": "^7.1.2", 2838 | "minizlib": "^3.0.1", 2839 | "mkdirp": "^3.0.1", 2840 | "yallist": "^5.0.0" 2841 | }, 2842 | "engines": { 2843 | "node": ">=18" 2844 | } 2845 | }, 2846 | "node_modules/terser": { 2847 | "version": "5.39.0", 2848 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", 2849 | "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", 2850 | "dev": true, 2851 | "dependencies": { 2852 | "@jridgewell/source-map": "^0.3.3", 2853 | "acorn": "^8.8.2", 2854 | "commander": "^2.20.0", 2855 | "source-map-support": "~0.5.20" 2856 | }, 2857 | "bin": { 2858 | "terser": "bin/terser" 2859 | }, 2860 | "engines": { 2861 | "node": ">=10" 2862 | } 2863 | }, 2864 | "node_modules/terser-webpack-plugin": { 2865 | "version": "5.3.14", 2866 | "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", 2867 | "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", 2868 | "dev": true, 2869 | "dependencies": { 2870 | "@jridgewell/trace-mapping": "^0.3.25", 2871 | "jest-worker": "^27.4.5", 2872 | "schema-utils": "^4.3.0", 2873 | "serialize-javascript": "^6.0.2", 2874 | "terser": "^5.31.1" 2875 | }, 2876 | "engines": { 2877 | "node": ">= 10.13.0" 2878 | }, 2879 | "funding": { 2880 | "type": "opencollective", 2881 | "url": "https://opencollective.com/webpack" 2882 | }, 2883 | "peerDependencies": { 2884 | "webpack": "^5.1.0" 2885 | }, 2886 | "peerDependenciesMeta": { 2887 | "@swc/core": { 2888 | "optional": true 2889 | }, 2890 | "esbuild": { 2891 | "optional": true 2892 | }, 2893 | "uglify-js": { 2894 | "optional": true 2895 | } 2896 | } 2897 | }, 2898 | "node_modules/tslib": { 2899 | "version": "2.8.1", 2900 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 2901 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" 2902 | }, 2903 | "node_modules/type-check": { 2904 | "version": "0.4.0", 2905 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2906 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2907 | "dev": true, 2908 | "dependencies": { 2909 | "prelude-ls": "^1.2.1" 2910 | }, 2911 | "engines": { 2912 | "node": ">= 0.8.0" 2913 | } 2914 | }, 2915 | "node_modules/undici-types": { 2916 | "version": "6.20.0", 2917 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 2918 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 2919 | "dev": true 2920 | }, 2921 | "node_modules/unicorn-magic": { 2922 | "version": "0.1.0", 2923 | "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", 2924 | "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", 2925 | "dev": true, 2926 | "engines": { 2927 | "node": ">=18" 2928 | }, 2929 | "funding": { 2930 | "url": "https://github.com/sponsors/sindresorhus" 2931 | } 2932 | }, 2933 | "node_modules/update-browserslist-db": { 2934 | "version": "1.1.3", 2935 | "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", 2936 | "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", 2937 | "dev": true, 2938 | "funding": [ 2939 | { 2940 | "type": "opencollective", 2941 | "url": "https://opencollective.com/browserslist" 2942 | }, 2943 | { 2944 | "type": "tidelift", 2945 | "url": "https://tidelift.com/funding/github/npm/browserslist" 2946 | }, 2947 | { 2948 | "type": "github", 2949 | "url": "https://github.com/sponsors/ai" 2950 | } 2951 | ], 2952 | "dependencies": { 2953 | "escalade": "^3.2.0", 2954 | "picocolors": "^1.1.1" 2955 | }, 2956 | "bin": { 2957 | "update-browserslist-db": "cli.js" 2958 | }, 2959 | "peerDependencies": { 2960 | "browserslist": ">= 4.21.0" 2961 | } 2962 | }, 2963 | "node_modules/uri-js": { 2964 | "version": "4.4.1", 2965 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2966 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2967 | "dev": true, 2968 | "dependencies": { 2969 | "punycode": "^2.1.0" 2970 | } 2971 | }, 2972 | "node_modules/watchpack": { 2973 | "version": "2.4.2", 2974 | "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", 2975 | "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", 2976 | "dev": true, 2977 | "dependencies": { 2978 | "glob-to-regexp": "^0.4.1", 2979 | "graceful-fs": "^4.1.2" 2980 | }, 2981 | "engines": { 2982 | "node": ">=10.13.0" 2983 | } 2984 | }, 2985 | "node_modules/webpack": { 2986 | "version": "5.98.0", 2987 | "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", 2988 | "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", 2989 | "dev": true, 2990 | "dependencies": { 2991 | "@types/eslint-scope": "^3.7.7", 2992 | "@types/estree": "^1.0.6", 2993 | "@webassemblyjs/ast": "^1.14.1", 2994 | "@webassemblyjs/wasm-edit": "^1.14.1", 2995 | "@webassemblyjs/wasm-parser": "^1.14.1", 2996 | "acorn": "^8.14.0", 2997 | "browserslist": "^4.24.0", 2998 | "chrome-trace-event": "^1.0.2", 2999 | "enhanced-resolve": "^5.17.1", 3000 | "es-module-lexer": "^1.2.1", 3001 | "eslint-scope": "5.1.1", 3002 | "events": "^3.2.0", 3003 | "glob-to-regexp": "^0.4.1", 3004 | "graceful-fs": "^4.2.11", 3005 | "json-parse-even-better-errors": "^2.3.1", 3006 | "loader-runner": "^4.2.0", 3007 | "mime-types": "^2.1.27", 3008 | "neo-async": "^2.6.2", 3009 | "schema-utils": "^4.3.0", 3010 | "tapable": "^2.1.1", 3011 | "terser-webpack-plugin": "^5.3.11", 3012 | "watchpack": "^2.4.1", 3013 | "webpack-sources": "^3.2.3" 3014 | }, 3015 | "bin": { 3016 | "webpack": "bin/webpack.js" 3017 | }, 3018 | "engines": { 3019 | "node": ">=10.13.0" 3020 | }, 3021 | "funding": { 3022 | "type": "opencollective", 3023 | "url": "https://opencollective.com/webpack" 3024 | }, 3025 | "peerDependenciesMeta": { 3026 | "webpack-cli": { 3027 | "optional": true 3028 | } 3029 | } 3030 | }, 3031 | "node_modules/webpack-cli": { 3032 | "version": "6.0.1", 3033 | "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", 3034 | "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", 3035 | "dev": true, 3036 | "dependencies": { 3037 | "@discoveryjs/json-ext": "^0.6.1", 3038 | "@webpack-cli/configtest": "^3.0.1", 3039 | "@webpack-cli/info": "^3.0.1", 3040 | "@webpack-cli/serve": "^3.0.1", 3041 | "colorette": "^2.0.14", 3042 | "commander": "^12.1.0", 3043 | "cross-spawn": "^7.0.3", 3044 | "envinfo": "^7.14.0", 3045 | "fastest-levenshtein": "^1.0.12", 3046 | "import-local": "^3.0.2", 3047 | "interpret": "^3.1.1", 3048 | "rechoir": "^0.8.0", 3049 | "webpack-merge": "^6.0.1" 3050 | }, 3051 | "bin": { 3052 | "webpack-cli": "bin/cli.js" 3053 | }, 3054 | "engines": { 3055 | "node": ">=18.12.0" 3056 | }, 3057 | "funding": { 3058 | "type": "opencollective", 3059 | "url": "https://opencollective.com/webpack" 3060 | }, 3061 | "peerDependencies": { 3062 | "webpack": "^5.82.0" 3063 | }, 3064 | "peerDependenciesMeta": { 3065 | "webpack-bundle-analyzer": { 3066 | "optional": true 3067 | }, 3068 | "webpack-dev-server": { 3069 | "optional": true 3070 | } 3071 | } 3072 | }, 3073 | "node_modules/webpack-cli/node_modules/commander": { 3074 | "version": "12.1.0", 3075 | "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", 3076 | "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", 3077 | "dev": true, 3078 | "engines": { 3079 | "node": ">=18" 3080 | } 3081 | }, 3082 | "node_modules/webpack-merge": { 3083 | "version": "6.0.1", 3084 | "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", 3085 | "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", 3086 | "dev": true, 3087 | "dependencies": { 3088 | "clone-deep": "^4.0.1", 3089 | "flat": "^5.0.2", 3090 | "wildcard": "^2.0.1" 3091 | }, 3092 | "engines": { 3093 | "node": ">=18.0.0" 3094 | } 3095 | }, 3096 | "node_modules/webpack-sources": { 3097 | "version": "3.2.3", 3098 | "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", 3099 | "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", 3100 | "dev": true, 3101 | "engines": { 3102 | "node": ">=10.13.0" 3103 | } 3104 | }, 3105 | "node_modules/which": { 3106 | "version": "2.0.2", 3107 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 3108 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 3109 | "dev": true, 3110 | "dependencies": { 3111 | "isexe": "^2.0.0" 3112 | }, 3113 | "bin": { 3114 | "node-which": "bin/node-which" 3115 | }, 3116 | "engines": { 3117 | "node": ">= 8" 3118 | } 3119 | }, 3120 | "node_modules/wildcard": { 3121 | "version": "2.0.1", 3122 | "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", 3123 | "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", 3124 | "dev": true 3125 | }, 3126 | "node_modules/ws": { 3127 | "version": "8.17.1", 3128 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", 3129 | "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", 3130 | "engines": { 3131 | "node": ">=10.0.0" 3132 | }, 3133 | "peerDependencies": { 3134 | "bufferutil": "^4.0.1", 3135 | "utf-8-validate": ">=5.0.2" 3136 | }, 3137 | "peerDependenciesMeta": { 3138 | "bufferutil": { 3139 | "optional": true 3140 | }, 3141 | "utf-8-validate": { 3142 | "optional": true 3143 | } 3144 | } 3145 | }, 3146 | "node_modules/xmlhttprequest-ssl": { 3147 | "version": "2.0.0", 3148 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", 3149 | "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", 3150 | "engines": { 3151 | "node": ">=0.4.0" 3152 | } 3153 | }, 3154 | "node_modules/yallist": { 3155 | "version": "5.0.0", 3156 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", 3157 | "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", 3158 | "dev": true, 3159 | "engines": { 3160 | "node": ">=18" 3161 | } 3162 | }, 3163 | "node_modules/yocto-queue": { 3164 | "version": "1.2.1", 3165 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", 3166 | "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", 3167 | "dev": true, 3168 | "engines": { 3169 | "node": ">=12.20" 3170 | }, 3171 | "funding": { 3172 | "url": "https://github.com/sponsors/sindresorhus" 3173 | } 3174 | }, 3175 | "node_modules/zx": { 3176 | "version": "8.5.0", 3177 | "resolved": "https://registry.npmjs.org/zx/-/zx-8.5.0.tgz", 3178 | "integrity": "sha512-XS5/oKOQxKNfG2sVO6TQQjZF5RqWGE5QGSUOCZZVTnvYr3RDBTdbX3IFmV9CrnycCAQWcY0hAD3DDUa4RJE4+w==", 3179 | "dev": true, 3180 | "bin": { 3181 | "zx": "build/cli.js" 3182 | }, 3183 | "engines": { 3184 | "node": ">= 12.17.0" 3185 | } 3186 | } 3187 | } 3188 | } 3189 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "h2r-graphics", 3 | "version": "3.7.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "format": "prettier -w .", 8 | "lint:raw": "eslint --ext .ts --ext .js --ignore-pattern dist --ignore-pattern pkg", 9 | "lint": "yarn lint:raw ." 10 | }, 11 | "license": "MIT", 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/bitfocus/companion-module-h2r-graphics.git" 15 | }, 16 | "dependencies": { 17 | "@companion-module/base": "^1.11.3", 18 | "got": "^13.0.0", 19 | "socket.io-client": "^4.6.0" 20 | }, 21 | "devDependencies": { 22 | "@companion-module/tools": "^2.2.2", 23 | "eslint": "^9.23.0" 24 | }, 25 | "prettier": "@companion-module/tools/.prettierrc.json", 26 | "type": "module" 27 | } 28 | -------------------------------------------------------------------------------- /src/actions.js: -------------------------------------------------------------------------------- 1 | import got from 'got' 2 | 3 | import { graphicToReadableLabel, stringToMS } from './utils.js' 4 | import { splitHex } from '@companion-module/base' 5 | 6 | const GRAPHIC_STATUS_TOGGLES = [ 7 | { id: 'coming', label: 'Show' }, 8 | { id: 'going', label: 'Hide' }, 9 | { id: 'toggle', label: 'Toggle on/off air' }, 10 | { id: 'cued', label: 'Cue on' }, 11 | { id: 'cuedoff', label: 'Cue off' }, 12 | { id: 'toggle-cued', label: 'Toggle Cued on/off' }, 13 | ] 14 | 15 | const DRAW_BRUSH_SIZES = [ 16 | { label: 'Extra small', id: 1 }, 17 | { label: 'Small', id: 3 }, 18 | { label: 'Medium', id: 6 }, 19 | { label: 'Large', id: 8 }, 20 | { label: 'Extra large', id: 10 }, 21 | ] 22 | 23 | const GRAPHIC_POSITION_OPTIONS = [ 24 | { id: 'tl', label: 'Top Left' }, 25 | { id: 'tc', label: 'Top Middle' }, 26 | { id: 'tr', label: 'Top Right' }, 27 | { id: 'ml', label: 'Middle Left' }, 28 | { id: 'mc', label: 'Middle' }, 29 | { id: 'mr', label: 'Middle Right' }, 30 | { id: 'bl', label: 'Bottom Left' }, 31 | { id: 'bc', label: 'Bottom Middle' }, 32 | { id: 'br', label: 'Bottom Right' }, 33 | ] 34 | 35 | export const actionsV2 = (self) => { 36 | let SELECTED_PROJECT_GRAPHICS = self.SELECTED_PROJECT_GRAPHICS || [] 37 | let SELECTED_PROJECT_MEDIA = self.SELECTED_PROJECT_MEDIA || [] 38 | let SELECTED_PROJECT_THEMES = self.SELECTED_PROJECT_THEMES || {} 39 | 40 | const sendHttpMessage = async (cmd = '', body = {}) => { 41 | var baseUri = `http://${self.config.host}:${self.config.portV2}/api/${self.config.projectId}` 42 | 43 | self.log('debug', `ATTEMPTING ${baseUri}/${cmd}`) 44 | await got.post(`${baseUri}/${cmd}`, { 45 | json: { 46 | ...body, 47 | }, 48 | }) 49 | } 50 | 51 | return { 52 | run: { 53 | name: 'Run', 54 | options: [], 55 | callback: async () => { 56 | sendHttpMessage(`run`) 57 | }, 58 | }, 59 | clear: { 60 | name: 'Hide all', 61 | options: [], 62 | callback: async () => { 63 | sendHttpMessage(`clear`) 64 | }, 65 | }, 66 | draw_on: { 67 | name: 'Draw on screen - On', 68 | options: [], 69 | callback: async () => { 70 | sendHttpMessage(`draw/on`) 71 | }, 72 | }, 73 | draw_off: { 74 | name: 'Draw on screen - Off', 75 | options: [], 76 | callback: async () => { 77 | sendHttpMessage(`draw/off`) 78 | }, 79 | }, 80 | draw_size: { 81 | name: 'Draw on screen - Set brush size', 82 | options: [ 83 | { 84 | type: 'dropdown', 85 | label: 'Brush size', 86 | id: 'size', 87 | default: DRAW_BRUSH_SIZES[3].id, 88 | choices: DRAW_BRUSH_SIZES, 89 | }, 90 | ], 91 | callback: async (action) => { 92 | sendHttpMessage(`draw/size/${action.options.size}`) 93 | }, 94 | }, 95 | draw_color: { 96 | name: 'Draw on screen - Set color', 97 | options: [ 98 | { 99 | id: 'color', 100 | type: 'colorpicker', 101 | label: 'Brush color', 102 | default: 'rgb(255, 0, 0)', 103 | }, 104 | ], 105 | callback: async (action) => { 106 | const color = splitHex(action.options.color) 107 | console.log('COLOUR', color) 108 | sendHttpMessage(`draw/color/${color.split('#')[1]}`) 109 | }, 110 | }, 111 | showHide: { 112 | name: 'Show/Hide graphic', 113 | options: [ 114 | { 115 | type: 'dropdown', 116 | label: 'Show/Hide', 117 | id: 'status', 118 | default: 'coming', 119 | choices: GRAPHIC_STATUS_TOGGLES, 120 | }, 121 | { 122 | type: 'dropdown', 123 | label: 'Graphic', 124 | id: 'graphicId', 125 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 126 | choices: [ 127 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 128 | const { id, label } = graphicToReadableLabel(c) 129 | 130 | return { 131 | id, 132 | label, 133 | } 134 | }), 135 | ], 136 | }, 137 | ], 138 | callback: async (action) => { 139 | sendHttpMessage(`graphic/${action.options.graphicId}/update`, { 140 | status: action.options.status, 141 | }) 142 | }, 143 | }, 144 | showHideGraphicWithVariable: { 145 | name: 'Show/Hide graphic (using Text or Variable)', 146 | options: [ 147 | { 148 | type: 'dropdown', 149 | label: 'Show/Hide', 150 | id: 'status', 151 | default: 'coming', 152 | choices: GRAPHIC_STATUS_TOGGLES, 153 | }, 154 | { 155 | type: 'textinput', 156 | label: 'Graphic', 157 | id: 'graphicId', 158 | default: '', 159 | useVariables: true, 160 | }, 161 | ], 162 | callback: async (action) => { 163 | const graphicId = await self.parseVariablesInString(action.options.graphicId || '') 164 | sendHttpMessage(`graphic/${graphicId}/update`, { 165 | status: action.options.status, 166 | }) 167 | }, 168 | }, 169 | updateContentLowerThird: { 170 | name: 'Update content - Lower third', 171 | options: [ 172 | { 173 | type: 'dropdown', 174 | label: 'Graphic', 175 | id: 'graphicId', 176 | choices: [ 177 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'lower_third').map((c) => { 178 | const { id, label } = graphicToReadableLabel(c) 179 | 180 | return { 181 | id, 182 | label, 183 | } 184 | }), 185 | ], 186 | }, 187 | { 188 | type: 'textinput', 189 | label: 'Line one', 190 | id: 'line_one', 191 | useVariables: true, 192 | }, 193 | { 194 | type: 'textinput', 195 | label: 'Line two', 196 | id: 'line_two', 197 | useVariables: true, 198 | }, 199 | ], 200 | callback: async (action) => { 201 | let l1 = await self.parseVariablesInString(action.options.line_one || '') 202 | let l2 = await self.parseVariablesInString(action.options.line_two || '') 203 | let cmd = `graphic/${action.options.graphicId}/update` 204 | let body = { 205 | line_one: l1, 206 | line_two: l2, 207 | } 208 | await sendHttpMessage(cmd, body) 209 | }, 210 | }, 211 | updateContentLowerThirdAnimated: { 212 | name: 'Update content - Lower Third Animated', 213 | options: [ 214 | { 215 | type: 'dropdown', 216 | label: 'Graphic', 217 | id: 'graphicId', 218 | choices: [ 219 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'lower_third_animated').map((c) => { 220 | const { id, label } = graphicToReadableLabel(c) 221 | 222 | return { 223 | id, 224 | label, 225 | } 226 | }), 227 | ], 228 | }, 229 | { 230 | type: 'dropdown', 231 | label: 'Animation', 232 | id: 'animationName', 233 | default: 'reveal', 234 | choices: [ 235 | { 236 | id: 'reveal', 237 | label: 'Reveal', 238 | }, 239 | { 240 | id: 'unfold', 241 | label: 'Unfold', 242 | }, 243 | { 244 | id: 'slide-out', 245 | label: 'Slide out', 246 | }, 247 | ], 248 | }, 249 | { 250 | type: 'textinput', 251 | label: 'Line one', 252 | id: 'line_one', 253 | useVariables: true, 254 | }, 255 | { 256 | type: 'textinput', 257 | label: 'Line two', 258 | id: 'line_two', 259 | useVariables: true, 260 | }, 261 | ], 262 | callback: async (action) => { 263 | let l1 = await self.parseVariablesInString(action.options.line_one || '') 264 | let l2 = await self.parseVariablesInString(action.options.line_two || '') 265 | 266 | let cmd = `graphic/${action.options.graphicId}/update` 267 | let body = { 268 | animationName: action.options.animationName, 269 | line_one: l1, 270 | line_two: l2, 271 | } 272 | await sendHttpMessage(cmd, body) 273 | }, 274 | }, 275 | updateContentMessage: { 276 | name: 'Update content - Message', 277 | options: [ 278 | { 279 | type: 'dropdown', 280 | label: 'Graphic', 281 | id: 'graphicId', 282 | choices: [ 283 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'message').map((c) => { 284 | const { id, label } = graphicToReadableLabel(c) 285 | 286 | return { 287 | id, 288 | label, 289 | } 290 | }), 291 | ], 292 | }, 293 | { 294 | type: 'textinput', 295 | label: 'Message body', 296 | id: 'body', 297 | useVariables: true, 298 | }, 299 | ], 300 | callback: async (action) => { 301 | let b = await self.parseVariablesInString(action.options.body || '') 302 | 303 | let cmd = `graphic/${action.options.graphicId}/update` 304 | let body = { 305 | body: b, 306 | } 307 | await sendHttpMessage(cmd, body) 308 | }, 309 | }, 310 | updateContentTime: { 311 | name: 'Update content - Time', 312 | options: [ 313 | { 314 | type: 'dropdown', 315 | label: 'Graphic', 316 | id: 'graphicId', 317 | choices: [ 318 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'time').map((c) => { 319 | const { id, label } = graphicToReadableLabel(c) 320 | 321 | return { 322 | id, 323 | label, 324 | } 325 | }), 326 | ], 327 | }, 328 | { 329 | type: 'dropdown', 330 | label: 'Type', 331 | id: 'type', 332 | default: 'time_of_day', 333 | choices: [ 334 | { 335 | id: 'time_of_day', 336 | label: 'Current time of day', 337 | }, 338 | { 339 | id: 'to_time_of_day', 340 | label: 'To time of day', 341 | }, 342 | { 343 | id: 'countdown', 344 | label: 'Count down', 345 | }, 346 | { 347 | id: 'countup', 348 | label: 'Count up', 349 | }, 350 | ], 351 | }, 352 | { 353 | type: 'textinput', 354 | label: 'Time (HH:MM:SS)', 355 | id: 'time', 356 | default: '00:01:00', 357 | }, 358 | ], 359 | callback: async (action) => { 360 | let cmd = `graphic/${action.options.graphicId}/update` 361 | let body = {} 362 | let d = new Date() 363 | if (action.options.type === 'time_of_day') { 364 | body = { 365 | timerType: action.options.type, 366 | } 367 | } else if (action.options.type === 'to_time_of_day') { 368 | body = { 369 | timerType: action.options.type, 370 | endTime: action.options.time, 371 | timeLeft: stringToMS(action.options.time) - d.getMilliseconds(), 372 | } 373 | } else if (action.options.type === 'countdown') { 374 | body = { 375 | timerType: action.options.type, 376 | duration: action.options.time, 377 | durationMS: stringToMS(action.options.time), 378 | timeLeft: stringToMS(action.options.time), 379 | } 380 | } else if (action.options.type === 'countup') { 381 | body = { 382 | timerType: action.options.type, 383 | duration: action.options.time, 384 | durationMS: stringToMS(action.options.time), 385 | timeLeft: 0, 386 | } 387 | } 388 | 389 | sendHttpMessage(cmd, body) 390 | }, 391 | }, 392 | updateContentBigTimer: { 393 | name: 'Update content - Big Timer', 394 | options: [ 395 | { 396 | type: 'dropdown', 397 | label: 'Graphic', 398 | id: 'graphicId', 399 | choices: [ 400 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'big_time').map((c) => { 401 | const { id, label } = graphicToReadableLabel(c) 402 | 403 | return { 404 | id, 405 | label, 406 | } 407 | }), 408 | ], 409 | }, 410 | { 411 | type: 'dropdown', 412 | label: 'Shape', 413 | id: 'shape', 414 | default: 'circle', 415 | choices: [ 416 | { 417 | id: 'circle', 418 | label: 'Circle', 419 | }, 420 | { 421 | id: 'line', 422 | label: 'Line', 423 | }, 424 | { 425 | id: 'mask', 426 | label: 'Mask', 427 | }, 428 | ], 429 | }, 430 | { 431 | type: 'dropdown', 432 | label: 'Type', 433 | id: 'type', 434 | default: 'countdown', 435 | choices: [ 436 | { 437 | id: 'countdown', 438 | label: 'Count down', 439 | }, 440 | { 441 | id: 'countup', 442 | label: 'Count up', 443 | }, 444 | ], 445 | }, 446 | { 447 | type: 'textinput', 448 | label: 'Time (HH:MM:SS)', 449 | id: 'time', 450 | default: '00:01:00', 451 | }, 452 | ], 453 | callback: async (action) => { 454 | let cmd = `graphic/${action.options.graphicId}/update` 455 | let body = {} 456 | if (action.options.type === 'countdown') { 457 | body = { 458 | shape: action.options.shape, 459 | timerType: action.options.type, 460 | duration: action.options.time, 461 | durationMS: stringToMS(action.options.time), 462 | timeLeft: stringToMS(action.options.time), 463 | } 464 | } else if (action.options.type === 'countup') { 465 | body = { 466 | shape: action.options.shape, 467 | timerType: action.options.type, 468 | duration: action.options.time, 469 | durationMS: stringToMS(action.options.time), 470 | timeLeft: 0, 471 | } 472 | } 473 | 474 | sendHttpMessage(cmd, body) 475 | }, 476 | }, 477 | updateContentImage: { 478 | name: 'Update content - Image', 479 | options: [ 480 | { 481 | type: 'dropdown', 482 | label: 'Graphic', 483 | id: 'graphicId', 484 | choices: [ 485 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'image').map((c) => { 486 | const { id, label } = graphicToReadableLabel(c) 487 | 488 | return { 489 | id, 490 | label, 491 | } 492 | }), 493 | ], 494 | }, 495 | { 496 | type: 'textinput', 497 | label: 'Name', 498 | id: 'imageName', 499 | }, 500 | { 501 | type: 'dropdown', 502 | label: 'Image', 503 | id: 'imageFilename', 504 | choices: [ 505 | ...SELECTED_PROJECT_MEDIA.map((img) => { 506 | return { 507 | id: img.filename, 508 | label: img.originalname, 509 | } 510 | }), 511 | ], 512 | }, 513 | ], 514 | callback: async (action) => { 515 | let cmd = `graphic/${action.options.graphicId}/update` 516 | let body = { 517 | name: action.options.image_name, 518 | filename: `${action.options.imageFilename}`, 519 | } 520 | 521 | sendHttpMessage(cmd, body) 522 | }, 523 | }, 524 | updateContentTicker: { 525 | name: 'Update content - Ticker', 526 | options: [ 527 | { 528 | type: 'dropdown', 529 | label: 'Graphic', 530 | id: 'graphicId', 531 | choices: [ 532 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'ticker').map((c) => { 533 | const { id, label } = graphicToReadableLabel(c) 534 | 535 | return { 536 | id, 537 | label, 538 | } 539 | }), 540 | ], 541 | }, 542 | { 543 | type: 'textinput', 544 | label: 'Title', 545 | id: 'title', 546 | useVariables: true, 547 | }, 548 | { 549 | type: 'textinput', 550 | label: 'Items (Use | to split items)', 551 | id: 'items', 552 | useVariables: true, 553 | }, 554 | ], 555 | callback: async (action) => { 556 | let t = await self.parseVariablesInString(action.options.title || '') 557 | let items = await self.parseVariablesInString(action.options.items || '') 558 | 559 | let cmd = `graphic/${action.options.graphicId}/update` 560 | let body = { 561 | title: t, 562 | items: items.split('|').map((item, i) => { 563 | return { 564 | title: `Item ${i + 1}`, 565 | body: item, 566 | } 567 | }), 568 | } 569 | 570 | await sendHttpMessage(cmd, body) 571 | }, 572 | }, 573 | updateContentWebpage: { 574 | name: 'Update content - Webpage', 575 | options: [ 576 | { 577 | type: 'dropdown', 578 | label: 'Graphic', 579 | id: 'graphicId', 580 | choices: [ 581 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'webpage').map((c) => { 582 | const { id, label } = graphicToReadableLabel(c) 583 | 584 | return { 585 | id, 586 | label, 587 | } 588 | }), 589 | ], 590 | }, 591 | { 592 | type: 'textinput', 593 | label: 'Name', 594 | id: 'name', 595 | useVariables: true, 596 | }, 597 | { 598 | type: 'textinput', 599 | label: 'URL', 600 | id: 'url', 601 | useVariables: true, 602 | }, 603 | ], 604 | callback: async (action) => { 605 | let name = await self.parseVariablesInString(action.options.name || '') 606 | let url = await self.parseVariablesInString(action.options.url || '') 607 | 608 | let cmd = `graphic/${action.options.graphicId}/update` 609 | let body = { 610 | name: name, 611 | url: url, 612 | } 613 | 614 | await sendHttpMessage(cmd, body) 615 | }, 616 | }, 617 | refreshWebpage: { 618 | name: 'Refresh Webpage', 619 | options: [ 620 | { 621 | type: 'dropdown', 622 | label: 'Graphic', 623 | id: 'graphicId', 624 | choices: [ 625 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'webpage').map((c) => { 626 | const { id, label } = graphicToReadableLabel(c) 627 | 628 | return { 629 | id, 630 | label, 631 | } 632 | }), 633 | ], 634 | }, 635 | ], 636 | callback: async (action) => { 637 | let cmd = `graphic/${action.options.graphicId}/update` 638 | let body = { 639 | refreshCount: new Date().getTime(), 640 | } 641 | 642 | await sendHttpMessage(cmd, body) 643 | }, 644 | }, 645 | updateContentUtilityLargeText: { 646 | name: 'Update content - Large Text (Utility)', 647 | options: [ 648 | { 649 | type: 'dropdown', 650 | label: 'Graphic', 651 | id: 'graphicId', 652 | choices: [ 653 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'utility_large_text').map((c) => { 654 | const { id, label } = graphicToReadableLabel(c) 655 | 656 | return { 657 | id, 658 | label, 659 | } 660 | }), 661 | ], 662 | }, 663 | { 664 | type: 'textinput', 665 | label: 'Text', 666 | id: 'text', 667 | useVariables: true, 668 | }, 669 | ], 670 | callback: async (action) => { 671 | let t = await self.parseVariablesInString(action.options.text || '') 672 | 673 | let cmd = `graphic/${action.options.graphicId}/update` 674 | let body = { 675 | text: t, 676 | } 677 | await sendHttpMessage(cmd, body) 678 | }, 679 | }, 680 | speakerTimerRun: { 681 | name: 'Run/Resume - Timer', 682 | options: [ 683 | { 684 | type: 'dropdown', 685 | label: 'Graphic', 686 | id: 'graphicId', 687 | choices: [ 688 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => 689 | [ 690 | 'utility_speaker_timer', 691 | 'time_countdown', 692 | 'time_countup', 693 | 'big_time_countdown', 694 | 'big_time_countup', 695 | ].includes(c.type) 696 | ).map((c) => { 697 | const { id, label } = graphicToReadableLabel(c) 698 | 699 | return { 700 | id, 701 | label, 702 | } 703 | }), 704 | ], 705 | }, 706 | ], 707 | callback: async (action) => { 708 | let cmd = `graphic/${action.options.graphicId}/timer/run` 709 | await sendHttpMessage(cmd) 710 | }, 711 | }, 712 | speakerTimerReset: { 713 | name: 'Reset - Timer', 714 | options: [ 715 | { 716 | type: 'dropdown', 717 | label: 'Graphic', 718 | id: 'graphicId', 719 | choices: [ 720 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => 721 | [ 722 | 'utility_speaker_timer', 723 | 'time_countdown', 724 | 'time_countup', 725 | 'big_time_countdown', 726 | 'big_time_countup', 727 | ].includes(c.type) 728 | ).map((c) => { 729 | const { id, label } = graphicToReadableLabel(c) 730 | 731 | return { 732 | id, 733 | label, 734 | } 735 | }), 736 | ], 737 | }, 738 | ], 739 | callback: async (action) => { 740 | let cmd = `graphic/${action.options.graphicId}/timer/reset` 741 | await sendHttpMessage(cmd) 742 | }, 743 | }, 744 | speakerTimerPause: { 745 | name: 'Pause - Timer', 746 | options: [ 747 | { 748 | type: 'dropdown', 749 | label: 'Graphic', 750 | id: 'graphicId', 751 | choices: [ 752 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => 753 | [ 754 | 'utility_speaker_timer', 755 | 'time_countdown', 756 | 'time_countup', 757 | 'big_time_countdown', 758 | 'big_time_countup', 759 | ].includes(c.type) 760 | ).map((c) => { 761 | const { id, label } = graphicToReadableLabel(c) 762 | 763 | return { 764 | id, 765 | label, 766 | } 767 | }), 768 | ], 769 | }, 770 | ], 771 | callback: async (action) => { 772 | let cmd = `graphic/${action.options.graphicId}/timer/pause` 773 | await sendHttpMessage(cmd) 774 | }, 775 | }, 776 | speakerTimerJump: { 777 | name: 'Add/Remove time - Timer', 778 | options: [ 779 | { 780 | type: 'dropdown', 781 | label: 'Graphic', 782 | id: 'graphicId', 783 | choices: [ 784 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => 785 | [ 786 | 'utility_speaker_timer', 787 | 'time_countdown', 788 | 'time_countup', 789 | 'big_time_countdown', 790 | 'big_time_countup', 791 | ].includes(c.type) 792 | ).map((c) => { 793 | const { id, label } = graphicToReadableLabel(c) 794 | 795 | return { 796 | id, 797 | label, 798 | } 799 | }), 800 | ], 801 | }, 802 | { 803 | type: 'number', 804 | label: 'Amount in seconds (+/-)', 805 | id: 'amount', 806 | default: 10, 807 | step: 1, 808 | required: true, 809 | range: false, 810 | }, 811 | ], 812 | callback: async (action) => { 813 | let t = await self.parseVariablesInString(action.options.amount || 0) 814 | 815 | let cmd = `graphic/${action.options.graphicId}/timer/jump/${t}` 816 | 817 | await sendHttpMessage(cmd) 818 | }, 819 | }, 820 | speakerTimerDuration: { 821 | name: 'Set duration - Timer', 822 | options: [ 823 | { 824 | type: 'dropdown', 825 | label: 'Graphic', 826 | id: 'graphicId', 827 | choices: [ 828 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => 829 | ['utility_speaker_timer', 'time_countdown', 'time_countup'].includes(c.type) 830 | ).map((c) => { 831 | const { id, label } = graphicToReadableLabel(c) 832 | 833 | return { 834 | id, 835 | label, 836 | } 837 | }), 838 | ], 839 | }, 840 | { 841 | type: 'textinput', 842 | label: 'Time (HH:MM:SS)', 843 | id: 'time', 844 | default: '00:01:00', 845 | }, 846 | ], 847 | callback: async (action) => { 848 | let t = await self.parseVariablesInString(action.options.time || 0) 849 | 850 | let cmd = `graphic/${action.options.graphicId}/timer/duration/${stringToMS(t) / 1000}` 851 | 852 | await sendHttpMessage(cmd) 853 | }, 854 | }, 855 | speakerTimerSetMessage: { 856 | name: 'Speaker Timer - Set Message to speaker', 857 | options: [ 858 | { 859 | type: 'dropdown', 860 | label: 'Graphic', 861 | id: 'graphicId', 862 | choices: [ 863 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'utility_speaker_timer').map((c) => { 864 | const { id, label } = graphicToReadableLabel(c) 865 | 866 | return { 867 | id, 868 | label, 869 | } 870 | }), 871 | ], 872 | }, 873 | { 874 | type: 'textinput', 875 | label: 'Message', 876 | id: 'body', 877 | useVariables: true, 878 | }, 879 | ], 880 | callback: async (action) => { 881 | let b = await self.parseVariablesInString(action.options.body || '') 882 | 883 | let cmd = `graphic/${action.options.graphicId}/update` 884 | let body = { 885 | speakerMessage: b, 886 | } 887 | await sendHttpMessage(cmd, body) 888 | }, 889 | }, 890 | speakerTimerToggleMessage: { 891 | name: 'Speaker Timer - Show/Hide message to speaker', 892 | options: [ 893 | { 894 | type: 'dropdown', 895 | label: 'Graphic', 896 | id: 'graphicId', 897 | choices: [ 898 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'utility_speaker_timer').map((c) => { 899 | const { id, label } = graphicToReadableLabel(c) 900 | 901 | return { 902 | id, 903 | label, 904 | } 905 | }), 906 | ], 907 | }, 908 | { 909 | type: 'dropdown', 910 | label: 'Show/Hide', 911 | id: 'status', 912 | default: 'true', 913 | choices: [ 914 | { id: true, label: 'Show' }, 915 | { id: false, label: 'Hide' }, 916 | ], 917 | }, 918 | ], 919 | callback: async (action) => { 920 | let choice = action.options.status 921 | 922 | let cmd = `graphic/${action.options.graphicId}/update` 923 | let body = { 924 | showSpeakerMessage: String(choice) === 'true' ? true : false, 925 | } 926 | await sendHttpMessage(cmd, body) 927 | }, 928 | }, 929 | updateContentScoreTotal: { 930 | name: 'Update content - Score - Total', 931 | options: [ 932 | { 933 | type: 'dropdown', 934 | label: 'Graphic', 935 | id: 'graphicId', 936 | choices: [ 937 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'score').map((c) => { 938 | const { id, label } = graphicToReadableLabel(c) 939 | 940 | return { 941 | id, 942 | label, 943 | } 944 | }), 945 | ], 946 | }, 947 | { 948 | type: 'dropdown', 949 | label: 'Team number', 950 | id: 'team', 951 | default: '1', 952 | choices: [ 953 | { id: '1', label: '1' }, 954 | { id: '2', label: '2' }, 955 | ], 956 | }, 957 | { 958 | type: 'dropdown', 959 | label: 'Level number', 960 | id: 'level', 961 | default: '1', 962 | choices: [ 963 | { id: '1', label: '1' }, 964 | { id: '2', label: '2' }, 965 | { id: '3', label: '3' }, 966 | { id: '4', label: '4' }, 967 | { id: '5', label: '5' }, 968 | { id: '6', label: '6' }, 969 | ], 970 | }, 971 | { 972 | type: 'dropdown', 973 | label: 'Type', 974 | id: 'type', 975 | default: 'set', 976 | choices: [ 977 | { id: 'set', label: 'Set score' }, 978 | { id: 'up', label: 'Increment up' }, 979 | { id: 'down', label: 'Decrement down' }, 980 | ], 981 | }, 982 | { 983 | type: 'number', 984 | label: 'Amount', 985 | id: 'amount', 986 | min: -1000, 987 | max: 1000, 988 | default: 1, 989 | step: 1, 990 | required: true, 991 | range: false, 992 | }, 993 | ], 994 | callback: async (action) => { 995 | let cmd = `graphic/${action.options.graphicId}/updateScore/${action.options.team}/${action.options.level}/${action.options.type}/${action.options.amount}` 996 | 997 | sendHttpMessage(cmd) 998 | }, 999 | }, 1000 | clearMapPins: { 1001 | name: 'Clear pins on the Map graphic', 1002 | options: [ 1003 | { 1004 | type: 'dropdown', 1005 | label: 'Graphic', 1006 | id: 'graphicId', 1007 | choices: [ 1008 | ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'map').map((c) => { 1009 | const { id, label } = graphicToReadableLabel(c) 1010 | 1011 | return { 1012 | id, 1013 | label, 1014 | } 1015 | }), 1016 | ], 1017 | }, 1018 | ], 1019 | callback: async (action) => { 1020 | let cmd = `graphic/${action.options.graphicId}/update` 1021 | let body = { 1022 | removePinCount: new Date().getTime(), 1023 | } 1024 | 1025 | await sendHttpMessage(cmd, body) 1026 | }, 1027 | }, 1028 | updateGraphicPosition: { 1029 | name: 'Update graphic position', 1030 | options: [ 1031 | { 1032 | type: 'dropdown', 1033 | label: 'Graphic', 1034 | id: 'graphicId', 1035 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1036 | choices: [ 1037 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1038 | const { id, label } = graphicToReadableLabel(c) 1039 | 1040 | return { 1041 | id, 1042 | label, 1043 | } 1044 | }), 1045 | ], 1046 | }, 1047 | { 1048 | type: 'dropdown', 1049 | label: 'Position', 1050 | id: 'position', 1051 | default: 'mc', 1052 | choices: [...GRAPHIC_POSITION_OPTIONS], 1053 | }, 1054 | ], 1055 | callback: async (action) => { 1056 | let cmd = `graphic/${action.options.graphicId}/update` 1057 | let body = { 1058 | position: action.options.position, 1059 | } 1060 | sendHttpMessage(cmd, body) 1061 | }, 1062 | }, 1063 | updateGraphicX: { 1064 | name: 'Update graphic offset X', 1065 | options: [ 1066 | { 1067 | type: 'dropdown', 1068 | label: 'Graphic', 1069 | id: 'graphicId', 1070 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1071 | choices: [ 1072 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1073 | const { id, label } = graphicToReadableLabel(c) 1074 | 1075 | return { 1076 | id, 1077 | label, 1078 | } 1079 | }), 1080 | ], 1081 | }, 1082 | { 1083 | type: 'number', 1084 | label: 'X (-100 to 100)', 1085 | id: 'x', 1086 | min: -100, 1087 | max: 100, 1088 | default: 0, 1089 | step: 0.5, 1090 | required: true, 1091 | range: false, 1092 | }, 1093 | ], 1094 | callback: async (action) => { 1095 | let cmd = `graphic/${action.options.graphicId}/update` 1096 | let body = { 1097 | offsetX: action.options.x, 1098 | } 1099 | sendHttpMessage(cmd, body) 1100 | }, 1101 | }, 1102 | updateGraphicY: { 1103 | name: 'Update graphic offset Y', 1104 | options: [ 1105 | { 1106 | type: 'dropdown', 1107 | label: 'Graphic', 1108 | id: 'graphicId', 1109 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1110 | choices: [ 1111 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1112 | const { id, label } = graphicToReadableLabel(c) 1113 | 1114 | return { 1115 | id, 1116 | label, 1117 | } 1118 | }), 1119 | ], 1120 | }, 1121 | { 1122 | type: 'number', 1123 | label: 'Y (-100 to 100)', 1124 | id: 'y', 1125 | min: -100, 1126 | max: 100, 1127 | default: 0, 1128 | step: 0.5, 1129 | required: true, 1130 | range: false, 1131 | }, 1132 | ], 1133 | callback: async (action) => { 1134 | let cmd = `graphic/${action.options.graphicId}/update` 1135 | let body = { 1136 | offsetY: action.options.y, 1137 | } 1138 | sendHttpMessage(cmd, body) 1139 | }, 1140 | }, 1141 | updateGraphicXY: { 1142 | name: 'Update graphic offset X & Y', 1143 | options: [ 1144 | { 1145 | type: 'dropdown', 1146 | label: 'Graphic', 1147 | id: 'graphicId', 1148 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1149 | choices: [ 1150 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1151 | const { id, label } = graphicToReadableLabel(c) 1152 | 1153 | return { 1154 | id, 1155 | label, 1156 | } 1157 | }), 1158 | ], 1159 | }, 1160 | { 1161 | type: 'number', 1162 | label: 'X (-100 to 100)', 1163 | id: 'x', 1164 | min: -100, 1165 | max: 100, 1166 | default: 0, 1167 | step: 0.5, 1168 | required: true, 1169 | range: false, 1170 | }, 1171 | { 1172 | type: 'number', 1173 | label: 'Y (-100 to 100)', 1174 | id: 'y', 1175 | min: -100, 1176 | max: 100, 1177 | default: 0, 1178 | step: 0.5, 1179 | required: true, 1180 | range: false, 1181 | }, 1182 | ], 1183 | callback: async (action) => { 1184 | let cmd = `graphic/${action.options.graphicId}/update` 1185 | let body = { 1186 | offsetX: action.options.x, 1187 | offsetY: action.options.y, 1188 | } 1189 | 1190 | sendHttpMessage(cmd, body) 1191 | }, 1192 | }, 1193 | updateGraphicScale: { 1194 | name: 'Update graphic scale', 1195 | options: [ 1196 | { 1197 | type: 'dropdown', 1198 | label: 'Graphic', 1199 | id: 'graphicId', 1200 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1201 | choices: [ 1202 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1203 | const { id, label } = graphicToReadableLabel(c) 1204 | 1205 | return { 1206 | id, 1207 | label, 1208 | } 1209 | }), 1210 | ], 1211 | }, 1212 | { 1213 | type: 'number', 1214 | label: 'Scale (1 to 500)', 1215 | id: 'scale', 1216 | min: 1, 1217 | max: 500, 1218 | default: 100, 1219 | step: 0.5, 1220 | required: true, 1221 | range: false, 1222 | }, 1223 | ], 1224 | callback: async (action) => { 1225 | let cmd = `graphic/${action.options.graphicId}/update` 1226 | let body = { 1227 | scale: action.options.scale, 1228 | } 1229 | 1230 | sendHttpMessage(cmd, body) 1231 | }, 1232 | }, 1233 | updateGraphicTheme: { 1234 | name: 'Update graphic theme', 1235 | options: [ 1236 | { 1237 | type: 'dropdown', 1238 | label: 'Graphic', 1239 | id: 'graphicId', 1240 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1241 | choices: [ 1242 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1243 | const { id, label } = graphicToReadableLabel(c) 1244 | 1245 | return { 1246 | id, 1247 | label, 1248 | } 1249 | }), 1250 | ], 1251 | }, 1252 | { 1253 | type: 'dropdown', 1254 | label: 'Theme', 1255 | id: 'theme', 1256 | choices: [ 1257 | ...Object.entries(SELECTED_PROJECT_THEMES).map(([id, theme]) => { 1258 | return { 1259 | id, 1260 | label: theme.name, 1261 | } 1262 | }), 1263 | ], 1264 | }, 1265 | ], 1266 | callback: async (action) => { 1267 | let cmd = `graphic/${action.options.graphicId}/update` 1268 | let body = { 1269 | theme: action.options.theme, 1270 | } 1271 | sendHttpMessage(cmd, body) 1272 | }, 1273 | }, 1274 | setTextVariable: { 1275 | name: 'Set text variable', 1276 | options: [ 1277 | { 1278 | type: 'dropdown', 1279 | label: 'Text variable', 1280 | id: 'variable', 1281 | default: 'text.1', 1282 | choices: [ 1283 | { 1284 | id: 'text.1', 1285 | label: '[text.1]', 1286 | }, 1287 | { 1288 | id: 'text.2', 1289 | label: '[text.2]', 1290 | }, 1291 | { 1292 | id: 'text.3', 1293 | label: '[text.3]', 1294 | }, 1295 | { 1296 | id: 'text.4', 1297 | label: '[text.4]', 1298 | }, 1299 | { 1300 | id: 'text.5', 1301 | label: '[text.5]', 1302 | }, 1303 | { 1304 | id: 'text.6', 1305 | label: '[text.6]', 1306 | }, 1307 | ], 1308 | }, 1309 | { 1310 | type: 'textinput', 1311 | label: 'Text', 1312 | id: 'text', 1313 | useVariables: true, 1314 | }, 1315 | ], 1316 | callback: async (action) => { 1317 | let cmd = `updateVariableText/${action.options.variable}` 1318 | let body = { 1319 | text: await self.parseVariablesInString(action.options.text || ''), 1320 | } 1321 | // const graphicId = await self.parseVariablesInString(action.options.graphicId || '') 1322 | // sendHttpMessage(`graphic/${graphicId}/update`, { 1323 | // status: action.options.status, 1324 | // }) 1325 | 1326 | sendHttpMessage(cmd, body) 1327 | }, 1328 | }, 1329 | addVariableListItem: { 1330 | name: 'Variable List - Add item', 1331 | options: [ 1332 | { 1333 | type: 'textinput', 1334 | label: 'List', 1335 | id: 'listId', 1336 | default: 1, 1337 | useVariables: true, 1338 | }, 1339 | { 1340 | type: 'textinput', 1341 | label: 'Column 1', 1342 | id: 'colOne', 1343 | useVariables: true, 1344 | }, 1345 | { 1346 | type: 'textinput', 1347 | label: 'Column 2', 1348 | id: 'colTwo', 1349 | useVariables: true, 1350 | }, 1351 | { 1352 | type: 'textinput', 1353 | label: 'Column 3', 1354 | id: 'colThree', 1355 | useVariables: true, 1356 | }, 1357 | ], 1358 | callback: async (action) => { 1359 | let var1 = await self.parseVariablesInString(action.options.colOne || '') 1360 | let var2 = await self.parseVariablesInString(action.options.colTwo || '') 1361 | let var3 = await self.parseVariablesInString(action.options.colThree || '') 1362 | 1363 | const listId = await self.parseVariablesInString(action.options.listId || 1) 1364 | 1365 | let cmd = `updateVariableList/${parseInt(listId)}/addRow` 1366 | let body = { 1367 | row: [{ value: var1 }, { value: var2 }, { value: var3 }], 1368 | } 1369 | 1370 | sendHttpMessage(cmd, body) 1371 | }, 1372 | }, 1373 | addVariableSelectRow: { 1374 | name: 'Variable List - Select row', 1375 | options: [ 1376 | { 1377 | type: 'textinput', 1378 | label: 'List', 1379 | id: 'listId', 1380 | default: 1, 1381 | useVariables: true, 1382 | }, 1383 | { 1384 | type: 'dropdown', 1385 | label: 'Next/Previous/Number', 1386 | id: 'nextPreviousNumber', 1387 | default: 'next', 1388 | choices: [ 1389 | { 1390 | id: 'next', 1391 | label: 'Next', 1392 | }, 1393 | { 1394 | id: 'previous', 1395 | label: 'Previous', 1396 | }, 1397 | { 1398 | id: 'number', 1399 | label: 'Number', 1400 | }, 1401 | ], 1402 | }, 1403 | { 1404 | type: 'textinput', 1405 | label: 'Row number', 1406 | id: 'number', 1407 | required: true, 1408 | range: false, 1409 | useVariables: true, 1410 | isVisible: (values) => values.nextPreviousNumber === 'number', 1411 | }, 1412 | ], 1413 | callback: async (action) => { 1414 | let cmd 1415 | const listId = await self.parseVariablesInString(action.options.listId || 1) 1416 | const number = await self.parseVariablesInString(action.options.number || 1) 1417 | if (action.options.nextPreviousNumber === 'next' || action.options.nextPreviousNumber === 'previous') { 1418 | cmd = `updateVariableList/${parseInt(listId)}/selectRow/${action.options.nextPreviousNumber}` 1419 | } else { 1420 | cmd = `updateVariableList/${parseInt(listId)}/selectRow/${parseInt(number)}` 1421 | } 1422 | 1423 | sendHttpMessage(cmd) 1424 | }, 1425 | }, 1426 | setTransitionOverride: { 1427 | name: 'Set Transition Override', 1428 | options: [ 1429 | { 1430 | type: 'dropdown', 1431 | label: 'Graphic', 1432 | id: 'graphicId', 1433 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1434 | choices: [ 1435 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 1436 | const { id, label } = graphicToReadableLabel(c) 1437 | 1438 | return { 1439 | id, 1440 | label, 1441 | } 1442 | }), 1443 | ], 1444 | }, 1445 | { 1446 | type: 'dropdown', 1447 | label: 'Next/Previous/Number', 1448 | id: 'override', 1449 | default: 'use-theme', 1450 | choices: [ 1451 | { 1452 | label: 'Use theme transition (default)', 1453 | id: 'use-theme', 1454 | }, 1455 | { 1456 | label: 'None', 1457 | id: 'none', 1458 | }, 1459 | { 1460 | label: 'Fade', 1461 | id: 'fade', 1462 | }, 1463 | { 1464 | label: 'Slide', 1465 | id: 'slide', 1466 | }, 1467 | { 1468 | label: 'Slide & Fade', 1469 | id: 'slide_fade', 1470 | }, 1471 | { 1472 | label: 'Scale', 1473 | id: 'scale', 1474 | }, 1475 | { 1476 | label: 'Scale & Fade', 1477 | id: 'scale_fade', 1478 | }, 1479 | { 1480 | label: 'Blur & Fade', 1481 | id: 'blur_fade', 1482 | }, 1483 | ], 1484 | }, 1485 | ], 1486 | callback: async (action) => { 1487 | let cmd = `graphic/${action.options.graphicId}/update` 1488 | let body = { 1489 | transition: action.options.override, 1490 | } 1491 | 1492 | await sendHttpMessage(cmd, body) 1493 | }, 1494 | }, 1495 | // updateCustomHtmlTemplate: { 1496 | // name: 'Update content - Custom HTML', 1497 | // options: [ 1498 | // { 1499 | // type: 'dropdown', 1500 | // label: 'Graphic', 1501 | // id: 'graphicId', 1502 | // default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 1503 | // choices: [ 1504 | // ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'custom_html').map((c) => { 1505 | // const { id, label } = graphicToReadableLabel(c) 1506 | 1507 | // return { 1508 | // id, 1509 | // label, 1510 | // } 1511 | // }), 1512 | // ], 1513 | // }, 1514 | // ...SELECTED_PROJECT_GRAPHICS.filter((c) => c.type === 'custom_html' && c.template.properties) 1515 | // .map((c) => { 1516 | // const str = JSON.stringify({ id: c.id }) 1517 | // return Object.entries(c.template?.properties).map(([key, _d]) => { 1518 | // return { 1519 | // type: 'textinput', 1520 | // label: _d.label, 1521 | // id: key, 1522 | // tooltip: _d.description, 1523 | // default: c.data?.[key], 1524 | // useVariables: true, 1525 | // isVisibleData: str, 1526 | // isVisible: (values, data) => values['graphicId'] == data.id, 1527 | // // isVisible: function (options) { 1528 | // // console.log('IS VISIBLE') 1529 | // // self.log('debug', 'IS VISIBLE') 1530 | // // return options.effect.includes('brightness') 1531 | // // }, 1532 | // } 1533 | // }) 1534 | // }) 1535 | // .flat(), 1536 | // ], 1537 | // callback: async (action) => { 1538 | // let cmd = `graphic/${action.options.graphicId}/update` 1539 | // let body = { 1540 | // transition: action.options.override, 1541 | // } 1542 | 1543 | // await sendHttpMessage(cmd, body) 1544 | // }, 1545 | // }, 1546 | sendCustonHTTP: { 1547 | name: 'Send custom HTTP', 1548 | options: [ 1549 | { 1550 | type: 'textinput', 1551 | label: 'URI', 1552 | id: 'uri', 1553 | }, 1554 | ], 1555 | callback: async (action) => { 1556 | let cmd = `${action.options.uri}` 1557 | sendHttpMessage(cmd) 1558 | }, 1559 | }, 1560 | } 1561 | } 1562 | -------------------------------------------------------------------------------- /src/feedback.js: -------------------------------------------------------------------------------- 1 | import { combineRgb } from '@companion-module/base' 2 | import { graphicToReadableLabel } from './utils.js' 3 | 4 | const GRAPHIC_STATUS_OPTIONS = [ 5 | { id: 'ready', label: 'Ready' }, 6 | { id: 'cued', label: 'Cue on' }, 7 | { id: 'coming', label: 'Coming on air' }, 8 | { id: 'onair', label: 'On air' }, 9 | { id: 'going', label: 'Going off air' }, 10 | { id: 'cuedoff', label: 'Cue off' }, 11 | { id: 'offair', label: 'Off air' }, 12 | ] 13 | 14 | export const initFeedbacks = (self) => { 15 | let SELECTED_PROJECT_GRAPHICS = self.SELECTED_PROJECT_GRAPHICS || [] 16 | const feedbacks = {} 17 | 18 | feedbacks['graphic_status'] = { 19 | type: 'boolean', // Feedbacks can either a simple boolean, or can be an 'advanced' style change (until recently, all feedbacks were 'advanced') 20 | name: 'Graphic status', 21 | defaultStyle: { 22 | bgcolor: combineRgb(255, 0, 0), 23 | color: combineRgb(255, 255, 255), 24 | }, 25 | // options is how the user can choose the condition the feedback activates for 26 | options: [ 27 | { 28 | type: 'dropdown', 29 | label: 'Status', 30 | id: 'status', 31 | default: 'onair', 32 | choices: GRAPHIC_STATUS_OPTIONS, 33 | }, 34 | { 35 | type: 'dropdown', 36 | label: 'Graphic', 37 | id: 'graphicId', 38 | default: SELECTED_PROJECT_GRAPHICS.length > 0 ? SELECTED_PROJECT_GRAPHICS[0].id : '', 39 | choices: [ 40 | ...SELECTED_PROJECT_GRAPHICS.map((c) => { 41 | const { id, label } = graphicToReadableLabel(c) 42 | return { 43 | id, 44 | label, 45 | } 46 | }), 47 | ], 48 | }, 49 | ], 50 | callback: function (feedback) { 51 | let status = self.SELECTED_PROJECT_GRAPHICS.find((g) => g.id === feedback?.options?.graphicId)?.status 52 | // This callback will be called whenever companion wants to check if this feedback is 'active' and should affect the button style 53 | if (status === feedback.options.status) { 54 | return true 55 | } else { 56 | return false 57 | } 58 | }, 59 | } 60 | return feedbacks 61 | } 62 | -------------------------------------------------------------------------------- /src/presets.js: -------------------------------------------------------------------------------- 1 | import { combineRgb } from '@companion-module/base' 2 | import { graphicToReadableLabel, graphicColours, graphicIcons, replaceWithDataSource } from './utils.js' 3 | 4 | export const initPresets = (self) => { 5 | const presets = {} 6 | let SELECTED_PROJECT_GRAPHICS = self.SELECTED_PROJECT_GRAPHICS || [] 7 | let SELECTED_PROJECT_VARIABLES = self.SELECTED_PROJECT_VARIABLES || {} 8 | let SELECTED_PROJECT_DYNAMIC_LISTS = self.SELECTED_PROJECT_DYNAMIC_LISTS || [] 9 | 10 | presets['Run'] = { 11 | type: 'button', 12 | category: 'Basic actions', 13 | name: 'Run', 14 | style: { 15 | text: 'Run', 16 | size: '18', 17 | color: combineRgb(255, 255, 255), 18 | bgcolor: combineRgb(0, 0, 0), 19 | }, 20 | steps: [ 21 | { 22 | down: [ 23 | { 24 | actionId: 'run', 25 | }, 26 | ], 27 | up: [], 28 | }, 29 | ], 30 | feedbacks: [], 31 | } 32 | 33 | presets['Hide'] = { 34 | type: 'button', 35 | category: 'Basic actions', 36 | name: 'Hide all graphics', 37 | style: { 38 | text: 'Hide all', 39 | size: '18', 40 | color: combineRgb(255, 255, 255), 41 | bgcolor: combineRgb(0, 0, 0), 42 | }, 43 | steps: [ 44 | { 45 | down: [ 46 | { 47 | actionId: 'clear', 48 | }, 49 | ], 50 | up: [], 51 | }, 52 | ], 53 | feedbacks: [], 54 | } 55 | 56 | const createPresetShowHide = (category, item) => { 57 | let bgColour = graphicColours(item.type).bgColour 58 | let pngIcon = self.config.usePngForPresets === 'true' ? graphicIcons(item.type).png : null 59 | let labelSource 60 | if (self.config.useLabelForPresets === 'true') { 61 | labelSource = 'label' 62 | } else { 63 | labelSource = ['lower_third', 'lower_third_animated'].includes(item.type) 64 | ? self.config.lowerThirdPresetLabelSource || 'contents' 65 | : 'contents' 66 | } 67 | 68 | return { 69 | category, 70 | type: 'button', 71 | name: replaceWithDataSource( 72 | graphicToReadableLabel(item).label, 73 | SELECTED_PROJECT_VARIABLES, 74 | SELECTED_PROJECT_DYNAMIC_LISTS 75 | ), 76 | style: { 77 | text: `$(${self.config.label}:graphic_${item.id}_${labelSource})`, 78 | png64: pngIcon, 79 | pngalignment: 'center:center', 80 | size: self.config.presetButtonTextSize || '18', 81 | color: combineRgb(255, 255, 255), 82 | bgcolor: combineRgb(bgColour[0], bgColour[1], bgColour[2]), 83 | latch: false, 84 | }, 85 | steps: [ 86 | { 87 | down: [ 88 | { 89 | actionId: 'showHide', 90 | options: { graphicId: item.id, status: 'toggle' }, 91 | }, 92 | ], 93 | up: [], 94 | }, 95 | ], 96 | feedbacks: [ 97 | { 98 | feedbackId: 'graphic_status', 99 | options: { 100 | graphicId: item.id, 101 | status: 'coming', 102 | }, 103 | style: { 104 | bgcolor: combineRgb(132, 0, 0), 105 | }, 106 | }, 107 | { 108 | feedbackId: 'graphic_status', 109 | options: { 110 | graphicId: item.id, 111 | status: 'onair', 112 | }, 113 | style: { 114 | bgcolor: combineRgb(255, 0, 0), 115 | }, 116 | }, 117 | { 118 | feedbackId: 'graphic_status', 119 | options: { 120 | graphicId: item.id, 121 | status: 'going', 122 | }, 123 | style: { 124 | bgcolor: combineRgb(132, 0, 0), 125 | }, 126 | }, 127 | ], 128 | } 129 | } 130 | 131 | SELECTED_PROJECT_GRAPHICS.forEach((graphic) => { 132 | if (graphic.type === 'section') return null 133 | const preset = createPresetShowHide('Show/Hide', graphic) 134 | 135 | presets[graphic.id] = preset 136 | }) 137 | 138 | // DRAW ON SCREEN 139 | 140 | presets['drawing_on'] = { 141 | type: 'button', 142 | category: 'Draw on screen', 143 | name: 'Drawing On', 144 | style: { 145 | text: 'Drawing On', 146 | size: '18', 147 | color: combineRgb(255, 255, 255), 148 | bgcolor: combineRgb(0, 0, 0), 149 | }, 150 | steps: [ 151 | { 152 | down: [ 153 | { 154 | actionId: 'draw_on', 155 | }, 156 | ], 157 | up: [], 158 | }, 159 | ], 160 | feedbacks: [], 161 | } 162 | presets['drawing_off'] = { 163 | type: 'button', 164 | category: 'Draw on screen', 165 | name: 'Drawing Off', 166 | style: { 167 | text: 'Drawing Off', 168 | size: '18', 169 | color: combineRgb(255, 255, 255), 170 | bgcolor: combineRgb(0, 0, 0), 171 | }, 172 | steps: [ 173 | { 174 | down: [ 175 | { 176 | actionId: 'draw_off', 177 | }, 178 | ], 179 | up: [], 180 | }, 181 | ], 182 | feedbacks: [], 183 | } 184 | presets['drawing_size'] = { 185 | type: 'button', 186 | category: 'Draw on screen', 187 | name: 'Drawing size', 188 | style: { 189 | text: 'Drawing size', 190 | size: '18', 191 | color: combineRgb(255, 255, 255), 192 | bgcolor: combineRgb(0, 0, 0), 193 | }, 194 | steps: [ 195 | { 196 | down: [ 197 | { 198 | actionId: 'draw_size', 199 | }, 200 | ], 201 | up: [], 202 | }, 203 | ], 204 | feedbacks: [], 205 | } 206 | presets['drawing_color'] = { 207 | type: 'button', 208 | category: 'Draw on screen', 209 | name: 'Drawing color', 210 | style: { 211 | text: 'Drawing color', 212 | size: '18', 213 | color: combineRgb(255, 255, 255), 214 | bgcolor: combineRgb(0, 0, 0), 215 | }, 216 | steps: [ 217 | { 218 | down: [ 219 | { 220 | actionId: 'draw_color', 221 | }, 222 | ], 223 | up: [], 224 | }, 225 | ], 226 | feedbacks: [], 227 | } 228 | 229 | return presets 230 | } 231 | -------------------------------------------------------------------------------- /src/tcp.js: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client' 2 | 3 | import { graphicToReadableLabel, replaceWithDataSource } from './utils.js' 4 | import { startStopTimer } from './timer.js' 5 | 6 | let socket = null 7 | 8 | export const init_http = (self) => { 9 | if (!self.config.host) { 10 | return 11 | } 12 | const uri = `http://${self.config.host}:${self.config.portV2}` 13 | socket = io.connect(uri, { 14 | transports: ['websocket'], 15 | forceNew: true, 16 | }) 17 | 18 | socket.on('connect', () => { 19 | self.updateStatus('ok') 20 | }) 21 | 22 | socket.on('error', (err) => { 23 | self.updateStatus('Error') 24 | 25 | console.log('error', err) 26 | }) 27 | 28 | socket.on('disconnect', () => { 29 | self.updateStatus('Disconnected') 30 | }) 31 | 32 | socket.on('connected', () => { 33 | self.updateStatus('ok') 34 | }) 35 | 36 | socket.on('updateFrontend', (data) => { 37 | if (data.projects[self.config.projectId] === undefined) { 38 | self.updateStatus(`Project "${self.config.projectId}" not found.`) 39 | return self.log('info', `H2R Graphics project (${self.config.projectId}) not found!`) 40 | } 41 | 42 | if (data.projects) { 43 | self.updateStatus(`ok`) 44 | self.PROJECTS = data.projects 45 | self.SELECTED_PROJECT_GRAPHICS = data.projects[self.config.projectId].cues || [] 46 | self.SELECTED_PROJECT_MEDIA = data.projects[self.config.projectId].media || [] 47 | self.SELECTED_PROJECT_THEMES = data.projects[self.config.projectId].themes || {} 48 | self.SELECTED_PROJECT_VARIABLES = data.projects[self.config.projectId].dynamicText || {} 49 | self.SELECTED_PROJECT_DYNAMIC_LISTS = data.projects[self.config.projectId].dynamicLists || [] 50 | 51 | const dynamicText = data.projects[self.config.projectId].dynamicText || {} 52 | const variables = [] 53 | const variableValues = {} 54 | 55 | data.projects[self.config.projectId].cues.map((c) => { 56 | const { id, label, contents } = graphicToReadableLabel(c) 57 | variables.push({ 58 | variableId: `graphic_${id}_contents`, 59 | name: label, 60 | }) 61 | variables.push({ 62 | variableId: `graphic_${id}_label`, 63 | name: label, 64 | }) 65 | variableValues[`graphic_${id}_label`] = c.label || id 66 | 67 | if (['lower_third', 'lower_third_animated'].includes(c.type)) { 68 | variables.push({ 69 | variableId: `graphic_${id}_first_line`, 70 | name: label, 71 | }) 72 | variableValues[`graphic_${id}_first_line`] = replaceWithDataSource( 73 | c.line_one, 74 | self.SELECTED_PROJECT_VARIABLES, 75 | self.SELECTED_PROJECT_DYNAMIC_LISTS 76 | ) 77 | } 78 | 79 | if (['score'].includes(c.type)) { 80 | c.scores.forEach((score, sI) => { 81 | const scoreGrouped = [] 82 | score.forEach((level, lI) => { 83 | if (lI + 1 > c.levels) return 84 | const variableId = `graphic_${id}_team_${sI + 1}_level_${lI + 1}_score` 85 | variables.push({ 86 | variableId, 87 | name: `Score - Team ${sI + 1}, Level ${lI + 1}`, 88 | }) 89 | scoreGrouped.push(level.score) 90 | variableValues[variableId] = level.score 91 | }) 92 | const variableIdGrouped = `graphic_${id}_team_${sI + 1}_score` 93 | variables.push({ 94 | variableId: variableIdGrouped, 95 | name: `Score - Team ${sI + 1}`, 96 | }) 97 | variableValues[variableIdGrouped] = scoreGrouped.join(c.delimiter || '-') 98 | }) 99 | } 100 | 101 | if (['social'].includes(c.type)) { 102 | variables.push({ 103 | variableId: `graphic_${id}_author_display_name`, 104 | name: `Social - Author (${id})`, 105 | }) 106 | variableValues[`graphic_${id}_author_display_name`] = c.chat.authorDetails.displayName 107 | 108 | variables.push({ 109 | variableId: `graphic_${id}_author_profile_image_url`, 110 | name: `Social - Author Profile Image URL (${id})`, 111 | }) 112 | variableValues[`graphic_${id}_author_profile_image_url`] = c.chat.authorDetails.profileImageUrl 113 | 114 | variables.push({ 115 | variableId: `graphic_${id}_source`, 116 | name: `Social - Source (${id})`, 117 | }) 118 | variableValues[`graphic_${id}_source`] = c.chat.source 119 | 120 | variables.push({ 121 | variableId: `graphic_${id}_chat_type`, 122 | name: `Social - Chat Type (${id})`, 123 | }) 124 | 125 | variableValues[`graphic_${id}_chat_type`] = c.chat.snippet.type 126 | 127 | variables.push({ 128 | variableId: `graphic_${id}_chat_id`, 129 | name: `Social - Chat ID (${id})`, 130 | }) 131 | 132 | variableValues[`graphic_${id}_chat_id`] = c.chat.id 133 | 134 | variables.push({ 135 | variableId: `graphic_${id}_use_custom_image`, 136 | name: `Social - Use Custom Image (${id})`, 137 | }) 138 | 139 | variableValues[`graphic_${id}_use_custom_image`] = c.useCustomImage || false 140 | 141 | variables.push({ 142 | variableId: `graphic_${id}_custom_image`, 143 | name: `Social - Custom Image (${id})`, 144 | }) 145 | 146 | variableValues[`graphic_${id}_custom_image`] = c.customImage || '' 147 | 148 | variables.push({ 149 | variableId: `graphic_${id}_celebration`, 150 | name: `Social - Celebration (${id})`, 151 | }) 152 | 153 | variableValues[`graphic_${id}_celebration`] = c.sponsoredCelebration || '' 154 | } 155 | 156 | if ( 157 | [ 158 | 'time_countdown', 159 | 'time_countup', 160 | 'time_to_tod', 161 | 'big_time_countdown', 162 | 'big_time_countup', 163 | 'big_time_to_tod', 164 | 'utility_speaker_timer', 165 | ].includes(c.type) 166 | ) { 167 | variables.push( 168 | { 169 | variableId: `graphic_${id}_hh`, 170 | name: `Hours (${id})`, 171 | }, 172 | { 173 | variableId: `graphic_${id}_mm`, 174 | name: `Minutes (${id})`, 175 | }, 176 | { 177 | variableId: `graphic_${id}_ss`, 178 | name: `Seconds (${id})`, 179 | } 180 | ) 181 | return startStopTimer(self, c) 182 | } 183 | variableValues[`graphic_${id}_contents`] = replaceWithDataSource( 184 | contents, 185 | self.SELECTED_PROJECT_VARIABLES, 186 | self.SELECTED_PROJECT_DYNAMIC_LISTS 187 | ) 188 | }) 189 | Object.entries(dynamicText).map(([id, val]) => { 190 | variables.push({ 191 | variableId: id, 192 | name: id, 193 | }) 194 | variableValues[id] = val 195 | }) 196 | 197 | const dynamicLists = data.projects[self.config.projectId].dynamicLists || [] 198 | 199 | for (let [index, dynamicList] of dynamicLists.entries()) { 200 | let selectedValue = null 201 | 202 | for (const element of dynamicList) { 203 | const found = element.find((item) => item.value === 'Selected') 204 | if (found) { 205 | selectedValue = found.selected 206 | break 207 | } 208 | } 209 | 210 | variables.push({ 211 | variableId: `list${index + 1}_selected_row_number`, 212 | name: `Dynamic List ${index + 1} Selected Row Number`, 213 | }) 214 | variableValues[`list${index + 1}_selected_row_number`] = selectedValue 215 | } 216 | 217 | self.setVariableDefinitions(variables) 218 | self.setVariableValues(variableValues) 219 | } 220 | 221 | self.updateActions() 222 | self.updatePresets() 223 | self.updateFeedbacks() 224 | self.checkFeedbacks('graphic_status') 225 | }) 226 | } 227 | -------------------------------------------------------------------------------- /src/timer.js: -------------------------------------------------------------------------------- 1 | const intervalIdObj = {} 2 | 3 | const toTimeString = (timeLeft, amount = 'full') => { 4 | let hours = Math.floor((timeLeft / (1000 * 60 * 60)) % 24) || 0 5 | let minutes = Math.floor((timeLeft / (1000 * 60)) % 60) || 0 6 | const seconds = Math.floor((timeLeft / 1000) % 60) || 0 7 | 8 | if (timeLeft <= 0) { 9 | hours++ 10 | minutes++ 11 | } 12 | 13 | if (amount == 'hh') return hours.toString().padStart(2, '0') 14 | if (amount == 'mm') return minutes.toString().padStart(2, '0') 15 | if (amount == 'ss') return seconds.toString().padStart(2, '0') 16 | 17 | const hoursString = `${timeLeft < 0 ? '-' : ''}${Math.abs(hours).toString().padStart(2, '0')}` 18 | const minutesString = `${Math.abs(minutes).toString().padStart(2, '0')}` 19 | const secondsString = `${Math.abs(seconds).toString().padStart(2, '0')}` 20 | 21 | return `${hoursString}:${minutesString}:${secondsString}` 22 | } 23 | function calculateTimeLeft(timeCue) { 24 | const currentTime = new Date().getTime() 25 | let timeLeft 26 | 27 | if (['time_countup', 'big_time_countup'].includes(timeCue.type)) { 28 | timeLeft = currentTime - timeCue.startedAt 29 | } else if (['time_countdown', 'big_time_countdown', 'utility_speaker_timer'].includes(timeCue.type)) { 30 | timeLeft = timeCue.state === 'reset' ? Number.parseInt(timeCue.duration, 10) : timeCue.endAt - currentTime 31 | } else if (['time_to_tod', 'big_time_to_tod'].includes(timeCue.type)) { 32 | const t = new Date(timeCue?.endTime)?.getTime() || 0 33 | timeLeft = t - currentTime 34 | } 35 | 36 | if ( 37 | ['time_countdown', 'big_time_countdown', 'big_time_to_tod', 'time_tod', 'utility_speaker_timer'].includes( 38 | timeCue.type 39 | ) && 40 | timeCue.onEnd === 'hold' 41 | ) { 42 | return Math.max(0, timeLeft) 43 | } 44 | return timeLeft 45 | } 46 | 47 | export function startStopTimer(instance, timerObj) { 48 | instance.log('debug', `ATTEMPTING ${timerObj.id} ${JSON.stringify(timerObj)}`) 49 | 50 | const timerKey = timerObj.id 51 | 52 | if (['paused', 'reset'].includes(timerObj.state)) return updateTimerDisplay(instance, timerObj, timerKey) 53 | 54 | clearInterval(intervalIdObj[timerKey]) 55 | intervalIdObj[timerKey] = setInterval(() => { 56 | return updateTimerDisplay(instance, timerObj, timerKey) 57 | }, 1000) 58 | 59 | return updateTimerDisplay(instance, timerObj, timerKey) 60 | } 61 | 62 | function updateTimerDisplay(instance, timeCue, timerKey) { 63 | const timeLeft = calculateTimeLeft(timeCue) 64 | 65 | if (['paused', 'reset'].includes(timeCue.state)) { 66 | clearInterval(intervalIdObj[timerKey]) 67 | delete intervalIdObj[timerKey] 68 | } 69 | 70 | instance.log('debug', `INTERVAL ${timeCue.id} ${JSON.stringify(timeCue)}`) 71 | return setTimerVariables(instance, timerKey, timeLeft) 72 | } 73 | 74 | function setTimerVariables(instance, timerKey, timeLeft) { 75 | return instance.setVariableValues({ 76 | [`graphic_${timerKey}_contents`]: `${toTimeString(timeLeft)}`, 77 | [`graphic_${timerKey}_hh`]: `${toTimeString(timeLeft, 'hh')}`, 78 | [`graphic_${timerKey}_mm`]: `${toTimeString(timeLeft, 'mm')}`, 79 | [`graphic_${timerKey}_ss`]: `${toTimeString(timeLeft, 'ss')}`, 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /src/upgrades.js: -------------------------------------------------------------------------------- 1 | export const upgrade = [ 2 | function (context, props) { 3 | // This is a placeholder than now cannot be used/removed 4 | return { 5 | updatedConfig: null, 6 | updatedActions: [], 7 | updatedFeedbacks: [], 8 | } 9 | }, 10 | ] 11 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | export const msToString = (ms = 0) => { 2 | let seconds = ms / 1000 3 | let hours = parseInt(seconds / 3600) 4 | seconds = seconds % 3600 5 | let minutes = parseInt(seconds / 60) 6 | seconds = Math.ceil(seconds % 60) 7 | return `${hours < 10 ? `0${hours}` : `${hours}`}:${minutes < 10 ? `0${minutes}` : `${minutes}`}:${ 8 | seconds < 10 ? `0${seconds}` : `${seconds === 60 ? '00' : seconds}` 9 | }` 10 | } 11 | 12 | export const stringToMS = (string = '00:00:00') => { 13 | let [h, m, s = '00'] = string.split(':') 14 | 15 | return (parseInt(h) * 60 * 60 + parseInt(m) * 60 + parseInt(s)) * 1000 16 | } 17 | 18 | export const graphicToReadableLabel = (graphic) => { 19 | let id = graphic.id 20 | let label 21 | let contents 22 | 23 | if (graphic.type === 'lower_third') { 24 | label = `${graphic.line_one}, ${graphic.line_two} (Lower third - ${graphic.id})` 25 | contents = `${graphic.line_one}, ${graphic.line_two}` 26 | } else if (graphic.type === 'message') { 27 | label = `${graphic.body} (Message) - ${graphic.id})` 28 | contents = `${graphic.body}` 29 | } else if (graphic.type === 'time') { 30 | if (graphic.timerType === 'to_time_of_day') { 31 | label = `${ 32 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 33 | ? msToString(graphic.timeLeft * 1000) 34 | : graphic.endTime 35 | } (Time - ${graphic.id})` 36 | contents = `${ 37 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 38 | ? msToString(graphic.timeLeft * 1000) 39 | : graphic.endTime 40 | }` 41 | } else if (graphic.timerType === 'time_of_day') { 42 | label = `Current time of day (Time - ${graphic.id})` 43 | contents = `Current time of day` 44 | } else if (graphic.timerType === 'countdown' || graphic.timerType === 'countup') { 45 | label = `${ 46 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 47 | ? msToString(graphic.timeLeft) 48 | : graphic.duration 49 | } (Time - ${graphic.id})` 50 | contents = `${ 51 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 52 | ? msToString(graphic.timeLeft) 53 | : graphic.duration 54 | }` 55 | } else { 56 | label = `${ 57 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 58 | ? msToString(graphic.timeLeft) 59 | : graphic.duration 60 | } (Time - ${graphic.id})` 61 | contents = `${ 62 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 63 | ? msToString(graphic.timeLeft) 64 | : graphic.duration 65 | }` 66 | } 67 | } else if (graphic.type === 'image') { 68 | label = `${graphic.name} (Image - ${graphic.id})` 69 | contents = `${graphic.name}` 70 | } else if (graphic.type === 'image_with_message') { 71 | label = `${graphic.body} (Image with Message - ${graphic.id})` 72 | contents = `${graphic.body}` 73 | } else if (graphic.type === 'ticker') { 74 | label = `${graphic.title} (Ticker - ${graphic.id})` 75 | contents = `${graphic.title}` 76 | } else if (graphic.type === 'social') { 77 | label = `Social - ${graphic.id}` 78 | contents = `${graphic.chat.snippet.displayMessage}` 79 | } else if (graphic.type === 'webpage') { 80 | label = `${graphic.url} (Webpage - ${graphic.id})` 81 | contents = `${graphic.url}` 82 | } else if (graphic.type === 'score') { 83 | label = `Score - ${graphic.id}` 84 | contents = `Score` 85 | } else if (graphic.type === 'lower_third_animated') { 86 | label = `${graphic.line_one}, ${graphic.line_two} (LT Animated - ${graphic.id})` 87 | contents = `${graphic.line_one}, ${graphic.line_two}` 88 | } else if (graphic.type === 'big_time') { 89 | label = `${ 90 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 91 | ? msToString(graphic.timeLeft) 92 | : graphic.duration 93 | } (Big timer - ${graphic.id})` 94 | contents = `${ 95 | graphic.status === 'onair' || graphic.status === 'coming' || graphic.status === 'going' 96 | ? msToString(graphic.timeLeft) 97 | : graphic.duration 98 | }` 99 | } else if (graphic.type === 'icon_with_message') { 100 | label = `${graphic.body} (Message - ${graphic.id})` 101 | contents = `${graphic.body}` 102 | } else if (graphic.type === 'credits') { 103 | label = `${graphic.lead} (Credits - ${graphic.id})` 104 | contents = `${graphic.lead}` 105 | } else if (graphic.type === 'animated_background') { 106 | label = `${graphic.animationName} (Animated Background - ${graphic.id})` 107 | contents = `${graphic.animationName}` 108 | } else if (graphic.type === 'video') { 109 | label = `${graphic.name} (Video - ${graphic.id})` 110 | contents = `${graphic.name}` 111 | } else if (graphic.type === 'audio') { 112 | label = `${graphic.name} (Audio - ${graphic.id})` 113 | contents = `${graphic.name}` 114 | } else if (graphic.type === 'celebration') { 115 | label = `${graphic.celebrationType} (Celebration - ${graphic.id})` 116 | contents = `${graphic.celebrationType}` 117 | } else if (graphic.type === 'now_next_then') { 118 | label = `${graphic.items[0].sectionTitle} (Now next then - ${graphic.id})` 119 | contents = `${graphic.items[0].sectionTitle}` 120 | } else if (graphic.type === 'qr') { 121 | label = `${graphic.message} (QR code - ${graphic.id})` 122 | contents = `${graphic.message}` 123 | } else if (graphic.type === 'map') { 124 | label = `Map - ${graphic.id}` 125 | contents = `Map` 126 | } else if (graphic.type === 'checklist') { 127 | label = `${graphic.title} (Checklist - ${graphic.id})` 128 | contents = `${graphic.title}` 129 | } else if (graphic.type === 'utility_large_text') { 130 | label = `${graphic.text} (Large Text - ${graphic.id})` 131 | contents = `${graphic.text}` 132 | } else if (graphic.type === 'utility_time_of_day') { 133 | label = `Time of day (Time of Day - ${graphic.id})` 134 | contents = `Time of day` 135 | } else if (graphic.type === 'utility_pattern') { 136 | label = `Pattern - ${graphic.id}` 137 | contents = `Pattern` 138 | } else if (graphic.type === 'utility_speaker_timer') { 139 | label = `${msToString(graphic.duration)} (Speaker timer - ${graphic.id})` 140 | contents = ['running'].includes(graphic.state) ? `${graphic.endAt}` : `${msToString(graphic.duration)}` 141 | } else if (graphic.type === 'time_tod') { 142 | label = `Time of day (Time of Day - ${graphic.id})` 143 | contents = `Time of day` 144 | } else if (graphic.type === 'time_to_tod') { 145 | label = `To time of day (To time of Day - ${graphic.id})` 146 | contents = `To time of day` 147 | } else if (graphic.type === 'time_countdown' || graphic.type === 'big_time_countdown') { 148 | label = `${msToString(graphic.duration)} (Countdown timer - ${graphic.id})` 149 | contents = ['running'].includes(graphic.state) ? `${graphic.endAt}` : `${msToString(graphic.duration)}` 150 | } else if (graphic.type === 'time_countup' || graphic.type === 'big_time_countup') { 151 | label = `${msToString(graphic.duration)} (Count Up timer - ${graphic.id})` 152 | contents = ['running'].includes(graphic.state) ? `${graphic.endAt}` : `${msToString(graphic.duration)}` 153 | } else if (graphic.type === 'image_sequence') { 154 | label = `${graphic.body} (Image Sequence - ${graphic.id})` 155 | contents = `${graphic.name || 'Image Sequence'}` 156 | } else if (graphic.type === 'custom_html') { 157 | label = `${graphic.html?.originalname || 'Custom HTML'} (Custom HTML - ${graphic.id})` 158 | contents = `${graphic.html?.originalname || 'Custom HTML'}` 159 | } else { 160 | label = `${graphic.type} (${graphic.id})` 161 | contents = `${graphic.type} (${graphic.id})` 162 | } 163 | 164 | return { 165 | id, 166 | label, 167 | contents, 168 | } 169 | } 170 | 171 | export const graphicColours = (graphic) => { 172 | let bgColour 173 | 174 | switch (graphic) { 175 | case 'lower_third': 176 | bgColour = [202, 138, 4] 177 | break 178 | 179 | case 'message': 180 | bgColour = [234, 179, 8] 181 | break 182 | 183 | case 'time': 184 | case 'time_countdown': 185 | case 'time_countup': 186 | case 'time_tod': 187 | case 'time_to_tod': 188 | bgColour = [248, 113, 113] 189 | break 190 | 191 | case 'image': 192 | case 'image_sequence': 193 | bgColour = [37, 99, 235] 194 | break 195 | 196 | case 'ticker': 197 | bgColour = [165, 180, 252] 198 | break 199 | 200 | case 'social': 201 | bgColour = [126, 34, 206] 202 | break 203 | 204 | case 'webpage': 205 | bgColour = [55, 48, 163] 206 | break 207 | 208 | case 'score': 209 | bgColour = [34, 197, 94] 210 | break 211 | 212 | case 'big_time': 213 | case 'big_time_countdown': 214 | case 'big_time_countup': 215 | case 'big_time_tod': 216 | case 'big_time_to_tod': 217 | bgColour = [248, 113, 113] 218 | break 219 | 220 | case 'lower_third_animated': 221 | bgColour = [250, 204, 21] 222 | break 223 | 224 | case 'icon_with_message': 225 | bgColour = [234, 179, 8] 226 | break 227 | 228 | case 'credits': 229 | bgColour = [34, 197, 94] 230 | break 231 | 232 | case 'video': 233 | bgColour = [80, 74, 226] 234 | break 235 | 236 | case 'image_with_message': 237 | bgColour = [150, 103, 28] 238 | break 239 | 240 | case 'animated_background': 241 | bgColour = [67, 102, 232] 242 | break 243 | 244 | case 'celebration': 245 | bgColour = [111, 41, 203] 246 | break 247 | 248 | case 'now_next_then': 249 | bgColour = [50, 87, 68] 250 | break 251 | 252 | case 'qr': 253 | bgColour = [53, 88, 52] 254 | break 255 | 256 | case 'checklist': 257 | bgColour = [100, 102, 237] 258 | break 259 | 260 | case 'map': 261 | bgColour = [45, 60, 135] 262 | break 263 | 264 | default: 265 | bgColour = [0, 0, 0] 266 | break 267 | } 268 | 269 | return { bgColour } 270 | } 271 | export const graphicIcons = (graphic) => { 272 | let png 273 | 274 | switch (graphic) { 275 | case 'lower_third': 276 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAHTSURBVHgB7ZThUQIxEIUXxwLsQEqwA84K1ArECvQqACtQK2CsQKiAswKhArECoIJzH3kZ1xsQZHT0x/tm3iTZ5HY3m1zMhBB/SV3Xbdcr2oa9R/uL69x1xHHB+bGrz37fNXDdcE0WvrsPfsYxjveHjfVQJ+ZDH4OcZ4idfd7RFuMMmvvZxIHtRrtRHATtukrXo+vJdeKauVbF8rZwdfjJmWvqgn3huqIq2qYcY+4+hOrTDh7Yf2vkcxTGsS2prufT5bpn2tAf2w4c2n4USLjVag0x8AQuLRVoZKkYmJ/AxpPCHDZ3bp83NGE7t1Tcpes4B3H/E/pfrfVxFU7+zPtLxlrHIvjPzOgD9rm3JznGJna9QU3yTYjJwFZZKgYK9sgEb5hYTKRDtTlG4fB7oLil7UZBH8cb5geWCo8bN4wTnssi7ONL9i0Qruol//vCUrJVKMJqbOlGXbOfQbGuqLweGzhlwluTJiV8WDqIdWDu1lWHghjfyh7zqGwL3ykQHjiAk+lnm6X3pwzBkPCCm88nNwp+ivqD7Cf/Tvi2Zz8H3rM23yCjb9yqwnVhvw0fYyGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEOLf8w7C6DWBaBx7RQAAAABJRU5ErkJggg==` 277 | break 278 | 279 | case 'message': 280 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGASURBVHgB7dTxTcJAFMfxw/i/HaFOoBvYEWAC2ECYAJwANigbWCeADYgTgBPoBvU9+7vkif3DRBIw+X6SF3vv3vXso9eUAFyytm1Li73FNOQmyvlco+t9yN1bbDRehvvknP8tw/12Fs9hXFjMVetzQ+V/7JXOTQ/m3kNur1x+6JVF5RHml2rU1wNarL0Jynn9SrXDcL+8fqmcz001V2ivddzrr67T6XzkX7LHjUXpNRofLLz2zWI0GAwO3hi7HivfWG6rWh9vtb7StedmVtPoLWl69jqJq3Q6LxaPFhOLp6O5W4sHhRupxsf+JlT2sAu7nqXu4Wq9GUXqmvaauqaOtd7zhZpTW+xS17y+vc4rHLE7P2bhaMUjNgn1hY5HpbEfsYXq5sqt8zrV1opWx2ejyN+zuNciXZKjZvi3o1Y+/tNRqYZkO+VyM1o12r8vTb6f7rnRHqXW5dppmP+2V/rP2u4IHefK9Et96wEAAAAAAAAAAAAAAAAAAAAAAAAA6PMJELIab6B0iTgAAAAASUVORK5CYII=` 281 | break 282 | 283 | case 'time': 284 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADVSURBVHgB7dPNDYJAEIbhwXjXErYTKYEODBVoCXQgdkAHagfYgR24JdgBzoYhbjh5MBNi3if5sn/sgcmsCIB/MAxDq3nOErLxqrlk309nR0t+rxInK/HTaWqb39K8KIqoY7C9jabSny9t3djZ1vKy+ym9OHErkBbjoeltmc9zUXOw+c7Wk1SkIJ+CuvDsoG+cNWV6UjIWJ87Od5YgTtayLOkZ3TUnGZ/SPjuL2nW1OFtaByWtjMXoZvupsyaNAAAAAAAAAAAAAAAAAAAAAAAAAACA33kDVUdpoA9PsA4AAAAASUVORK5CYII=` 285 | break 286 | 287 | case 'image': 288 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEiSURBVHgB7dTRTcNAEEXRNeKflLBUQAlsB7iDJBUQKqAEoIKECnAHoQNDBXEHpAMzI57FCMEPki1ZuUd6sr0zjpTRelMCMFd932fLQde95SXUimp1WGt/9Cws9+prh167NlobktMcaTB9GJQrqu30vNJz/UfPQbWN5UND26tWht6xnKdpvVr8z3Z2XVq6UKtVz5ai+xvLuqqqRruksfuj3Xv/hXpHdZam9ZS+BuPD2CUNyHeF1t+1towvaThbSxt2zKXlWhnN1AM6Wt4sD5bnsO4D6yxXes4ahPfeau3Oskjfu853k++udZqrX86gMhzOqvtZstKhuw3v+fqj3mv1G37+bEI9yumU6RMEAAAAAAAAAAAAAAAAAAAAAAAAAODfPgH66h0vMFhShgAAAABJRU5ErkJggg==` 289 | break 290 | 291 | case 'ticker': 292 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAE9SURBVHgB7dTRTQJBEMbxxfguHXgdiB0cHdCBUAF0IHSgFYgViBVAB9oB1wF2cH6T+za57JMPXgjk/0smw87sXdjJ3aUE4NK0bTtTHIuI2k6x8p6l61+KZ9dWirdef68YF/eJWlWsl+mS+AC1B3Lw77EPs/awWufonRRz92LPxP3a92s9vNq9Kvd9XZikAdymAYxGo0apiT+vfNL6EHWt85Za8an6zvWp0o8i9leKD8UmX2eV9zTOqfg9TgMYZEB/EIc55YUG8R3ZA6xSd+iH4pp7xZ37W9f2eV0M89/cpPM4KGZ+VfI3Zt7rPSri9XnqXfOqISwU615t6v2DPD3hLAPSIbdK74pj6p6kxrXcb5Q2ipcYost7f2uOxe0WqRt2na5RPEEJAAAAAAAAAAAAAAAAAAAAAAAAAICB/QI89xHf9AjT5wAAAABJRU5ErkJggg==` 293 | break 294 | 295 | case 'social': 296 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAE3SURBVHgB7dSBScNQFIXhV3GAjJAR6gZ1gmaDphPYDVyhG7Qb2A2iE1gnsBtUJ4jnhhN8BEVEUwj8HxzS3N48uCHvpQRgitq2vVNelWfl3rVC2Wb16of+6N1mPY3/L3xfRS1NjV9E6wHmHrxU9srR9Y1ydm/tnsqJ+sL9O69Zes34r3atey6N6DqN501ZKk/K7Ww2O2mYuF/r9yEa4qvRpXIes/rJz+e6HuVFWSn7dAFXaQQaNIa7SZ/DNP22GIi+vv6ePX+MFzrojZd5VM7K/Jv1/t0oLyi2lS4PSnwRa6VUohYDrtyzcO3g+tLbqPR2qwfrxRqFr6FOU+bzo9e41g/fnyUb14tB/zZbY+fDusnW7u59BuXqNCUevPiq/pt+AAAAAAAAAAAAAAAAAAAAAAAAAAD+6gM/A09KXqlvfAAAAABJRU5ErkJggg==` 297 | break 298 | 299 | case 'webpage': 300 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAF+SURBVHgB7dTtUcJAEMbxwwbUDs4KxApIB6YD0wF0YDoAKyAdiBUEK8AOsAOwgrgnz87s8FGckdH/b2aHy2Yv95IcKQE4Z8MwtBbPatcWG7WzxdZirF+PPtzz60f16ZXbWMzDGCvlrkJuGmq9/+xorDr9NptEZbFTuxsOKm3WVvmiUX6sDfK6Rm3ftJk/U22v/brW8xrfAMVOfcrLWqtdxQ39rot0urd0mPTYfiYWrxaVRXl761B3aZEt4qRvFevRaPSu3N7apd9etZWe82Rxr5oH9Vlp/DufR5mKxsnpB5y8QTbJspAyuUapNh02qiz8JZRWyueQu7G4Lrnwtuf+RZrOYqrnl4X7V/GhKBYWvcVM11njTNK50FEon/myLECf/+CL9iMU6nM4VlfqW4cjlo/qlgo/dq1qcxivUX6Zzk1YSK3rvkS4H21DvevjQkO/shmbcL0ItV3o3+l+e/TcJv1n2qiT/4gBAAAAAAAAAAAAAAAAAAAAAAAAAH/fJ6huB3NZQWVPAAAAAElFTkSuQmCC` 301 | break 302 | 303 | case 'score': 304 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEsSURBVHgB7dThTYNAGMbxwzgAI+AGOIEdoW7ABrhB2QA3aDdQJ6AblA1wg+IE5/uah3hWiV/KB5L/L3nS4ym9cBeuIQBYqxjjzjJYTpatusLSqffP4p/+NZljb8ktT+qmbMPa+ENbzpZSCzqp9wUdLBvL80X/kvSDNqPT7zeaz8eN5ajOk4eF3IbljBZ/8NrylmXZvd4Kz6Nd93bd27ic6Wt101zevWtOF5Pv+7CQm7AQW+jRPu4sH5Z2elNk1D2j7vvV63rajNYy6PqgrrA8KOtjG1L5kdHY35KoI+PHpFW/86Ok8ZD09cURq5SzOj9i+7BmWsgQvzXqy6T/+o+a6Sv1XTIetDlN/KkKa6WNyv/oi7n7AwAAAAAAAAAAAAAAAAAAAAAAAAAAV/YJIFeFjZEgJQ8AAAAASUVORK5CYII=` 305 | break 306 | 307 | case 'big_time': 308 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAFlSURBVHgB7dTRbcIwEMZxU/UdukG6ARuUDZoNyghsABuUDVA3KBNAJ2CElAlgg/QOfUYniz5AotKH/086xTk7vjiJkxKA/6xt24lFo9hYTJX387Hac53vcn+4viliZTHTMc89C+PflatU73xtMZ/Xmqd70yJa3fDC4qB8q76pbrhW+5Qvrp+F8WPNswlz78L4JtTz9lLjJqFurdwh1rrFY+rPxGJo8VHk3zw3GAw+fVHWfrY45k7Lby1/bvvRF1hOroVWF+oOlT+GnLe/1R6lDh5SfyqLJ4tXW0y8KW/nm19Z+NdQp+usLXy7nB520ecP/EWRQh3fcnt/Meme8jZQuwpbJR8X+h9UYVvUv82h83KLjbRdmlAjzzUt5op1N6mj3r4gLdDf2jZvFVla7NXnsb72rdp4/wK/fO4L3Ss9lLbIe91x13/Qn9FX0Ol/AAAAAAAAAAAAAAAAAAAAAAAAAADArX4A60ygGjhjv2YAAAAASUVORK5CYII=` 309 | break 310 | 311 | case 'lower_third_animated': 312 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGsSURBVHgB7ZTvUcJAEMUXxwIoISWkA88KxAoMFYgVSAdgBUAHsYLECqADQgXBCuLu3IuzYoAMw4wffL+ZN8nd7u3tn4AIIeSvaZpmpCrcOldtvTrOmM9aNXQx/NrsE2ihCoiVuRgzH9ts3sdyOsijwD1+b+721vAJcuUGZQeJpiioQYHhwD+BrXbFZNibueKmUOHiFS6GnW/kZ9Nr5xNQfIP4KZ41bAFxMjQnIN+6HdQ5buQCBoPBRlVi6d9bRirbW6me3P5elZ2YoNlT2E271mCF6uNB9Wg2W+PeDVxKy8vFSqDv2Oavmut7ZXlIDy5qUA+sKZZsLbGYdlrWgLFqoeqaoNnfJDb4VbV0tgC7Ucn5Au+g5Mg9vbh6gzDpVGIDEiSTtXadYK6Pd/h0YRN+xnvu9q3pOzwricUfw76WMVS63Ibu68ylB7fSn8T9H9jFyyN+E4k/uzGS+pT401g5nyn2fqHn9nqmlNhEQYxEYlH3VjDWWxRbyelcl6oPnLcv2gb2onG6zhFCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCH/ky+zbJBaZPCbcwAAAABJRU5ErkJggg==` 313 | break 314 | 315 | case 'icon_with_message': 316 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAH6SURBVHgB7ZThbcJADIVDJ8gGTSconYB0gmaDsgF0AsIE0AnCBsAEYQPYIN0gdIKrLb0rJhgof5AqvU+yLnnx2T7n7pKEEHIPQgiFWI3nTJ/FGozZFV2fx3jO9fsNeXXu0rz3EX8Ma4wVF2qYQNtqDSZeBT012sj4TqCd5OoWOowLg8Mci12YxnV169+ieP0WnEZoAXNH17khLgpxlRK2RUy1FPk3yDWHFcjfxxz7o0NsuFlnwJwc84ZeLvV/cArWQjOxstfrbWTUwNMzehb/oLAXqxIHLUCGgdgzikk7Ll9iBWK94z2SIm9m8jyKacyV1DKGpn4jsZ1or/DNEetT7M1oa/FZ4duLxjmT67RBSPaLBNqjIfvEJy52inHk+GhznpB44HzXBWhjdFuvk+MGxfkD1FPK8IFYle4M1KcL/RabxR2EmDvUnpuf2WLUHa2+MydXdlRBPGLYxq05m5NLOp4bzM/g4x0x3cKVo8e5tdn6tTlidce/MjUsjO8SWoE48Xgtw+EeKpErXgepyX+Sy22QSdKY89uHnhu9NXqDYxTvGq9BqXO0bINyk782DbIMnRrixW210q7H/KB4N81NzNp8t5TJNcJhS/5JvydeDd4PuBLjJn9CCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCH/lx+NQDLmx4NbOwAAAABJRU5ErkJggg==` 317 | break 318 | 319 | case 'credits': 320 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAF3SURBVHgB7dXtTcMwEMbxK+I7HaFMQDYgnYAyAWEENigTtEwAnQCYoGEC2CBlgnaD8FxzEVYEiA+WKNL/J50cO2cnfmlqBuA/adt2plgrGsW9YhxtTYTfKxWTpK3PLQd51WDM2aBPE23F8Jl2iGLSbp5M1q+ruPaJLBXbJLeK3CLKNsoq8sqk/yTqT4o6rn0DXhWLZKEqy+TY8pop6tFoNPeKXnSqwnez8Lra33yigz4nioli0zcor47+pYorxUu0e84mFmCb5O3i2e+K68jL4sjyGkfs+Yv6okTVd3+rcqm4TfqUinPrFmloZ7+gZ0xjTB9n/7OzTHIvUK0o4qj70X/0b0Lc2yhOrZt0OvEbTdB3/SEdyMdQcWFxen7iPzEfX2Ncqny2btGzyLpAceR9J/2F/bSMLTktuu8Lc6dY2OdJa+K7s+7zvKLC66vhwn1j5fnR78y6U3rY/uKfxD/iBgAAAAAAAAAAAAAAAAAAAAAAAADAFz4Ai4lYrXh4sfgAAAAASUVORK5CYII=` 321 | break 322 | 323 | case 'image_with_message': 324 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAH+SURBVHgB7ZTtUcMwDIZdjv9kA8IG3YAwAWUCsgHZgDIBYYKWCcoGYQO6QcoELRMYKX1NhZq7thz0+PE+dzo7sqwv2wmBEHJsYoytyFDkReTN6HOsVfi+FWnURuTxAP8F/JRG9whdDp9tEhOrRax7k0+ynYhkLs+Z8Z+J1NDrniH0W7H2KSCiiCbNoZ/ie4wk0jwVPO7x9ZWMa5DSGF0LXSquhl1hcqpwcG8Y1ffMHGY6uFJkiT2ZyX0uMkLOSzRtK5blNOxmIaIn9ipyiVEpdT4YDLpmyfxKZGUKVl0hos3RhF/E9tX5HiKpvCfuGfQLk8ctYtyIr4Xs/YB/9VGpDrZq9yByhzxr6DTHOWQq9ivxYWOtfBInYTdPKKRCku9m7QOjrultmJm1PKwbqpyjiD7fd5Bnt3aB/WnfFeyvRbobJAWOwroR2qQWNyfHHi12Dvvg8prAvnCxLsM+uCdW4gpGzKfmWS3xJDJc9brHV+uvrnliGcY2bp5semKlsc+NTYa4Izy1Ajb6xCbIscV8ZuI0Ef9JF/9brJ82qPvHYK1rEObjuKHB6XlfXVF9DcK8QTG+QV/Arvax4vqftHRN1qbV7oAq51f3VGbdkoffxjfgL+mLdUhRx8yVEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEELI/+ETmK8GbNsEzmMAAAAASUVORK5CYII=` 325 | break 326 | 327 | case 'video': 328 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAD0SURBVHgB7dRhDcIwEIbhBgVIqAQcMAmTMAdIwAIOwAE4GA6QUAngoNyFr6SUwL/92PI+yWXrUZrcpbcQAMxVznljkSzWWndal3y0GPXuz2O1N1UxKtfuj2HOvFiLu8Wg9akUll+iij2oebeqGW5QfqNcvdfPSmHuVFApOqnotkGDfu89qXe3q5rUKVdu2PuMMKFVmN7Fwkeqt2e0uP7Z+2jWncVW/3v82LsOc6cx85ty0frrBmkcz82IxeqMMq57rfeLGDGnMcvVKLUNKsbSlPwpKddX+1P5NqEx9XcHAAAAAAAAAAAAAAAAAAAAAAAAALA8T7fEe56O0g6nAAAAAElFTkSuQmCC` 329 | break 330 | 331 | case 'celebration': 332 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAHwSURBVHgB7ZXhUcJAEIUXx//agbEC6cBYgXQgdoAVECtQK0ArECsgVABUQKxArAD3yTvZYZwkzuioM++beXNkb/Nu77IJZkKI32a9XvdcE9fMdRNiy6ABNdq5N+bAIwvX8BsybxxiI9dh8EBswt+DHU+oS+8uc4bBqx/qnSVfrtdr2vt+UwI25MOj69pVulD8q4+Va+W6Yiqu+65sxyJjzpz5KXbGEX4PPh647piH9Z5dBTeBTeEQch/HzMGDWrjuuTa8Dnkgfa6J+248ViUP15BzB4zV0nhAXKzsdDoFLnyxM8ZzLpDxel7jgZyVbQ8VnDAO78p9jXNz5qXicUAlc3PWgfx3P78uWVda68L14PEx4zljU3r3PfZkLdlrmfdx0tgMFOZOqazm/iPm5CF2DDvcxy4F6Iol17vl63Bum06pbLPRrxK7JHX8yFp0D2hzQKVxEyg4fSM4h8O6pOo66I45RYjdugrbtr6x+PRqYDM9jiecz9gRdaBTzllvxnunadJruLdNJ3WtBY0HxBbGtwFP9oUFX3M6X28pPonljE1SIFgnv7mF1zNsYGB8vdJDsM3Davqw4uAX9Iee6BmBV2XfTfxn+euw2/9NvUIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIX6WN8P9YzuXYAzQAAAAAElFTkSuQmCC` 333 | break 334 | 335 | case 'animated_background': 336 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAHlSURBVHgB7ZTdUcNADIQVhnfcAe6AUAGmAtwBpgLcAUkFpINABYQKklQQU0FMBaEDoyXrQRgS54EHhtlvZsd3ku6k+/GZCSH+Ak3TrKDQL11PoT935a4JhfbalYWYGeJCv4gxbEdNmSfaymBDTU+utFPrPPgxR0L7bbDf2S9uTubaUBlto2ZLGRaHBT+wqIL+Of0p+2v7uunrEJNx8Q3bQ+ZZsZ9xHtgW7I9YVxLmbTdySF9BbXhw7XqKvrUf2WEUrpnr2ZUHe+W6QyE7xsE/ZPEjV22fi0jhc43bmMFgsOAYQ9tVMRzjU+qNtjVjRuznndxnrozxC7aXHj9jHedc014O3aAL1yuTXQc7+ljglIvoAv+jq+Qc4+CDrWKxGJtbfw1QusP/1uknQe0BbviduHBr762H3g3iL5W6Tl0nwfaBn8iExSU7psAp4X+vLdwg54p9bPiLfd34LrXnuaGqUFuCd4W5q86YZ96uJXPBn/PmFoxZWg/H1k/BZDcsKrXtaccTg2/102D8BngvbHuTjHPgRDHPpftrbvg8viMd8GY0bI9DXVCN/JinM2aKt9C2G1MyT+rt9g3E7/lg4jt7DkIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIcQ/5R2L87OAzMyCPAAAAABJRU5ErkJggg==` 337 | break 338 | 339 | case 'now_next_then': 340 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAIDSURBVHgB7ZXvTeNAEMU3iO+kg3MHlw5wB5er4JIKclSAr4ILFRgqSKggpgLcQUwFmArCPPwGDUuIBEJISO8njXZ3dvx2Zv/IKQkhvoLdbjc1uzUbc7w2+8v+wmzL+XP6arOK/cpsxX7J2PEhXdo2mPtcp6B/ksXB6pD3JpvbcM1NiFnSplnskmvGWOQ39fFx2CMUMDHDBpyZncDH4KXZb7PerDbfg7V3Zr/MKrNTs5KbgPhuNBr1h3Q519MHOo7PTWfG+Gv650HD83D+UW/FuJaxRVbbju2YGr7mjLn/t5zz/F5sUKL4zIKvg69EovbxGgPOldw0FFNw3LL9ycIiKAind5P5x6GQFptqMSi4ZvJLbnRj/icdGzdRAGPmABobd7h1aTjcGf0/qOd4fHeg7ieO9xQyZ4LxBtxnMSdMDH08wyYNm1LSzt7QXWWJgtOQZBvWxWbkse/FtYtsXfd3IT8/mHg701GuyJuCk57Q1aTh9As+oT9BGJuyYLtmH8+r3aMLnaugmxg7p/k3eEYXabgBVfo4vWuznlf+eButjxfhz/OZozfEcSs6fniZhsK2abhJ8PsNabzlaXfBt48qvTxJvH2n8h+AaWF9FLYIz+ezKMKadTaHNfv0UfxPJIQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQnw3HgHNJIea1n5GlwAAAABJRU5ErkJggg==` 341 | break 342 | 343 | case 'checklist': 344 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAG2SURBVHgB7ZThTQJBEIUHYwHXgVcCVKB0cFQgVgAdgBWIFYAVgBUcVABWwFqBWAHOy70zm4tBst4PQ96XvFxud/bN3tzOmgkh/iPH47Fwla69a+7K6rEoZkYVjKs15vyI71vXhGNj+EXzW3ojrtvIP//Jx5U38kEzS+DaEsAG/LF0PbseXU8ufHRw5VFohnA+oQHHg3vc+RObfuC6uY99Mi5njinmO53Oge9Zwztn0eDTZ24U+oW+yDFi3mAJJBXIKVw733h9EgbcMDaLvz1k3E1jYzmfgR6v7rGIPA6uIeNwEhc+v7LTBK67d21cfV+DscCiHvx9bYlcWQtgQ65dNHRL5Y3QeBwF/Yg8dvwwi+a79ntuFKfnerPqtJRoSWuJ1AKhGF20Ce+HZX0fWPXH0BY44ptozfc4/yhORsH7or5jpozFfI85xqc2grvIqnaHH05hbmcU9lySCsQPxN2DNsApyPh+ChSiZsrWwV2xp0ew6i6pcwR6TtgqoOT6MvJdu97pA63+0lKt08ZxbsujzdYSQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQghxWXwB7OMuc15ZyCMAAAAASUVORK5CYII=` 345 | break 346 | 347 | case 'qr': 348 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAFsSURBVHgB7dTRUcJAFIXhxfFd7AArUCuQEugAOhArMB0gFWgHxgoSK5AOQgfBCuK5eHdY0Dgy5iHO/N/MnZBzsyHZJBsCgP+iaZqRqlBVqkfb9zxmb6rFN+Puk/6kJZ95Nk+y5+Q/cs9jXYW+8Qt7UI394oskn3tex5v13sL7Ez/GDFtyG5/55MTftR9fqJ48txqGDpyGjthFaTNSZYPBYKP9tX5X8QnLRrXybcrGLTUm9/OsWvKpZ9tzKS+1LZXfahvfujO/huD9PzsJHbPJaWnZp1Wr3lV5ktuT3iTjSz/HXh6+Tmyax96F6sarE529QcHfDls3tD1XXarWutm1Muvfhc+nOz2YxFfLdEzpffssr1UvB/lYtVRt1xb/hKbei29drnNnoa98vaianbnnls18rahj7r24sDdp74c8S85fNbvFu2j2jUNf+c2N0on4xZjhMTkAAAAAAAAAAAAAAAAAAAAAAAAAAMf4ADranYWgCZjnAAAAAElFTkSuQmCC` 349 | break 350 | 351 | case 'map': 352 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADxSURBVHgB7dRhTcRAEMXxKUFAJVQCEg4FHA7qAJwQFBAUgIMrCsAB56B10HtzeU1GwKVNmv8veWl3dvthN52NALAX8zwflH+lL7U31zqPe49fy5qTa7+5PvbKB5ROHrfe+FwO6FsZlzWu5Zqjv8+5Y6zkPrbxkJvVs6vFPDA9npRn5SsPrWmas6cnvQ+q5XsbK7mLbbwrL85nqeefMTlnpS9zeWCj54bYo9JirZ/Xu2dpMd81f8rHcu/4u6XFuljZJi2mVpm02UGvP6XcKQfl0a2UbTS6FdNU2g0AAAAAAAAAAAAAAAAAAAAAAAAAANzSBdGTyjOnDtskAAAAAElFTkSuQmCC` 353 | break 354 | 355 | default: 356 | // BLANK 357 | png = `iVBORw0KGgoAAAANSUhEUgAAAEgAAAA6CAYAAAATBx+NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAmSURBVHgB7cABAQAAAIIg/69uSFAAAAAAAAAAAAAAAAAAAAAArwZBegAB2I2aJAAAAABJRU5ErkJggg==` 358 | break 359 | } 360 | 361 | return { png } 362 | } 363 | 364 | // export const replaceWithDataSource = (text, dynamicText, keepBrakets = false) => { 365 | // const array = text.split(/\[(.*?)\]/g) 366 | // let array2 367 | // const regEx = /\[(.*?)\]/g 368 | // const match = text.match(regEx) 369 | 370 | // if (!match) return text 371 | 372 | // array2 = [...array] 373 | 374 | // match.forEach((m) => { 375 | // let m2 = m.replace('[', '') 376 | // let m3 = m2.replace(']', '') 377 | 378 | // const index = array.indexOf(m3) 379 | 380 | // let returnString = dynamicText?.[m3] 381 | 382 | // array2.splice(index, 1) 383 | // array2.splice(index, 0, !keepBrakets ? returnString : `[${returnString || 'Not set'}]`) 384 | // }) 385 | 386 | // return array2.join('') 387 | // } 388 | 389 | export const replaceWithDataSource = (text = '', dynamicText, dynamicLists, keepBrakets = false) => { 390 | const array = text.split(/\[(.*?)\]/g) 391 | let array2 392 | const regEx = /\[(.*?)\]/g 393 | const match = text.match(regEx) 394 | 395 | if (!match) return text 396 | 397 | array2 = [...array] 398 | 399 | match.forEach((m) => { 400 | let m2 = m.replace('[', '') 401 | let m3 = m2.replace(']', '') 402 | let pullFromList = false 403 | let list = 0 404 | let row = 1 405 | let cell = 0 406 | 407 | const index = array.indexOf(m3) 408 | 409 | if (m3.includes('row') && m3.includes('cell')) { 410 | pullFromList = true 411 | let split = m3.split('.') 412 | list = split[0]?.replace('list', '') 413 | row = split[1]?.replace('row', '') 414 | cell = split[2]?.replace('cell', '') 415 | } 416 | 417 | let returnString = pullFromList 418 | ? dynamicLists?.[parseInt(list) - 1]?.[parseInt(row)]?.[parseInt(cell) - 1]?.value 419 | : dynamicText?.[m3] 420 | 421 | array2.splice(index, 1) 422 | array2.splice(index, 0, !keepBrakets ? returnString : `[${returnString || 'Not set'}]`) 423 | }) 424 | return array2.join('') 425 | } 426 | -------------------------------------------------------------------------------- /utils/README.md: -------------------------------------------------------------------------------- 1 | # Useful Utilities 2 | 3 | ## Automated H2R Launching on Windows 4 | 5 | If you want to automate launching H2R on Windows the [launch_h2r.ahk](/utils/launch_h2r.ahk) script will help. 6 | 7 | - Download [AutoHotkey v2](https://www.autohotkey.com) from 8 | - install it 9 | - Copy `launch_h2r.ahk` somewhere that Bitfocus Companion can find it 10 | - Edit `launch_h2r.ahk` to customise paths and window titles at the top: 11 | 12 | ```autohotkey 13 | exe := "C:\\h2r-graphics-electron\H2R Graphics.exe" 14 | window_title := "Output 1 - " 15 | url := "http://localhost:4001/api//output/1/open" 16 | ``` 17 | 18 | If you now double click `launch_h2r.ahk` in your Windows Explorer, it should launch H2R (if needed), open an output window (if needed) and maximise it full screen. 19 | 20 | If you want to automate this in Companion 21 | 22 | - create a button 23 | - add the steps shown below 24 | 25 | ![Companion Action Steps](/utils/companion%20steps.png) 26 | 27 | > [!IMPORTANT] 28 | > For the "Path" you want something like: 29 | > `"C:\Program Files\AutoHotkey\v2\AutoHotkey.exe" "\scripts\launch_h2r.ahk"` 30 | > 31 | > You will need the quotes and spaces exactly as shown. 32 | 33 | If you now press the button, H2R should launch, and open the output window full screen ready for you to use in your video switcher. 34 | -------------------------------------------------------------------------------- /utils/companion steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitfocus/companion-module-h2r-graphics/53492c76ed1cd3f8a002d314ba2c6abeca58e0a3/utils/companion steps.png -------------------------------------------------------------------------------- /utils/launch_h2r.ahk: -------------------------------------------------------------------------------- 1 | #SingleInstance 2 | ; customise these variables 3 | exe := "C:\\h2r-graphics-electron\H2R Graphics.exe" 4 | window_title := "Output 1 - " 5 | url := "http://localhost:4001/api//output/1/open" 6 | 7 | If !WinExist("ahk_exe H2R Graphics.exe") { 8 | Run exe 9 | Sleep 5000 10 | } 11 | If !WinExist(window_title) { 12 | whr := ComObject("WinHttp.WinHttpRequest.5.1") 13 | whr.Open("POST", url, true) 14 | whr.SetRequestHeader("Content-Type", "application/json") 15 | whr.Send("{}") 16 | whr.WaitForResponse() 17 | } 18 | 19 | WinWait window_title 20 | 21 | ; if the window is not maximized, maximize it 22 | WinGetPos &X, &Y, &W, &H, window_title 23 | If (W != 1920) 24 | { 25 | WinActivate window_title 26 | Send "^f" 27 | } 28 | 29 | Sleep 1000 30 | 31 | WinMinimize "H2R Graphics" ; just in case it pops up --------------------------------------------------------------------------------