diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9d08a1a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.env.example b/.env.example index 64a24ad..db4a646 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,5 @@ -CG_PUBLIC_URL=chatguessr.com -CG_API_URL=https://chatguessr.com/api -SOCKET_SERVER_URL= -SUPABASE_URL= -SUPABASE_ANON_KEY= -NODE_ENV= \ No newline at end of file +VITE_CG_PUBLIC_URL=chatguessr.com +VITE_CG_API_URL=https://chatguessr.com/api +VITE_SOCKET_SERVER_URL= +VITE_SUPABASE_URL= +VITE_SUPABASE_ANON_KEY= diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..96b1ac6 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "root": true, + "env": { + "browser": true, + "es6": true, + "node": true + }, + "plugins": ["vue", "@typescript-eslint", "prettier"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "plugin:vue/vue3-recommended", + "@vue/eslint-config-typescript/recommended", + "@vue/eslint-config-prettier" + ], + "rules": { + "no-empty": ["error", { "allowEmptyCatch": true }], + "@typescript-eslint/no-empty-function": ["error", { "allow": ["arrowFunctions"] }], + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-explicit-any": "warn", + "vue/multi-word-component-names": "off", + "vue/no-v-html": "off" + } +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b80e7cb..d9e720e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,17 +2,24 @@ name: CI on: [push, pull_request] +env: + VITE_CG_PUBLIC_URL: ${{secrets.VITE_CG_PUBLIC_URL}} + VITE_CG_API_URL: ${{secrets.VITE_CG_API_URL}} + VITE_SOCKET_SERVER_URL: ${{secrets.VITE_SOCKET_SERVER_URL}} + VITE_SUPABASE_URL: ${{secrets.VITE_SUPABASE_URL}} + VITE_SUPABASE_ANON_KEY: ${{secrets.VITE_SUPABASE_ANON_KEY}} + jobs: types: name: Types runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - name: Install dependencies run: npm ci - name: Check types @@ -22,18 +29,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - name: Install dependencies run: npm ci - name: Run tests run: npm test package: name: Package - needs: [test, types] + needs: [types, test] strategy: fail-fast: false matrix: @@ -41,26 +48,24 @@ jobs: runs-on: ${{matrix.os}} steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - name: Install dependencies run: npm ci - - name: Write .env - run: node create-env.js - env: - CG_PUBLIC_URL: ${{secrets.CG_PUBLIC_URL}} - CG_API_URL: ${{secrets.CG_API_URL}} - SOCKET_SERVER_URL: ${{secrets.SOCKET_SERVER_URL}} - SENTRY_DSN: ${{secrets.SENTRY_DSN}} - SUPABASE_URL: ${{secrets.SUPABASE_URL}} - SUPABASE_ANON_KEY: ${{secrets.SUPABASE_ANON_KEY}} - TWITCH_CLIENT_ID: ${{secrets.TWITCH_CLIENT_ID}} + # - name: Write .env + # run: node create-env.js + # env: + # VITE_CG_PUBLIC_URL: ${{secrets.VITE_CG_PUBLIC_URL}} + # VITE_CG_API_URL: ${{secrets.VITE_CG_API_URL}} + # VITE_SOCKET_SERVER_URL: ${{secrets.VITE_SOCKET_SERVER_URL}} + # VITE_SUPABASE_URL: ${{secrets.VITE_SUPABASE_URL}} + # VITE_SUPABASE_ANON_KEY: ${{secrets.VITE_SUPABASE_ANON_KEY}} - name: Package run: npm run package - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Chatguessr-${{runner.os}} path: out/*/ diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 34cc51c..309d20e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,6 +5,13 @@ on: release: types: [created] +env: + VITE_CG_PUBLIC_URL: ${{secrets.VITE_CG_PUBLIC_URL}} + VITE_CG_API_URL: ${{secrets.VITE_CG_API_URL}} + VITE_SOCKET_SERVER_URL: ${{secrets.VITE_SOCKET_SERVER_URL}} + VITE_SUPABASE_URL: ${{secrets.VITE_SUPABASE_URL}} + VITE_SUPABASE_ANON_KEY: ${{secrets.VITE_SUPABASE_ANON_KEY}} + jobs: release: name: Publish release @@ -15,29 +22,26 @@ jobs: runs-on: ${{matrix.os}} steps: - name: Checkout sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - name: Install dependencies run: npm ci - - name: Write .env - run: node create-env.js - env: - CG_PUBLIC_URL: ${{secrets.CG_PUBLIC_URL}} - CG_API_URL: ${{secrets.CG_API_URL}} - SOCKET_SERVER_URL: ${{secrets.SOCKET_SERVER_URL}} - SENTRY_DSN: ${{secrets.SENTRY_DSN}} - SUPABASE_URL: ${{secrets.SUPABASE_URL}} - SUPABASE_ANON_KEY: ${{secrets.SUPABASE_ANON_KEY}} - TWITCH_CLIENT_ID: ${{secrets.TWITCH_CLIENT_ID}} + # - name: Write .env + # run: node create-env.js + # env: + # VITE_CG_PUBLIC_URL: ${{secrets.VITE_CG_PUBLIC_URL}} + # VITE_CG_API_URL: ${{secrets.VITE_CG_API_URL}} + # VITE_SOCKET_SERVER_URL: ${{secrets.VITE_SOCKET_SERVER_URL}} + # VITE_SUPABASE_URL: ${{secrets.VITE_SUPABASE_URL}} + # VITE_SUPABASE_ANON_KEY: ${{secrets.VITE_SUPABASE_ANON_KEY}} - name: Publish run: npm run publish env: GITHUB_TOKEN: ${{github.token}} - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Chatguessr-${{runner.os}} path: out/*/ - diff --git a/.gitignore b/.gitignore index 4576c24..a507c3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules +.vite +out dist +*.log* .env -.parcel-cache -out/ diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000..d955e51 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,5 @@ +singleQuote: true +semi: false +printWidth: 100 +trailingComma: none +endOfLine: auto diff --git a/README.md b/README.md index f6abff8..4eb199b 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,56 @@ -# ChatGuessr - -> Play GeoGuessr on Stream with Twitch Chat. - -This is the source code for the ChatGuessr application. Are you a streamers or player? Check [the website](https://chatguessr.com) instead. +
+ +

ChatGuessr

+
+ +

+ + releases url + + + license url + + + paypal url + +

+ +

This is the source code for the ChatGuessr application. Are you a streamer or a player ? Check the website instead.

## Build + Run the application in development mode: + ``` -npm start +npm run dev ``` Run unit tests: + ``` npm test ``` -Typecheck JSDoc: +Typecheck + ``` npm run typecheck ``` -Build the application for the current platform: +Lint + ``` -npm run package +npm run lint ``` -Build an installer for the current platform: +Format + ``` -npm run make +npm run format ``` ## License + The ChatGuessr source is available under the [MIT License](./LICENSE). -The Montserrat and Comfortaa fonts are used under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL). +The Montserrat font is used under the [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL). diff --git a/assets/extenssr-styles.css b/assets/extenssr-styles.css deleted file mode 100644 index 7fb826c..0000000 --- a/assets/extenssr-styles.css +++ /dev/null @@ -1,37 +0,0 @@ -/* Adapted from https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/css/styles.css */ - -/* shortcut menu items */ -.extenssr__nav-submenu { - z-index: 55; - position: absolute; - top: 3rem; - padding: 0.375rem 0; - border-radius: 0.5rem; - max-width: 300px; - background: var(--ds-color-black-80); - list-style-type: none; -} - -.extenssr__nav-submenu li { - box-sizing: border-box; - width: 100%; - white-space: nowrap; - padding: 0; - margin: 0; -} - -.extenssr__nav-submenu a { - box-sizing: border-box; - display: inline-block; - width: 100%; - padding: 0.25rem 1rem 0.25rem 1rem; - color: #fff; - opacity: 0.6; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.extenssr__nav-submenu a:hover { - opacity: 1; - text-decoration: none; -} diff --git a/assets/flags/USME.svg b/assets/flags/USME.svg deleted file mode 100644 index 575715d..0000000 --- a/assets/flags/USME.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/flags/USMT.svg b/assets/flags/USMT.svg deleted file mode 100644 index cf35904..0000000 --- a/assets/flags/USMT.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/flags/USVT.svg b/assets/flags/USVT.svg deleted file mode 100644 index db9d6fe..0000000 --- a/assets/flags/USVT.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/fonts/Comfortaa-Bold.ttf b/assets/fonts/Comfortaa-Bold.ttf deleted file mode 100644 index 62389b6..0000000 Binary files a/assets/fonts/Comfortaa-Bold.ttf and /dev/null differ diff --git a/assets/fonts/Comfortaa-Regular.ttf b/assets/fonts/Comfortaa-Regular.ttf deleted file mode 100644 index 2862736..0000000 Binary files a/assets/fonts/Comfortaa-Regular.ttf and /dev/null differ diff --git a/assets/fonts/montserrat-regular-webfont.woff b/assets/fonts/montserrat-regular-webfont.woff deleted file mode 100644 index 86331d9..0000000 Binary files a/assets/fonts/montserrat-regular-webfont.woff and /dev/null differ diff --git a/assets/icons/gear.svg b/assets/icons/gear.svg deleted file mode 100644 index 80b738f..0000000 --- a/assets/icons/gear.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/icons/scoreboard_hidden.svg b/assets/icons/scoreboard_hidden.svg deleted file mode 100644 index 96ee879..0000000 --- a/assets/icons/scoreboard_hidden.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/assets/icons/scoreboard_visible.svg b/assets/icons/scoreboard_visible.svg deleted file mode 100644 index ae5fb1e..0000000 --- a/assets/icons/scoreboard_visible.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/icons/start_flag.svg b/assets/icons/start_flag.svg deleted file mode 100644 index bfebe45..0000000 --- a/assets/icons/start_flag.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/icons/timer_hidden.svg b/assets/icons/timer_hidden.svg deleted file mode 100644 index 640353c..0000000 --- a/assets/icons/timer_hidden.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/assets/icons/timer_visible.svg b/assets/icons/timer_visible.svg deleted file mode 100644 index b423a7a..0000000 --- a/assets/icons/timer_visible.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/assets/styles.css b/assets/styles.css deleted file mode 100644 index 0cee78d..0000000 --- a/assets/styles.css +++ /dev/null @@ -1,567 +0,0 @@ -@import "./extenssr-styles.css"; - -:root { - --main-color: #59f3b3; -} - -@font-face { - font-family: Montserrat; - src: url(asset:fonts/montserrat-regular-webfont.woff2) format("woff2"), - url(asset:fonts/montserrat-regular-webfont.woff) format("woff"); - font-weight: 400; - font-style: normal; -} - -/* GAME SETTINGS SCREEN */ -[data-qa="game-type-challenge"], -[data-qa="game-type-single-player"] { - display: none !important; -} - -[class^="play_map__"] { - height: 9rem !important; -} -[class^="start-standard-game_body__"] { - margin-top: 0 !important; -} - -/* Hides friends list bar */ -[class^="version4_sidebar__"] { - display: none; -} -[class^="version4_content__"] { - max-width: 100% !important; -} - -/* Hide promo and daily challenge from menu */ -[class^='header_promoDealButtonWrapper'] { - display: none !important; -} - -[class^="header_context__"] > :nth-child(3) { - display: none !important; -} -[class^="header_loginButton__"] { - display: block !important; -} - -/* Hide Return to Home Top Left menu */ -[class^="header_mainNavigation__"] { - display: none !important; -} - -/* Hide community page menu links */ -[class^="community-navigation_tabsWrapper__"] a:not([href="/community/maps"]) { - display: none; -} - -/* Hide results overlay */ -[class^="result-overlay_overlay__"], -[class^="result-overlay_overlayContent__"], -[class^="result-overlay_overlayXpBar__"], -[class^="result-layout_adWrapper__"], -[class^="standard-final-result_challengeWrapper__"] { - display: none !important; -} - -[class^="styles_friendChatButton__"] { - display: none; -} - -/* removes game breakdown button */ -[class^="standard-final-result_wrapper__"] > div:first-child { - display: none; -} -[class^="round-indicator_roundIndicator__"] { - width: 150px; -} - -/* CUSTOM SLIDER FOR SCRIPTS */ -.custom-slider { - -webkit-appearance: none; - width: 100%; - height: 0.5rem; - border-radius: 0.625rem; - background: #a19bd9; - margin: 1.25rem 0; - padding: 0; - border: none; - outline: none; - -webkit-transition: 0.2s; - transition: opacity 0.2s; -} -.custom-slider::-webkit-slider-thumb { - -webkit-appearance: none; - box-shadow: inset 0 0.0625rem 0 0 #a19bd9; - appearance: none; - width: 1.5rem; - height: 1.5rem; - border-radius: 50%; - background: #7950e5; - cursor: pointer; -} -.custom-slider::-moz-range-thumb { - box-shadow: inset 0 0.0625rem 0 0 #a19bd9; - width: 1.5rem; - height: 1.5rem; - border-radius: 50%; - background: #7950e5; - cursor: pointer; -} - -/* CG Guess Markers InfoWindow */ -.gm-ui-hover-effect { - display: none !important; -} - -.gm-style .gm-style-iw-c, -.gm-style .gm-style-iw-tc::after { - background: rgba(0, 0, 0, 0.5) !important; -} -.gm-style .gm-style-iw-c { - padding: 8px 10px !important; -} - -.gm-style .gm-style-iw-d { - overflow: auto !important; - padding: 0 !important; - color: #ffffff; - text-align: center; - font-weight: 700; - padding-left: 7px; -} -.gm-style-iw-d .username { - font-size: 1rem; -} -.gm-style .gm-style-iw-d::-webkit-scrollbar-track, -.gm-style .gm-style-iw-d::-webkit-scrollbar-track-piece { - background: transparent !important; -} -.gm-style-cc, -#satelliteCanvas .gmnoprint { - display: none; -} - -/* SCOREBOARD */ -#scoreboard { - font-family: Montserrat, sans-serif; - position: relative; - min-width: 380px; - min-height: 180px; - max-width: 1800px; - max-height: 1000px; - padding: 5px; - background-color: rgba(0, 0, 0, 0.4); - box-shadow: 2px 2px 7px -2px #000; - color: #fff; - text-align: center; - border-radius: 10px; - pointer-events: auto; - user-select: none; - overflow: hidden; - cursor: move; - z-index: 999999; -} -.dataTables_scrollHeadInner { - width: 100% !important; -} -#scoreboardHeader { - display: grid; - grid-template-areas: "settings title switch"; - grid-template-columns: 90px auto 80px; - grid-template-rows: 40px; - justify-items: center; - font-size: 18px; - align-items: center; -} -.is-slider-visible #scoreboardHeader { - grid-template-areas: - "settings title switch" - "scroll scroll scroll"; - grid-template-rows: 40px 10px; -} -.is-hint-visible #scoreboardHeader { - grid-template-areas: - "settings title switch" - "hint hint hint"; - grid-template-rows: 40px 20px; -} -.is-slider-visible.is-hint-visible #scoreboardHeader { - grid-template-areas: - "settings title switch" - "hint hint hint" - "scroll scroll scroll"; - grid-template-rows: 40px 20px 10px; -} -.scoreboardSettings { - grid-area: settings; -} -.scoreboardTitle { - grid-area: title; -} -.scoreboardHint { - grid-area: hint; - display: none; - font-size: 0.75rem; -} -.is-hint-visible .scoreboardHint { - display: block; -} -.scoreboardSlider { - grid-area: scroll; - width: 100%; - display: none; -} -.is-slider-visible .scoreboardSlider { - display: block; -} - -.flag-icon-background { - background-size: contain; - background-position: 50%; - background-repeat: no-repeat; -} -.flag-icon { - background-size: contain; - background-position: 50%; - background-repeat: no-repeat; - position: relative; - display: inline-block; - width: 1.33333333em; - line-height: 1em; - margin-right: 5px; -} -.flag-icon:before { - content: "\00a0"; -} -.flag-icon.flag-icon-squared { - width: 1em; -} - -.dataTables_scrollBody::-webkit-scrollbar { - display: none; -} -.dataTables_scrollBody { - padding-top: 2px; - padding-bottom: 55px; - -ms-overflow-style: none; - scrollbar-width: none; -} -#scoreboard table { - font-size: 15px; - line-height: 0.8; - font-weight: 700; - width: 100% !important; - margin: 0 auto; - clear: both; - border-collapse: collapse; - table-layout: fixed; - word-wrap: break-word; - overflow: hidden; -} -#scoreboard thead { - font-size: 14px; - background-color: rgba(0, 0, 0, 0.5); -} -#scoreboard tbody td, -#scoreboard thead th { - padding: 8px 0; - line-height: 1em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -#scoreboard tbody .odd { - background-color: rgba(0, 0, 0, 0.1); -} -#scoreboard tbody .even { - background-color: rgba(0, 0, 0, 0.2); -} -#scoreboard tbody > tr:hover { - -webkit-transition: 0.1s; - transition: 0.1s; - transform: scale(1.01); - background-color: rgba(0, 0, 0, 0.4); -} -#scoreboard tbody tr:hover > .sorting_1, -#scoreboard tbody tr > .sorting_1 { - background-color: rgba(0, 0, 0, 0.1); -} -#scoreboard th.sorting, -#scoreboard th.sorting_asc, -#scoreboard th.sorting_desc { - cursor: pointer; -} -#scoreboard th.sorting:hover, -#scoreboard th.sorting_asc:hover, -#scoreboard th.sorting_desc:hover { - -webkit-transition: 0.1s; - transition: 0.2s; - color: #d6d6d6; -} -.dt-down-arrow { - display: none; -} -.dataTables_empty { - display: none; -} -.medal { - font-size: 20px; - line-height: 0; -} -.username { - text-shadow: 0.05em 0 0.05em #fff; -} -.expand { - animation: expand 0.2s ease-in-out; -} -@keyframes expand { - from { - transform: scale(0); - opacity: 0; - } -} -.ui-draggable .ui-dialog-titlebar { - cursor: move; -} -.ui-draggable-handle { - -ms-touch-action: none; - touch-action: none; -} -.ui-resizable { - position: relative; -} -.ui-resizable-handle { - position: absolute; - font-size: 0.1px; - touch-action: none; -} -.ui-resizable-autohide .ui-resizable-handle, -.ui-resizable-disabled .ui-resizable-handle { - display: none; -} -.ui-resizable-n { - cursor: n-resize; - height: 12px; - width: 100%; - top: -5px; - left: 0; -} -.ui-resizable-s { - cursor: s-resize; - height: 12px; - width: 100%; - bottom: 0; - left: 0; -} -.ui-resizable-e { - cursor: e-resize; - width: 12px; - height: 100%; - right: -3px; - top: 0; -} -.ui-resizable-w { - cursor: w-resize; - width: 12px; - height: 100%; - left: 0; - top: 0; -} -.ui-resizable-se { - cursor: se-resize; - width: 12px; - height: 12px; - right: 0; - bottom: 0; -} -.ui-resizable-sw { - cursor: sw-resize; - width: 12px; - height: 12px; - left: 0; - bottom: 0; -} -.ui-resizable-nw { - cursor: nw-resize; - width: 12px; - height: 12px; - left: 0; - top: 0; -} -.ui-resizable-ne { - cursor: ne-resize; - width: 12px; - height: 12px; - right: -3px; - top: -3px; -} -.dt-buttons { - text-align: left; -} -.dt-button { - vertical-align: middle; - font-size: 14px; - cursor: pointer; - border-radius: 5px; - border: 1px solid #000; - background-size: 200% auto; - background-image: linear-gradient(to right, #2e2e2e 0, #454545 51%, #2e2e2e 100%); - transition: 0.3s; - -webkit-transition: 0.3s; -} -.dt-button:hover { - background-position: right center; - box-shadow: 2px 2px 5px -2px #000; -} -.dt-button-collection { - margin-top: -29px; - margin-left: 45px; - position: absolute; -} -.dt-button-collection div { - background-color: #333; - border-radius: 8px; - padding: 4px 6px 4px 6px; -} -.buttons-columnVisibility { - color: #fff; - padding: 3px 7px; -} -.buttons-columnVisibility.active { - background-image: linear-gradient(to right, #1cd997 0, #33b09b 51%, #1cd997 100%); -} -.colvis-btn { - width: 40px; - height: 25px; -} -.scrollBtn { - text-align: center; - width: 38px; - height: 23px; - margin-right: 4px; - float: left; -} -.scrollBtn label span { - margin-top: 2px; - height: 100%; - display: block; - cursor: pointer; -} -.scrollBtn label input { - position: absolute; - top: -50px; -} -.scrollBtn input:checked + span { - color: #1cd997; -} -#switchContainer { - grid-area: "switch"; - z-index: 99; - position: relative; - display: inline-block; - width: 37px; - height: 21px; - -webkit-transition: 0.1s; - transition: 0.1s; -} -#switchContainer:hover { - box-shadow: 2px 2px 7px -2px #000; -} -#switchContainer input { - display: none; -} -.switch { - position: absolute; - cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - border-radius: 4px; - background-color: #e04352; - transition: 0.1s; -} -.switch:before { - position: absolute; - content: ""; - height: 16px; - width: 16px; - left: 2px; - bottom: 3px; - border-radius: 3px; - background-color: #fff; - transition: 0.2s; -} -input:checked + .switch { - background-color: #1cd997; - box-shadow: 2px 2px 7px -2px #000; -} -input:checked + .switch:before { - transform: translateX(17px); -} -#scrollSpeedSlider { - vertical-align: super; - height: 3px; - padding: 0; - -webkit-appearance: none; - width: calc(100% - 12px); - background: #fff; - outline: 0; - opacity: 0.2; - -webkit-transition: 0.3s; - transition: opacity 0.3s; - direction: rtl; -} -#scrollSpeedSlider:hover { - opacity: 1; -} -#scrollSpeedSlider::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 30px; - height: 7px; - background: #63db85; - cursor: pointer; -} -#scrollSpeedSlider::-moz-range-thumb { - width: 30px; - height: 7px; - background: #63db85; - cursor: pointer; -} -.btn { - margin: 30px; - padding: 5px; - background-color: #22da8d; - color: #fff; - font-weight: 700; -} -.btn:hover { - background-color: #18cc81; -} -.btn:active { - background-color: #15b472; -} - -#satelliteCanvas { - z-index: 9; - display: none; - z-index: 1; - width: 100%; - height: 100%; -} - -.guess-map__canvas > div > div { - background: rgba(0, 0, 0, 0.5) !important; -} -.gm-style-mtc :is(button, ul, li) { - background: rgba(0, 0, 0, 0.5) !important; - color: #fff !important; -} -.gm-style-mtc img { - background: #22da8d !important; -} -.ssQIHO-checkbox-menu-item span span { - background-color: #fff !important; -} diff --git a/create-env.js b/create-env.js index a1cabc3..35ffeb8 100644 --- a/create-env.js +++ b/create-env.js @@ -1,11 +1,12 @@ -const { writeFileSync } = require("fs"); +const { writeFileSync } = require('fs') -writeFileSync(".env", ` -CG_PUBLIC_URL=${process.env.CG_PUBLIC_URL} -CG_API_URL=${process.env.CG_API_URL} -SOCKET_SERVER_URL=${process.env.SOCKET_SERVER_URL} -SENTRY_DSN=${process.env.SENTRY_DSN} -SUPABASE_URL=${process.env.SUPABASE_URL} -SUPABASE_ANON_KEY=${process.env.SUPABASE_ANON_KEY} -TWITCH_CLIENT_ID=${process.env.TWITCH_CLIENT_ID} -`); \ No newline at end of file +writeFileSync( + '.env', + ` +VITE_CG_PUBLIC_URL=${process.env.VITE_CG_PUBLIC_URL} +VITE_CG_API_URL=${process.env.VITE_CG_API_URL} +VITE_SOCKET_SERVER_URL=${process.env.VITE_SOCKET_SERVER_URL} +VITE_SUPABASE_URL=${process.env.VITE_SUPABASE_URL} +VITE_SUPABASE_ANON_KEY=${process.env.VITE_SUPABASE_ANON_KEY} +` +) diff --git a/forge.config.ts b/forge.config.ts new file mode 100644 index 0000000..aee63c9 --- /dev/null +++ b/forge.config.ts @@ -0,0 +1,59 @@ +import type { ForgeConfig } from '@electron-forge/shared-types' +import { MakerSquirrel } from '@electron-forge/maker-squirrel' +import { MakerZIP } from '@electron-forge/maker-zip' +import { MakerDeb } from '@electron-forge/maker-deb' +import { VitePlugin } from '@electron-forge/plugin-vite' +import { PublisherGithub } from '@electron-forge/publisher-github' + +const config: ForgeConfig = { + packagerConfig: { + asar: true, + icon: 'build/icon', + executableName: 'chatguessr' + }, + makers: [ + new MakerSquirrel({ + name: 'chatguessr', + setupIcon: 'build/icon.ico', + loadingGif: 'build/icon_installer.gif', + iconUrl: 'file://build/icon.ico' + }), + new MakerZIP({}, ['darwin']), + new MakerDeb({ + options: { + bin: 'chatguessr' + } + }) + ], + publishers: [ + new PublisherGithub({ + repository: { + owner: 'tzhf', + name: 'chatguessr' + } + }) + ], + plugins: [ + new VitePlugin({ + build: [ + // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. + { + entry: 'src/main/main.ts', + config: 'vite.main.config.ts' + }, + { entry: 'src/preload/preload.ts' }, + { + entry: 'src/renderer/renderer.ts', + config: 'vite.renderer.config.ts' + }, + { entry: 'src/auth/auth_preload.ts' }, + { entry: 'src/auth/auth_impl.ts' } + ], + // Usually renderer goes here but in our case we need the compiled JS + // so we can inject it into GeoGuessr instead of running a vite dev server + renderer: [] + }) + ] +} + +export default config diff --git a/package-lock.json b/package-lock.json index ecf4ca6..fc82f1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,10682 +1,10765 @@ { - "name": "chatguessr", - "version": "2.3.4", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "chatguessr", - "version": "2.3.4", - "license": "MIT", - "dependencies": { - "@sentry/electron": "^4.1.1", - "@supabase/supabase-js": "^2.1.0", - "@vueuse/core": "^9.13.0", - "axios": "^1.1.3", - "better-sqlite3": "^8.0.0", - "coordinate_to_country": "^1.1.0", - "datatables.net": "^1.11.3", - "datatables.net-buttons": "^2.0.1", - "datatables.net-plugins": "^1.10.24", - "datatables.net-scroller": "^2.0.5", - "dotenv": "^16.0.3", - "electron-squirrel-startup": "^1.0.0", - "electron-store": "^8.0.1", - "find-up": "^5.0.0", - "format-duration": "^3.0.2", - "jquery": "^3.6.0", - "jquery-ui-dist": "^1.12.1", - "match-sorter": "^6.3.1", - "p-map": "^4.0.0", - "socket.io-client": "^4.4.1", - "tmi.js": "^1.8.5", - "update-electron-app": "^2.0.1", - "vue": "^3.2.47", - "when-dom-ready": "^1.2.12" - }, - "devDependencies": { - "@electron-forge/cli": "^6.0.0", - "@electron-forge/maker-deb": "^6.0.0", - "@electron-forge/maker-squirrel": "^6.0.0", - "@electron-forge/maker-zip": "^6.0.0", - "@electron-forge/publisher-github": "^6.0.0", - "@parcel/transformer-inline-string": "^2.0.0", - "@parcel/transformer-vue": "^2.8.3", - "@tsconfig/node16": "^1.0.3", - "@types/better-sqlite3": "^7.6.1", - "@types/datatables.net-buttons": "^1.4.7", - "@types/datatables.net-scroller": "^1.4.1", - "@types/google.maps": "^3.45.6", - "@types/jquery": "^3.5.7", - "@types/jqueryui": "^1.12.16", - "@types/node": "^17.0.18", - "@types/tmi.js": "^1.8.0", - "@types/when-dom-ready": "^1.2.0", - "electron": "^22.0.3", - "parcel": "^2.0.0", - "typescript": "^4.4.4", - "vitest": "^0.34.2", - "vue-tsc": "^1.2.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@electron-forge/cli": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-6.0.5.tgz", - "integrity": "sha512-3xD4XKyV634cQCR8HobpVnb4LqVdTHDs+KwsU9zgjaBIJMBapCS3ZzpXYbxzPekTaVwu39ojMUg990JVYBhs2A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-cli?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "@electron-forge/core": "6.0.5", - "@electron-forge/shared-types": "6.0.5", - "@electron/get": "^2.0.0", - "chalk": "^4.0.0", - "commander": "^4.1.1", - "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "listr2": "^5.0.3", - "semver": "^7.2.1" - }, - "bin": { - "electron-forge": "dist/electron-forge.js", - "electron-forge-vscode-nix": "script/vscode.sh", - "electron-forge-vscode-win": "script/vscode.cmd" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/core": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-6.0.5.tgz", - "integrity": "sha512-lMtm3x2ZFEBOU7/JTIo2oI5dXm2hKqpdc4opHA7iOxja5YYDDvnqKt+tACJSCdnCOxYLS+0OSoaz/DJ8SNyStw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-core?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "@electron-forge/core-utils": "6.0.5", - "@electron-forge/maker-base": "6.0.5", - "@electron-forge/plugin-base": "6.0.5", - "@electron-forge/publisher-base": "6.0.5", - "@electron-forge/shared-types": "6.0.5", - "@electron-forge/template-base": "6.0.5", - "@electron-forge/template-webpack": "6.0.5", - "@electron-forge/template-webpack-typescript": "6.0.5", - "@electron/get": "^2.0.0", - "@electron/rebuild": "^3.2.10", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.3.1", - "electron-packager": "^17.1.1", - "fast-glob": "^3.2.7", - "filenamify": "^4.1.0", - "find-up": "^5.0.0", - "fs-extra": "^10.0.0", - "got": "^11.8.5", - "interpret": "^3.1.1", - "listr2": "^5.0.3", - "lodash": "^4.17.20", - "log-symbols": "^4.0.0", - "node-fetch": "^2.6.7", - "progress": "^2.0.3", - "rechoir": "^0.8.0", - "resolve-package": "^1.0.1", - "semver": "^7.2.1", - "source-map-support": "^0.5.13", - "sudo-prompt": "^9.1.1", - "username": "^5.1.0", - "yarn-or-npm": "^3.0.1" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/core-utils": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-6.0.5.tgz", - "integrity": "sha512-KCxTQOGRGITUwdxMu63xFn4SkuBE6Fvn188MjZHyztAHimiKBWdNGBrBHgjR2WyYTziT8y6JXcAntAW5d+jYHQ==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5", - "@electron/rebuild": "^3.2.10", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.3.1", - "find-up": "^5.0.0", - "fs-extra": "^10.0.0", - "log-symbols": "^4.0.0", - "semver": "^7.2.1", - "yarn-or-npm": "^3.0.1" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/maker-base": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-6.0.5.tgz", - "integrity": "sha512-m3xS/Gd2XlYUjXO4o8bxZEcwN9AulMDjuIzq68FRH5VB1vuESJKtVZjSa331IjaA+0aRXbSCa108FLy8g5Qlaw==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5", - "fs-extra": "^10.0.0", - "which": "^2.0.2" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/maker-deb": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-6.0.5.tgz", - "integrity": "sha512-uaDxBeLhJcrySnPGPEZbGwJG7qeiBE05+rdkPpsfHzsTBYca1abQ2Ll66R5EmOrosIZv60OUt1eGyxOrWlo1+w==", - "dev": true, - "dependencies": { - "@electron-forge/maker-base": "6.0.5", - "@electron-forge/shared-types": "6.0.5" - }, - "engines": { - "node": ">= 14.17.5" - }, - "optionalDependencies": { - "electron-installer-debian": "^3.0.0" - } - }, - "node_modules/@electron-forge/maker-squirrel": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-6.0.5.tgz", - "integrity": "sha512-moP4OIytJlqxx3J7UCWrOv04tepjQIzK9RdzK4m9jfjPAxZtRObesFGXr/jLO18NHXk7fDcbYLf3sTIfaPU6jg==", - "dev": true, - "dependencies": { - "@electron-forge/maker-base": "6.0.5", - "@electron-forge/shared-types": "6.0.5", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 14.17.5" - }, - "optionalDependencies": { - "electron-winstaller": "^5.0.0" - } - }, - "node_modules/@electron-forge/maker-zip": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-6.0.5.tgz", - "integrity": "sha512-Yg256nGQUWT35EZyRIALpgtdM8WSvgZc0O4aA6Wy0S6ektaxyM2a+tO2ug/Vl+RgYA6oIeAADfkU2RxLiGnhbA==", - "dev": true, - "dependencies": { - "@electron-forge/maker-base": "6.0.5", - "@electron-forge/shared-types": "6.0.5", - "cross-zip": "^4.0.0", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/plugin-base": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-6.0.5.tgz", - "integrity": "sha512-Q2ywNq6Qzb9K1W59qzbJvI+NZaDPrHz7iq9W8UfyHoEDYLJsD368PzHtNaQFJx+ofZNgsSpukXoL9mGvN1lVbA==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/publisher-base": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-6.0.5.tgz", - "integrity": "sha512-gwOaMC3RKPO1mq3dqP9ko8kJptO41XU+I+pM66W/wvCNIQzisFCqrsx3d8A9RWsMJug0I1xNsYdBt99j1/2haA==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/publisher-github": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/publisher-github/-/publisher-github-6.0.5.tgz", - "integrity": "sha512-jrIkOTfIGiqTpu+IF7zBNIbOXrQQFp3cgoT/NEHKIjSsMznw+lMbQEEV7ue3G8OXtKeADbH23Jl3CzJeyLWxag==", - "dev": true, - "dependencies": { - "@electron-forge/publisher-base": "6.0.5", - "@electron-forge/shared-types": "6.0.5", - "@octokit/core": "^3.2.4", - "@octokit/plugin-retry": "^3.0.9", - "@octokit/rest": "^18.0.11", - "@octokit/types": "^6.1.2", - "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "mime-types": "^2.1.25" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/shared-types": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-6.0.5.tgz", - "integrity": "sha512-FrJI11afw/Cxk0JwgWyKg9aPoHOdmMi4JHTY6pnmi95MjarQ1d0SIqKJUzX7q2lXPUAxqPKA2Wmykg6F2CThlg==", - "dev": true, - "dependencies": { - "@electron/rebuild": "^3.2.10", - "electron-packager": "^17.1.1", - "listr2": "^5.0.3" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/template-base": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-6.0.5.tgz", - "integrity": "sha512-/3nOKPltnL8nVdZS2EpnKx1VMBqgLjW8TLRt8vtc+WdHtCVJBiU1Pt0JxTYDM3Raq/CclWGqVFb1svqorAon7Q==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5", - "@malept/cross-spawn-promise": "^2.0.0", - "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "username": "^5.1.0" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/template-webpack": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-6.0.5.tgz", - "integrity": "sha512-fDINYYCJ3D8rMYgS5tTHhgC8d73pRpQKtyBCQFC9KkfdNMYJr9MPZeep5pYQqrOMjSgBpgaYSBL9Unsa5I1F2g==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5", - "@electron-forge/template-base": "6.0.5", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron-forge/template-webpack-typescript": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-6.0.5.tgz", - "integrity": "sha512-YjKVszYRT4S3Sw3AOEpJokU7KPpmr0HWuO14+WHMO0FhQ1gaTMfPoz6QRHg0F1Ulz73mm6b3MLb9ID5igZv7Mw==", - "dev": true, - "dependencies": { - "@electron-forge/shared-types": "6.0.5", - "@electron-forge/template-base": "6.0.5", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron/asar": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.3.tgz", - "integrity": "sha512-wmOfE6szYyqZhRIiLH+eyZEp+bGcJI0OD/SCvSUrfBE0jvauyGYO2ZhpWxmNCcDojKu5DYrsVqT5BOCZZ01XIg==", - "dev": true, - "dependencies": { - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - }, - "optionalDependencies": { - "@types/glob": "^7.1.1" - } - }, - "node_modules/@electron/asar/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@electron/get": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", - "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@electron/get/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@electron/get/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@electron/get/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/@electron/notarize": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.3.tgz", - "integrity": "sha512-9oRzT56rKh5bspk3KpAVF8lPKHYQrBnRwcgiOeR0hdilVEQmszDaAu0IPCPrwwzJN0ugNs0rRboTreHMt/6mBQ==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/osx-sign": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", - "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", - "dev": true, - "dependencies": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, - "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@electron/rebuild": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz", - "integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==", - "dev": true, - "dependencies": { - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "lzma-native": "^8.0.5", - "node-abi": "^3.0.0", - "node-api-version": "^0.1.4", - "node-gyp": "^9.0.0", - "ora": "^5.1.0", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/src/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/universal": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", - "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", - "dev": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", - "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@electron/universal/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@lezer/common": { - "version": "0.15.12", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", - "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==", - "dev": true - }, - "node_modules/@lezer/lr": { - "version": "0.15.8", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", - "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", - "dev": true, - "dependencies": { - "@lezer/common": "^0.15.0" - } - }, - "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", - "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", - "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", - "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", - "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", - "integrity": "sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-win32-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", - "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@malept/cross-spawn-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", - "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/@mischnic/json-sourcemap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz", - "integrity": "sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==", - "dev": true, - "dependencies": { - "@lezer/common": "^0.15.7", - "@lezer/lr": "^0.15.4", - "json5": "^2.2.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz", - "integrity": "sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz", - "integrity": "sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz", - "integrity": "sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz", - "integrity": "sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz", - "integrity": "sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz", - "integrity": "sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3" - } - }, - "node_modules/@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", - "dev": true, - "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dev": true, - "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", - "dev": true - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.21.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", - "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.40.0" - }, - "peerDependencies": { - "@octokit/core": ">=2" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", - "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.39.0", - "deprecation": "^2.3.1" - }, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-retry": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz", - "integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3", - "bottleneck": "^2.15.3" - } - }, - "node_modules/@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "dev": true, - "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dev": true, - "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/rest": { - "version": "18.12.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", - "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", - "dev": true, - "dependencies": { - "@octokit/core": "^3.5.1", - "@octokit/plugin-paginate-rest": "^2.16.8", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^5.12.0" - } - }, - "node_modules/@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", - "dev": true, - "dependencies": { - "@octokit/openapi-types": "^12.11.0" - } - }, - "node_modules/@osm_borders/maritime_10m": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@osm_borders/maritime_10m/-/maritime_10m-1.1.0.tgz", - "integrity": "sha512-Mln0gqbYzjqNX7iGtEt3np16nfGwjwADTuUg7J5LQTqlqUBDxsWaxQmsKtkJCumvc/pl7QZu8lvEs41JMs+zbQ==" - }, - "node_modules/@parcel/bundler-default": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.8.3.tgz", - "integrity": "sha512-yJvRsNWWu5fVydsWk3O2L4yIy3UZiKWO2cPDukGOIWMgp/Vbpp+2Ct5IygVRtE22bnseW/E/oe0PV3d2IkEJGg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/graph": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/cache": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/cache/-/cache-2.8.3.tgz", - "integrity": "sha512-k7xv5vSQrJLdXuglo+Hv3yF4BCSs1tQ/8Vbd6CHTkOhf7LcGg6CPtLw053R/KdMpd/4GPn0QrAsOLdATm1ELtQ==", - "dev": true, - "dependencies": { - "@parcel/fs": "2.8.3", - "@parcel/logger": "2.8.3", - "@parcel/utils": "2.8.3", - "lmdb": "2.5.2" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@parcel/codeframe": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/codeframe/-/codeframe-2.8.3.tgz", - "integrity": "sha512-FE7sY53D6n/+2Pgg6M9iuEC6F5fvmyBkRE4d9VdnOoxhTXtkEqpqYgX7RJ12FAQwNlxKq4suBJQMgQHMF2Kjeg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/compressor-raw": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/compressor-raw/-/compressor-raw-2.8.3.tgz", - "integrity": "sha512-bVDsqleBUxRdKMakWSlWC9ZjOcqDKE60BE+Gh3JSN6WJrycJ02P5wxjTVF4CStNP/G7X17U+nkENxSlMG77ySg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/config-default": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/config-default/-/config-default-2.8.3.tgz", - "integrity": "sha512-o/A/mbrO6X/BfGS65Sib8d6SSG45NYrNooNBkH/o7zbOBSRQxwyTlysleK1/3Wa35YpvFyLOwgfakqCtbGy4fw==", - "dev": true, - "dependencies": { - "@parcel/bundler-default": "2.8.3", - "@parcel/compressor-raw": "2.8.3", - "@parcel/namer-default": "2.8.3", - "@parcel/optimizer-css": "2.8.3", - "@parcel/optimizer-htmlnano": "2.8.3", - "@parcel/optimizer-image": "2.8.3", - "@parcel/optimizer-svgo": "2.8.3", - "@parcel/optimizer-terser": "2.8.3", - "@parcel/packager-css": "2.8.3", - "@parcel/packager-html": "2.8.3", - "@parcel/packager-js": "2.8.3", - "@parcel/packager-raw": "2.8.3", - "@parcel/packager-svg": "2.8.3", - "@parcel/reporter-dev-server": "2.8.3", - "@parcel/resolver-default": "2.8.3", - "@parcel/runtime-browser-hmr": "2.8.3", - "@parcel/runtime-js": "2.8.3", - "@parcel/runtime-react-refresh": "2.8.3", - "@parcel/runtime-service-worker": "2.8.3", - "@parcel/transformer-babel": "2.8.3", - "@parcel/transformer-css": "2.8.3", - "@parcel/transformer-html": "2.8.3", - "@parcel/transformer-image": "2.8.3", - "@parcel/transformer-js": "2.8.3", - "@parcel/transformer-json": "2.8.3", - "@parcel/transformer-postcss": "2.8.3", - "@parcel/transformer-posthtml": "2.8.3", - "@parcel/transformer-raw": "2.8.3", - "@parcel/transformer-react-refresh-wrap": "2.8.3", - "@parcel/transformer-svg": "2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@parcel/core": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.8.3.tgz", - "integrity": "sha512-Euf/un4ZAiClnlUXqPB9phQlKbveU+2CotZv7m7i+qkgvFn5nAGnrV4h1OzQU42j9dpgOxWi7AttUDMrvkbhCQ==", - "dev": true, - "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", - "@parcel/cache": "2.8.3", - "@parcel/diagnostic": "2.8.3", - "@parcel/events": "2.8.3", - "@parcel/fs": "2.8.3", - "@parcel/graph": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/logger": "2.8.3", - "@parcel/package-manager": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "@parcel/workers": "2.8.3", - "abortcontroller-polyfill": "^1.1.9", - "base-x": "^3.0.8", - "browserslist": "^4.6.6", - "clone": "^2.1.1", - "dotenv": "^7.0.0", - "dotenv-expand": "^5.1.0", - "json5": "^2.2.0", - "msgpackr": "^1.5.4", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/core/node_modules/dotenv": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz", - "integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@parcel/core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/diagnostic": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/diagnostic/-/diagnostic-2.8.3.tgz", - "integrity": "sha512-u7wSzuMhLGWZjVNYJZq/SOViS3uFG0xwIcqXw12w54Uozd6BH8JlhVtVyAsq9kqnn7YFkw6pXHqAo5Tzh4FqsQ==", - "dev": true, - "dependencies": { - "@mischnic/json-sourcemap": "^0.1.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/events": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/events/-/events-2.8.3.tgz", - "integrity": "sha512-hoIS4tAxWp8FJk3628bsgKxEvR7bq2scCVYHSqZ4fTi/s0+VymEATrRCUqf+12e5H47uw1/ZjoqrGtBI02pz4w==", - "dev": true, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/fs": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-2.8.3.tgz", - "integrity": "sha512-y+i+oXbT7lP0e0pJZi/YSm1vg0LDsbycFuHZIL80pNwdEppUAtibfJZCp606B7HOjMAlNZOBo48e3hPG3d8jgQ==", - "dev": true, - "dependencies": { - "@parcel/fs-search": "2.8.3", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "@parcel/watcher": "^2.0.7", - "@parcel/workers": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@parcel/fs-search": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/fs-search/-/fs-search-2.8.3.tgz", - "integrity": "sha512-DJBT2N8knfN7Na6PP2mett3spQLTqxFrvl0gv+TJRp61T8Ljc4VuUTb0hqBj+belaASIp3Q+e8+SgaFQu7wLiQ==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/fs-search/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@parcel/graph": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/graph/-/graph-2.8.3.tgz", - "integrity": "sha512-26GL8fYZPdsRhSXCZ0ZWliloK6DHlMJPWh6Z+3VVZ5mnDSbYg/rRKWmrkhnr99ZWmL9rJsv4G74ZwvDEXTMPBg==", - "dev": true, - "dependencies": { - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/hash": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/hash/-/hash-2.8.3.tgz", - "integrity": "sha512-FVItqzjWmnyP4ZsVgX+G00+6U2IzOvqDtdwQIWisCcVoXJFCqZJDy6oa2qDDFz96xCCCynjRjPdQx2jYBCpfYw==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3", - "xxhash-wasm": "^0.4.2" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/hash/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@parcel/logger": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-2.8.3.tgz", - "integrity": "sha512-Kpxd3O/Vs7nYJIzkdmB6Bvp3l/85ydIxaZaPfGSGTYOfaffSOTkhcW9l6WemsxUrlts4za6CaEWcc4DOvaMOPA==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/events": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/markdown-ansi": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/markdown-ansi/-/markdown-ansi-2.8.3.tgz", - "integrity": "sha512-4v+pjyoh9f5zuU/gJlNvNFGEAb6J90sOBwpKJYJhdWXLZMNFCVzSigxrYO+vCsi8G4rl6/B2c0LcwIMjGPHmFQ==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/namer-default": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/namer-default/-/namer-default-2.8.3.tgz", - "integrity": "sha512-tJ7JehZviS5QwnxbARd8Uh63rkikZdZs1QOyivUhEvhN+DddSAVEdQLHGPzkl3YRk0tjFhbqo+Jci7TpezuAMw==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/node-resolver-core": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/node-resolver-core/-/node-resolver-core-2.8.3.tgz", - "integrity": "sha512-12YryWcA5Iw2WNoEVr/t2HDjYR1iEzbjEcxfh1vaVDdZ020PiGw67g5hyIE/tsnG7SRJ0xdRx1fQ2hDgED+0Ww==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/node-resolver-core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/optimizer-css": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-css/-/optimizer-css-2.8.3.tgz", - "integrity": "sha512-JotGAWo8JhuXsQDK0UkzeQB0UR5hDAKvAviXrjqB4KM9wZNLhLleeEAW4Hk8R9smCeQFP6Xg/N/NkLDpqMwT3g==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "browserslist": "^4.6.6", - "lightningcss": "^1.16.1", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-htmlnano": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.8.3.tgz", - "integrity": "sha512-L8/fHbEy8Id2a2E0fwR5eKGlv9VYDjrH9PwdJE9Za9v1O/vEsfl/0T/79/x129l5O0yB6EFQkFa20MiK3b+vOg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "htmlnano": "^2.0.0", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "svgo": "^2.4.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-image": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-image/-/optimizer-image-2.8.3.tgz", - "integrity": "sha512-SD71sSH27SkCDNUNx9A3jizqB/WIJr3dsfp+JZGZC42tpD/Siim6Rqy9M4To/BpMMQIIiEXa5ofwS+DgTEiEHQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "@parcel/workers": "2.8.3", - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-image/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@parcel/optimizer-svgo": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-svgo/-/optimizer-svgo-2.8.3.tgz", - "integrity": "sha512-9KQed99NZnQw3/W4qBYVQ7212rzA9EqrQG019TIWJzkA9tjGBMIm2c/nXpK1tc3hQ3e7KkXkFCQ3C+ibVUnHNA==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "svgo": "^2.4.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/optimizer-terser": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/optimizer-terser/-/optimizer-terser-2.8.3.tgz", - "integrity": "sha512-9EeQlN6zIeUWwzrzu6Q2pQSaYsYGah8MtiQ/hog9KEPlYTP60hBv/+utDyYEHSQhL7y5ym08tPX5GzBvwAD/dA==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1", - "terser": "^5.2.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/package-manager": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/package-manager/-/package-manager-2.8.3.tgz", - "integrity": "sha512-tIpY5pD2lH53p9hpi++GsODy6V3khSTX4pLEGuMpeSYbHthnOViobqIlFLsjni+QA1pfc8NNNIQwSNdGjYflVA==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/fs": "2.8.3", - "@parcel/logger": "2.8.3", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "@parcel/workers": "2.8.3", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@parcel/package-manager/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/packager-css": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/packager-css/-/packager-css-2.8.3.tgz", - "integrity": "sha512-WyvkMmsurlHG8d8oUVm7S+D+cC/T3qGeqogb7sTI52gB6uiywU7lRCizLNqGFyFGIxcVTVHWnSHqItBcLN76lA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-html": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/packager-html/-/packager-html-2.8.3.tgz", - "integrity": "sha512-OhPu1Hx1RRKJodpiu86ZqL8el2Aa4uhBHF6RAL1Pcrh2EhRRlPf70Sk0tC22zUpYL7es+iNKZ/n0Rl+OWSHWEw==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-js": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/packager-js/-/packager-js-2.8.3.tgz", - "integrity": "sha512-0pGKC3Ax5vFuxuZCRB+nBucRfFRz4ioie19BbDxYnvBxrd4M3FIu45njf6zbBYsI9eXqaDnL1b3DcZJfYqtIzw==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "globals": "^13.2.0", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-js/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@parcel/packager-js/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@parcel/packager-raw": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.8.3.tgz", - "integrity": "sha512-BA6enNQo1RCnco9MhkxGrjOk59O71IZ9DPKu3lCtqqYEVd823tXff2clDKHK25i6cChmeHu6oB1Rb73hlPqhUA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/packager-svg": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/packager-svg/-/packager-svg-2.8.3.tgz", - "integrity": "sha512-mvIoHpmv5yzl36OjrklTDFShLUfPFTwrmp1eIwiszGdEBuQaX7JVI3Oo2jbVQgcN4W7J6SENzGQ3Q5hPTW3pMw==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "posthtml": "^0.16.4" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/plugin": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/plugin/-/plugin-2.8.3.tgz", - "integrity": "sha512-jZ6mnsS4D9X9GaNnvrixDQwlUQJCohDX2hGyM0U0bY2NWU8Km97SjtoCpWjq+XBCx/gpC4g58+fk9VQeZq2vlw==", - "dev": true, - "dependencies": { - "@parcel/types": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/reporter-cli": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/reporter-cli/-/reporter-cli-2.8.3.tgz", - "integrity": "sha512-3sJkS6tFFzgIOz3u3IpD/RsmRxvOKKiQHOTkiiqRt1l44mMDGKS7zANRnJYsQzdCsgwc9SOP30XFgJwtoVlMbw==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "chalk": "^4.1.0", - "term-size": "^2.2.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/reporter-dev-server": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/reporter-dev-server/-/reporter-dev-server-2.8.3.tgz", - "integrity": "sha512-Y8C8hzgzTd13IoWTj+COYXEyCkXfmVJs3//GDBsH22pbtSFMuzAZd+8J9qsCo0EWpiDow7V9f1LischvEh3FbQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/resolver-default": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/resolver-default/-/resolver-default-2.8.3.tgz", - "integrity": "sha512-k0B5M/PJ+3rFbNj4xZSBr6d6HVIe6DH/P3dClLcgBYSXAvElNDfXgtIimbjCyItFkW9/BfcgOVKEEIZOeySH/A==", - "dev": true, - "dependencies": { - "@parcel/node-resolver-core": "2.8.3", - "@parcel/plugin": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-browser-hmr": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.8.3.tgz", - "integrity": "sha512-2O1PYi2j/Q0lTyGNV3JdBYwg4rKo6TEVFlYGdd5wCYU9ZIN9RRuoCnWWH2qCPj3pjIVtBeppYxzfVjPEHINWVg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-js": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/runtime-js/-/runtime-js-2.8.3.tgz", - "integrity": "sha512-IRja0vNKwvMtPgIqkBQh0QtRn0XcxNC8HU1jrgWGRckzu10qJWO+5ULgtOeR4pv9krffmMPqywGXw6l/gvJKYQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-react-refresh": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.8.3.tgz", - "integrity": "sha512-2v/qFKp00MfG0234OdOgQNAo6TLENpFYZMbVbAsPMY9ITiqG73MrEsrGXVoGbYiGTMB/Toer/lSWlJxtacOCuA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "react-error-overlay": "6.0.9", - "react-refresh": "^0.9.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/runtime-service-worker": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/runtime-service-worker/-/runtime-service-worker-2.8.3.tgz", - "integrity": "sha512-/Skkw+EeRiwzOJso5fQtK8c9b452uWLNhQH1ISTodbmlcyB4YalAiSsyHCtMYD0c3/t5Sx4ZS7vxBAtQd0RvOw==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/source-map": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@parcel/source-map/-/source-map-2.1.1.tgz", - "integrity": "sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": "^12.18.3 || >=14" - } - }, - "node_modules/@parcel/source-map/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@parcel/transformer-babel": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-babel/-/transformer-babel-2.8.3.tgz", - "integrity": "sha512-L6lExfpvvC7T/g3pxf3CIJRouQl+sgrSzuWQ0fD4PemUDHvHchSP4SNUVnd6gOytF3Y1KpnEZIunQGi5xVqQCQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "browserslist": "^4.6.6", - "json5": "^2.2.0", - "nullthrows": "^1.1.1", - "semver": "^5.7.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-babel/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/transformer-css": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-css/-/transformer-css-2.8.3.tgz", - "integrity": "sha512-xTqFwlSXtnaYen9ivAgz+xPW7yRl/u4QxtnDyDpz5dr8gSeOpQYRcjkd4RsYzKsWzZcGtB5EofEk8ayUbWKEUg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "browserslist": "^4.6.6", - "lightningcss": "^1.16.1", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-html": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-html/-/transformer-html-2.8.3.tgz", - "integrity": "sha512-kIZO3qsMYTbSnSpl9cnZog+SwL517ffWH54JeB410OSAYF1ouf4n5v9qBnALZbuCCmPwJRGs4jUtE452hxwN4g==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/plugin": "2.8.3", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1", - "srcset": "4" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-html/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/transformer-image": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-image/-/transformer-image-2.8.3.tgz", - "integrity": "sha512-cO4uptcCGTi5H6bvTrAWEFUsTNhA4kCo8BSvRSCHA2sf/4C5tGQPHt3JhdO0GQLPwZRCh/R41EkJs5HZ8A8DAg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "@parcel/workers": "2.8.3", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@parcel/transformer-inline-string": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-inline-string/-/transformer-inline-string-2.8.3.tgz", - "integrity": "sha512-TBMk2H9nV8JMOsLztalhzS6HgthG5SCHKYkR2MaW7eSZuSGotbSP22aJip8HgQZ/lPMdOMb1lknHmd8WROxWHg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-js": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-js/-/transformer-js-2.8.3.tgz", - "integrity": "sha512-9Qd6bib+sWRcpovvzvxwy/PdFrLUXGfmSW9XcVVG8pvgXsZPFaNjnNT8stzGQj1pQiougCoxMY4aTM5p1lGHEQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "@parcel/workers": "2.8.3", - "@swc/helpers": "^0.4.12", - "browserslist": "^4.6.6", - "detect-libc": "^1.0.3", - "nullthrows": "^1.1.1", - "regenerator-runtime": "^0.13.7", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@parcel/transformer-js/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@parcel/transformer-js/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/transformer-json": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-json/-/transformer-json-2.8.3.tgz", - "integrity": "sha512-B7LmVq5Q7bZO4ERb6NHtRuUKWGysEeaj9H4zelnyBv+wLgpo4f5FCxSE1/rTNmP9u1qHvQ3scGdK6EdSSokGPg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "json5": "^2.2.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-postcss": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-postcss/-/transformer-postcss-2.8.3.tgz", - "integrity": "sha512-e8luB/poIlz6jBsD1Izms+6ElbyzuoFVa4lFVLZnTAChI3UxPdt9p/uTsIO46HyBps/Bk8ocvt3J4YF84jzmvg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "clone": "^2.1.1", - "nullthrows": "^1.1.1", - "postcss-value-parser": "^4.2.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-postcss/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/transformer-posthtml": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-posthtml/-/transformer-posthtml-2.8.3.tgz", - "integrity": "sha512-pkzf9Smyeaw4uaRLsT41RGrPLT5Aip8ZPcntawAfIo+KivBQUV0erY1IvHYjyfFzq1ld/Fo2Ith9He6mxpPifA==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-posthtml/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/transformer-raw": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-raw/-/transformer-raw-2.8.3.tgz", - "integrity": "sha512-G+5cXnd2/1O3nV/pgRxVKZY/HcGSseuhAe71gQdSQftb8uJEURyUHoQ9Eh0JUD3MgWh9V+nIKoyFEZdf9T0sUQ==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-react-refresh-wrap": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.8.3.tgz", - "integrity": "sha512-q8AAoEvBnCf/nPvgOwFwKZfEl/thwq7c2duxXkhl+tTLDRN2vGmyz4355IxCkavSX+pLWSQ5MexklSEeMkgthg==", - "dev": true, - "dependencies": { - "@parcel/plugin": "2.8.3", - "@parcel/utils": "2.8.3", - "react-refresh": "^0.9.0" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-svg": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-svg/-/transformer-svg-2.8.3.tgz", - "integrity": "sha512-3Zr/gBzxi1ZH1fftH/+KsZU7w5GqkmxlB0ZM8ovS5E/Pl1lq1t0xvGJue9m2VuQqP8Mxfpl5qLFmsKlhaZdMIQ==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/plugin": "2.8.3", - "nullthrows": "^1.1.1", - "posthtml": "^0.16.5", - "posthtml-parser": "^0.10.1", - "posthtml-render": "^3.0.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-svg/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/transformer-vue": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/transformer-vue/-/transformer-vue-2.8.3.tgz", - "integrity": "sha512-GinydFphIuoNZJT7LxFE1mWddcacnQSBXEqnNXad3M9sWpiTSpkiIw5sCbfF4//J9UX8d5FrFB9aECATdkkk5w==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/plugin": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/utils": "2.8.3", - "@vue/compiler-sfc": "^3.2.27", - "consolidate": "^0.16.0", - "nullthrows": "^1.1.1", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.8.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/transformer-vue/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@parcel/types": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/types/-/types-2.8.3.tgz", - "integrity": "sha512-FECA1FB7+0UpITKU0D6TgGBpGxYpVSMNEENZbSJxFSajNy3wrko+zwBKQmFOLOiPcEtnGikxNs+jkFWbPlUAtw==", - "dev": true, - "dependencies": { - "@parcel/cache": "2.8.3", - "@parcel/diagnostic": "2.8.3", - "@parcel/fs": "2.8.3", - "@parcel/package-manager": "2.8.3", - "@parcel/source-map": "^2.1.1", - "@parcel/workers": "2.8.3", - "utility-types": "^3.10.0" - } - }, - "node_modules/@parcel/utils": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-2.8.3.tgz", - "integrity": "sha512-IhVrmNiJ+LOKHcCivG5dnuLGjhPYxQ/IzbnF2DKNQXWBTsYlHkJZpmz7THoeLtLliGmSOZ3ZCsbR8/tJJKmxjA==", - "dev": true, - "dependencies": { - "@parcel/codeframe": "2.8.3", - "@parcel/diagnostic": "2.8.3", - "@parcel/hash": "2.8.3", - "@parcel/logger": "2.8.3", - "@parcel/markdown-ansi": "2.8.3", - "@parcel/source-map": "^2.1.1", - "chalk": "^4.1.0" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.1.0.tgz", - "integrity": "sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^3.2.1", - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/workers": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.8.3.tgz", - "integrity": "sha512-+AxBnKgjqVpUHBcHLWIHcjYgKIvHIpZjN33mG5LG9XXvrZiqdWvouEzqEXlVLq5VzzVbKIQQcmsvRy138YErkg==", - "dev": true, - "dependencies": { - "@parcel/diagnostic": "2.8.3", - "@parcel/logger": "2.8.3", - "@parcel/types": "2.8.3", - "@parcel/utils": "2.8.3", - "chrome-trace-event": "^1.0.2", - "nullthrows": "^1.1.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "peerDependencies": { - "@parcel/core": "^2.8.3" - } - }, - "node_modules/@sentry/browser": { - "version": "7.37.1", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.37.1.tgz", - "integrity": "sha512-MfVbKzEVHKVH6ZyMCKLtPXvMtRCvxqQzrnK735sYW6EyMpcMYhukBU0pq7ws1E/KaCZjAJi1wDx2nqf2yPIVdQ==", - "dependencies": { - "@sentry/core": "7.37.1", - "@sentry/replay": "7.37.1", - "@sentry/types": "7.37.1", - "@sentry/utils": "7.37.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/browser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/core": { - "version": "7.37.1", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.37.1.tgz", - "integrity": "sha512-eS5hoFDjAOl7POZg6K77J0oiypiqR1782oVSB49UkjK+D8tCZzZ5PxPMv0b/O0310p7x4oZ3WGRJaWEN3vY4KQ==", - "dependencies": { - "@sentry/types": "7.37.1", - "@sentry/utils": "7.37.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/electron": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@sentry/electron/-/electron-4.3.0.tgz", - "integrity": "sha512-LqFMvgycMd+Mcs4Km9S8YBtaHISHSiIUVUz6mgAr2khKY6SNhkW9A4GcoOKtzRJreqYLVeBSbaUVttQfQ4Ot7g==", - "dependencies": { - "@sentry/browser": "7.37.1", - "@sentry/core": "7.37.1", - "@sentry/node": "7.37.1", - "@sentry/types": "7.37.1", - "@sentry/utils": "7.37.1", - "deepmerge": "4.3.0", - "tslib": "^2.5.0" - } - }, - "node_modules/@sentry/node": { - "version": "7.37.1", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.37.1.tgz", - "integrity": "sha512-nGerngIo5JwinJgl7m0SaL/xI+YRBlhb53gbkuLSAAcnoitBFzbp7LjywsqYFTWuWDIyk7O2t124GNxtolBAgA==", - "dependencies": { - "@sentry/core": "7.37.1", - "@sentry/types": "7.37.1", - "@sentry/utils": "7.37.1", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sentry/replay": { - "version": "7.37.1", - "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.37.1.tgz", - "integrity": "sha512-3sHOE/oPirdvJbOn0IA/wpds12Sm2WaEtiAeC0+5Gg5mxQzFBLRrsA1Mz/ifzPGwr+ETn3sCyPCnd9b3PWaWMQ==", - "dependencies": { - "@sentry/core": "7.37.1", - "@sentry/types": "7.37.1", - "@sentry/utils": "7.37.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@sentry/types": { - "version": "7.37.1", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.37.1.tgz", - "integrity": "sha512-c2HWyWSgVA0V4+DSW2qVb0yjftrb1X/q2CzCom+ayjGHO72qyWC+9Tc+7ZfotU1mapRjqUWBgkXkbGmao8N8Ug==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.37.1", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.37.1.tgz", - "integrity": "sha512-/4mJOyDsfysx+5TXyJgSI+Ihw2/0EVJbrHjCyXPDXW5ADwbtU8VdBZ0unOmF0hk4QfftqwM9cyEu3BN4iBJsEA==", - "dependencies": { - "@sentry/types": "7.37.1", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" - }, - "node_modules/@supabase/functions-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.1.0.tgz", - "integrity": "sha512-vRziB+AqRXRaGHjEFHwBo0kuNDTuAxI7VUeqU24Fe86ISoD8YEQm0dGdpleJEcqgDGWaO6pxT1tfj1BRY5PwMg==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/gotrue-js": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-2.13.0.tgz", - "integrity": "sha512-NFBHuHNUn94mP/zOQzsp1k2PtwV55Vhf6ZbTzmMpiUvIRlXhVteZcdfdoAQDIBrdxOdL7F54NFp1gIupPZka6g==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/postgrest-js": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.4.1.tgz", - "integrity": "sha512-aruqwV/aTggkM7OVv2JinCeXmRMKHJCZpkuS1nuoa0NgLw7g3NyILSyWOKYTBJ/PxE/zXtWsBhdxFzaaNz5uxg==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/realtime-js": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.6.0.tgz", - "integrity": "sha512-tOVulMobhpxyDuu8VIImpL8FXmZOKsGNOSyS5ihJdj2xYmPPvYG+D2J51Ewfl+MFF65tweiB6p9N9bNIW1cDNA==", - "dependencies": { - "@types/phoenix": "^1.5.4", - "websocket": "^1.0.34" - } - }, - "node_modules/@supabase/storage-js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.3.1.tgz", - "integrity": "sha512-BaPIvyvjuZW1V0CnfGKUZyzpBUXnsh0XD8eqTOYd+MdiGPmIPI0vtwnT4fAoK8mipp1vpcN62EVQaqeUnWXPtQ==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/supabase-js": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.10.0.tgz", - "integrity": "sha512-/vkpPxGDyLfTASWnVHL8vdgQxn9SX/Cs+BotTxFhLSIeGFSazC6rpQSMKu6RqzO7gjBD1KqTv0h3auWfClWs+Q==", - "dependencies": { - "@supabase/functions-js": "^2.1.0", - "@supabase/gotrue-js": "^2.12.0", - "@supabase/postgrest-js": "^1.1.1", - "@supabase/realtime-js": "^2.4.0", - "@supabase/storage-js": "^2.3.1", - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "node_modules/@turf/bbox": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-6.5.0.tgz", - "integrity": "sha512-RBbLaao5hXTYyyg577iuMtDB8ehxMlUqHEJiMs8jT1GHkFhr6sYre3lmLsPeYEi/ZKj5TP5tt7fkzNdJ4GIVyw==", - "dependencies": { - "@turf/helpers": "^6.5.0", - "@turf/meta": "^6.5.0" - }, - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@turf/boolean-contains": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-6.5.0.tgz", - "integrity": "sha512-4m8cJpbw+YQcKVGi8y0cHhBUnYT+QRfx6wzM4GI1IdtYH3p4oh/DOBJKrepQyiDzFDaNIjxuWXBh0ai1zVwOQQ==", - "dependencies": { - "@turf/bbox": "^6.5.0", - "@turf/boolean-point-in-polygon": "^6.5.0", - "@turf/boolean-point-on-line": "^6.5.0", - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - }, - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@turf/boolean-point-in-polygon": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz", - "integrity": "sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==", - "dependencies": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - }, - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@turf/boolean-point-on-line": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-6.5.0.tgz", - "integrity": "sha512-A1BbuQ0LceLHvq7F/P7w3QvfpmZqbmViIUPHdNLvZimFNLo4e6IQunmzbe+8aSStH9QRZm3VOflyvNeXvvpZEQ==", - "dependencies": { - "@turf/helpers": "^6.5.0", - "@turf/invariant": "^6.5.0" - }, - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@turf/helpers": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", - "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@turf/invariant": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", - "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", - "dependencies": { - "@turf/helpers": "^6.5.0" - }, - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@turf/meta": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-6.5.0.tgz", - "integrity": "sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA==", - "dependencies": { - "@turf/helpers": "^6.5.0" - }, - "funding": { - "url": "https://opencollective.com/turf" - } - }, - "node_modules/@types/better-sqlite3": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.3.tgz", - "integrity": "sha512-YS64N9SNDT/NAvou3QNdzAu3E2om/W/0dhORimtPGLef+zSK5l1vDzfsWb4xgXOgfhtOI5ZDTRxnvRPb22AIVQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", - "dev": true - }, - "node_modules/@types/chai-subset": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.3.tgz", - "integrity": "sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==", - "dev": true, - "dependencies": { - "@types/chai": "*" - } - }, - "node_modules/@types/datatables.net": { - "version": "1.10.24", - "resolved": "https://registry.npmjs.org/@types/datatables.net/-/datatables.net-1.10.24.tgz", - "integrity": "sha512-Qb82/7Gn0bU36YLiv0MdaqKzhTLfRO9qPvFdkW0miQ6ATMG47aoPn2r//zTvGd3oPSt+Lzp1HSsjP6rZRuki8g==", - "dev": true, - "dependencies": { - "@types/jquery": "*" - } - }, - "node_modules/@types/datatables.net-buttons": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/@types/datatables.net-buttons/-/datatables.net-buttons-1.4.7.tgz", - "integrity": "sha512-BicCRXPmHoLReYvEBD35aZIkXptUP61pXD6N5t82Xh4+gquErTqDiqOY7V5kFLIleMsZJY/IZp2XlCFhzFiGKw==", - "dev": true, - "dependencies": { - "@types/datatables.net": "*", - "@types/jquery": "*" - } - }, - "node_modules/@types/datatables.net-scroller": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@types/datatables.net-scroller/-/datatables.net-scroller-1.4.1.tgz", - "integrity": "sha512-11MNAwUx7BfN7+nQJAgS7yyYc/USHXKG1UkYYQKXyXEgSoXBiHzaTVamp4pNx8MKZyseqHlIsAP2IMlcPC9o3Q==", - "dev": true, - "dependencies": { - "@types/datatables.net": "*", - "@types/jquery": "*" - } - }, - "node_modules/@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/google.maps": { - "version": "3.52.1", - "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.52.1.tgz", - "integrity": "sha512-O0MTQyE57zSWf04q/uNmKa3XHvgEj5pvDwJ4N3SqfYaHdusGVQWzkXkNYHeJPL09yHjvSdSy0WcDEX9C/do9kQ==", - "dev": true - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "node_modules/@types/jquery": { - "version": "3.5.16", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.16.tgz", - "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==", - "dev": true, - "dependencies": { - "@types/sizzle": "*" - } - }, - "node_modules/@types/jqueryui": { - "version": "1.12.16", - "resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.16.tgz", - "integrity": "sha512-6huAQDpNlso9ayaUT9amBOA3kj02OCeUWs+UvDmbaJmwkHSg/HLsQOoap/D5uveN9ePwl72N45Bl+Frp5xyG1Q==", - "dev": true, - "dependencies": { - "@types/jquery": "*" - } - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "optional": true - }, - "node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "node_modules/@types/phoenix": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.5.5.tgz", - "integrity": "sha512-1eWWT19k0L4ZiTvdXjAvJ9KvW0B8SdiVftQmFPJGTEx78Q4PCSIQDpz+EfkFVR1N4U9gREjlW4JXL8YCIlY0bw==" - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/sizzle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", - "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", - "dev": true - }, - "node_modules/@types/tmi.js": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@types/tmi.js/-/tmi.js-1.8.3.tgz", - "integrity": "sha512-piKPU1DF+Lxnh9BV0gVpbJIMnKOQT6zT0o6NLE0DZgHNW7fGxReRRSp987+Ph1aYiyNWXXbxAeQAovTlEYC1hw==", - "dev": true - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", - "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" - }, - "node_modules/@types/when-dom-ready": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/when-dom-ready/-/when-dom-ready-1.2.0.tgz", - "integrity": "sha512-+ZZcdwtGXSjjgpdEbCU9n91OOeFHZDFAyt98/yO8PUYZ4NJ46D/y9NFRIgsREXpmHFz7oZL5Bv9e515WynM4dQ==", - "dev": true - }, - "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@vitest/expect": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.2.tgz", - "integrity": "sha512-EZm2dMNlLyIfDMha17QHSQcg2KjeAZaXd65fpPzXY5bvnfx10Lcaz3N55uEe8PhF+w4pw+hmrlHLLlRn9vkBJg==", - "dev": true, - "dependencies": { - "@vitest/spy": "0.34.2", - "@vitest/utils": "0.34.2", - "chai": "^4.3.7" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.2.tgz", - "integrity": "sha512-8ydGPACVX5tK3Dl0SUwxfdg02h+togDNeQX3iXVFYgzF5odxvaou7HnquALFZkyVuYskoaHUOqOyOLpOEj5XTA==", - "dev": true, - "dependencies": { - "@vitest/utils": "0.34.2", - "p-limit": "^4.0.0", - "pathe": "^1.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vitest/snapshot": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.2.tgz", - "integrity": "sha512-qhQ+xy3u4mwwLxltS4Pd4SR+XHv4EajiTPNY3jkIBLUApE6/ce72neJPSUQZ7bL3EBuKI+NhvzhGj3n5baRQUQ==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@vitest/spy": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.2.tgz", - "integrity": "sha512-yd4L9OhfH6l0Av7iK3sPb3MykhtcRN5c5K5vm1nTbuN7gYn+yvUVVsyvzpHrjqS7EWqn9WsPJb7+0c3iuY60tA==", - "dev": true, - "dependencies": { - "tinyspy": "^2.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.2.tgz", - "integrity": "sha512-Lzw+kAsTPubhoQDp1uVAOP6DhNia1GMDsI9jgB0yMn+/nDaPieYQ88lKqz/gGjSHL4zwOItvpehec9OY+rS73w==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@volar/language-core": { - "version": "1.3.0-alpha.0", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.3.0-alpha.0.tgz", - "integrity": "sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==", - "dev": true, - "dependencies": { - "@volar/source-map": "1.3.0-alpha.0" - } - }, - "node_modules/@volar/source-map": { - "version": "1.3.0-alpha.0", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.3.0-alpha.0.tgz", - "integrity": "sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==", - "dev": true, - "dependencies": { - "muggle-string": "^0.2.2" - } - }, - "node_modules/@volar/typescript": { - "version": "1.3.0-alpha.0", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.3.0-alpha.0.tgz", - "integrity": "sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==", - "dev": true, - "dependencies": { - "@volar/language-core": "1.3.0-alpha.0" - } - }, - "node_modules/@volar/vue-language-core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.2.0.tgz", - "integrity": "sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==", - "dev": true, - "dependencies": { - "@volar/language-core": "1.3.0-alpha.0", - "@volar/source-map": "1.3.0-alpha.0", - "@vue/compiler-dom": "^3.2.47", - "@vue/compiler-sfc": "^3.2.47", - "@vue/reactivity": "^3.2.47", - "@vue/shared": "^3.2.47", - "minimatch": "^6.1.6", - "muggle-string": "^0.2.2", - "vue-template-compiler": "^2.7.14" - } - }, - "node_modules/@volar/vue-language-core/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@volar/vue-language-core/node_modules/minimatch": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", - "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@volar/vue-typescript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.2.0.tgz", - "integrity": "sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==", - "dev": true, - "dependencies": { - "@volar/typescript": "1.3.0-alpha.0", - "@volar/vue-language-core": "1.2.0" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", - "integrity": "sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==", - "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/shared": "3.2.47", - "estree-walker": "^2.0.2", - "source-map": "^0.6.1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz", - "integrity": "sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==", - "dependencies": { - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz", - "integrity": "sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==", - "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-ssr": "3.2.47", - "@vue/reactivity-transform": "3.2.47", - "@vue/shared": "3.2.47", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7", - "postcss": "^8.1.10", - "source-map": "^0.6.1" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz", - "integrity": "sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==", - "dependencies": { - "@vue/compiler-dom": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.47.tgz", - "integrity": "sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==", - "dependencies": { - "@vue/shared": "3.2.47" - } - }, - "node_modules/@vue/reactivity-transform": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz", - "integrity": "sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==", - "dependencies": { - "@babel/parser": "^7.16.4", - "@vue/compiler-core": "3.2.47", - "@vue/shared": "3.2.47", - "estree-walker": "^2.0.2", - "magic-string": "^0.25.7" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.47.tgz", - "integrity": "sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==", - "dependencies": { - "@vue/reactivity": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz", - "integrity": "sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==", - "dependencies": { - "@vue/runtime-core": "3.2.47", - "@vue/shared": "3.2.47", - "csstype": "^2.6.8" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.47.tgz", - "integrity": "sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==", - "dependencies": { - "@vue/compiler-ssr": "3.2.47", - "@vue/shared": "3.2.47" - }, - "peerDependencies": { - "vue": "3.2.47" - } - }, - "node_modules/@vue/shared": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.47.tgz", - "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" - }, - "node_modules/@vueuse/core": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.13.0.tgz", - "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", - "dependencies": { - "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "9.13.0", - "@vueuse/shared": "9.13.0", - "vue-demi": "*" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/metadata": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz", - "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz", - "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", - "dependencies": { - "vue-demi": "*" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/abortcontroller-polyfill": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", - "integrity": "sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", - "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "depd": "^2.0.0", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/asar": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz", - "integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==", - "deprecated": "Please use @electron/asar moving forward. There is no API change, just a package name change", - "dev": true, - "optional": true, - "dependencies": { - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - }, - "optionalDependencies": { - "@types/glob": "^7.1.1" - } - }, - "node_modules/asar/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atomically": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/author-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", - "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/axios": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", - "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "node_modules/better-sqlite3": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.1.0.tgz", - "integrity": "sha512-p1m09H+Oi8R9TPj810pdNswMFuVgRNgCJEWypp6jlkOgSwMIrNyuj3hW78xEuBRGok5RzeaUW8aBtTWF3l/TQA==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.5.0", - "prebuild-install": "^7.1.0" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "optional": true - }, - "node_modules/bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", - "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", - "dev": true, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001462", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001462.tgz", - "integrity": "sha512-PDd20WuOBPiasZ7KbFnmQRyuLE7cFXW2PVd7dmALzbkUXEP46upAuCDm9eY9vho8fgNMGmbAX92QBZHzcnWIqw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", - "dev": true - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/conf": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", - "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", - "dependencies": { - "ajv": "^8.6.3", - "ajv-formats": "^2.1.1", - "atomically": "^1.7.0", - "debounce-fn": "^4.0.0", - "dot-prop": "^6.0.1", - "env-paths": "^2.2.1", - "json-schema-typed": "^7.0.3", - "onetime": "^5.1.2", - "pkg-up": "^3.1.0", - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true - }, - "node_modules/consolidate": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", - "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", - "dev": true, - "dependencies": { - "bluebird": "^3.7.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/coordinate_to_country": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/coordinate_to_country/-/coordinate_to_country-1.1.0.tgz", - "integrity": "sha512-kLMIFZpnZb1W7KcJnTehWBTOLZjVnx0udZaHj8b5nN5Qmoj+mYQrWEhNm8lBDZm+r12BEIaZFhmrHgWkD6IAXQ==", - "dependencies": { - "@osm_borders/maritime_10m": "^1.1.0", - "geojson-geometries-lookup": "^0.5.0" - } - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", - "dependencies": { - "node-fetch": "2.6.7" - } - }, - "node_modules/cross-fetch/node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn-windows-exe": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cross-spawn-windows-exe/-/cross-spawn-windows-exe-1.2.0.tgz", - "integrity": "sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-cross-spawn-windows-exe?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "@malept/cross-spawn-promise": "^1.1.0", - "is-wsl": "^2.2.0", - "which": "^2.0.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cross-spawn-windows-exe/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cross-zip": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-4.0.0.tgz", - "integrity": "sha512-MEzGfZo0rqE10O/B+AEcCSJLZsrWuRUvmqJTqHNqBtALhaJc3E3ixLGLJNTRzEA2K34wbmOHC4fwYs9sVsdcCA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=12.10" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csstype": { - "version": "2.6.21", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", - "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/datatables.net": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.13.3.tgz", - "integrity": "sha512-YVnz02oJsaP/OfnclBlqHkuV1il60sSVa+a0Xvs5gyiDLftmAxc+rvVAwCm7O0OpKo09N43k6EcCAf3L9WYI7g==", - "dependencies": { - "jquery": ">=1.7" - } - }, - "node_modules/datatables.net-buttons": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/datatables.net-buttons/-/datatables.net-buttons-2.3.5.tgz", - "integrity": "sha512-iY4BC10zNWuyzgdiPQ4b8n9Cz74oEk4OzO8FTDeg0yytmsZVT/JncIS2mBt08JW4DLWaB6a0+6UPd+0UHwvIUA==", - "dependencies": { - "datatables.net": ">=1.12.1", - "jquery": ">=1.7" - } - }, - "node_modules/datatables.net-plugins": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/datatables.net-plugins/-/datatables.net-plugins-1.13.1.tgz", - "integrity": "sha512-4UpaRl7ZiTmStjV1QTB3x9V0EKmgdMvF7Ms+HzZ6gSzv33kPrL9Cw76/Uxxl02Z+ajergobvfMN64ndlZ9AXzA==" - }, - "node_modules/datatables.net-scroller": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/datatables.net-scroller/-/datatables.net-scroller-2.1.0.tgz", - "integrity": "sha512-B/MxP8YPcFtoa1cexvlcK0PXQdzy6tz+HhQlyjNpRCoRc/8ZM5VcZg+ecYfP/pRBBXZORgkOJjWYkIdoChhE0w==", - "dependencies": { - "datatables.net": ">=1.12.1", - "jquery": ">=1.7" - } - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true - }, - "node_modules/debounce-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", - "dependencies": { - "mimic-fn": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deepmerge": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", - "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defaults/node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "optional": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "optional": true - }, - "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "engines": { - "node": ">=12" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "node_modules/electron": { - "version": "22.3.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.2.tgz", - "integrity": "sha512-rcE01ammPJ9RVDF3sCETyeHiDEVxV49Ywn+wXUGiG+jGtOB6erLx5jnBTf2eSVYoTXqoIbigoxGHLq4nLMLLUg==", - "hasInstallScript": true, - "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^16.11.26", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" - }, - "engines": { - "node": ">= 12.20.55" - } - }, - "node_modules/electron-installer-common": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/electron-installer-common/-/electron-installer-common-0.10.3.tgz", - "integrity": "sha512-mYbP+6i+nHMIm0WZHXgGdmmXMe+KXncl6jZYQNcCF9C1WsNA9C5SZ2VP4TLQMSIoFO+X4ugkMEA5uld1bmyEvA==", - "dev": true, - "optional": true, - "dependencies": { - "@malept/cross-spawn-promise": "^1.0.0", - "asar": "^3.0.0", - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "glob": "^7.1.4", - "lodash": "^4.17.15", - "parse-author": "^2.0.0", - "semver": "^7.1.1", - "tmp-promise": "^3.0.2" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "url": "https://github.com/electron-userland/electron-installer-common?sponsor=1" - }, - "optionalDependencies": { - "@types/fs-extra": "^9.0.1" - } - }, - "node_modules/electron-installer-common/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "optional": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/electron-installer-common/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "optional": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-installer-debian": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/electron-installer-debian/-/electron-installer-debian-3.1.0.tgz", - "integrity": "sha512-k6KChvx0Fw8XTlCqwwbBfh19yGQaKjGdbugokmr1IpzINOm4QFyACKMTHAYFHW5LCBUZQShZD96hwxUZ+8Kx+w==", - "dev": true, - "optional": true, - "os": [ - "darwin", - "linux" - ], - "dependencies": { - "@malept/cross-spawn-promise": "^1.0.0", - "debug": "^4.1.1", - "electron-installer-common": "^0.10.2", - "fs-extra": "^9.0.0", - "get-folder-size": "^2.0.1", - "lodash": "^4.17.4", - "word-wrap": "^1.2.3", - "yargs": "^15.0.1" - }, - "bin": { - "electron-installer-debian": "src/cli.js" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-installer-debian/node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "optional": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/electron-installer-debian/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "optional": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/electron-installer-debian/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "optional": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "optional": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-installer-debian/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "optional": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "optional": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-installer-debian/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "optional": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "optional": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true, - "optional": true - }, - "node_modules/electron-installer-debian/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "optional": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-installer-debian/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "optional": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/electron-is-dev": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz", - "integrity": "sha512-jLttuuq8QK67n3mXmIe9pkrO7IH3LGIk12xJkhTmc852U2sCJaRAOpRGPSh+1Xnzck5v9escd9YXzuze9nGejg==" - }, - "node_modules/electron-packager": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-17.1.1.tgz", - "integrity": "sha512-r1NDtlajsq7gf2EXgjRfblCVPquvD2yeg+6XGErOKblvxOpDi0iulZLVhgYDP4AEF1P5/HgbX/vwjlkEv7PEIQ==", - "dev": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "@electron/get": "^2.0.0", - "@electron/notarize": "^1.2.3", - "@electron/osx-sign": "^1.0.1", - "@electron/universal": "^1.3.2", - "cross-spawn-windows-exe": "^1.2.0", - "debug": "^4.0.1", - "extract-zip": "^2.0.0", - "filenamify": "^4.1.0", - "fs-extra": "^10.1.0", - "galactus": "^0.2.1", - "get-package-info": "^1.0.0", - "junk": "^3.1.0", - "parse-author": "^2.0.0", - "plist": "^3.0.0", - "rcedit": "^3.0.1", - "resolve": "^1.1.6", - "semver": "^7.1.3", - "yargs-parser": "^21.1.1" - }, - "bin": { - "electron-packager": "bin/electron-packager.js" - }, - "engines": { - "node": ">= 14.17.5" - }, - "funding": { - "url": "https://github.com/electron/electron-packager?sponsor=1" - } - }, - "node_modules/electron-squirrel-startup": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz", - "integrity": "sha512-Oce8mvgGdFmwr+DsAcXBmFK8jFfN6yaFAP9IvyhTfupM3nFkBku/7VS/mdtJteWumImkC6P+BKGsxScoDDkv9Q==", - "dependencies": { - "debug": "^2.2.0" - } - }, - "node_modules/electron-squirrel-startup/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/electron-squirrel-startup/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/electron-store": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", - "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", - "dependencies": { - "conf": "^10.2.0", - "type-fest": "^2.17.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.322", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.322.tgz", - "integrity": "sha512-KovjizNC9XB7dno/2GjxX8VS0SlfPpCjtyoKft+bCO+UfD8bFy16hY4Sh9s0h9BDxbRH2U0zX5VBjpM1LTcNlg==", - "dev": true - }, - "node_modules/electron-winstaller": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.1.0.tgz", - "integrity": "sha512-4wlZzkUm5cJNiOtp5wL804+QpygdKTKkrZJXA3sSDEI2XnCVPv0kxmxUvVw4KHBwbNS+Yox89agEr+VkR7kxww==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash.template": "^4.2.2", - "temp": "^0.9.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/electron-winstaller/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/electron-winstaller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optional": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-winstaller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "optional": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/electron/node_modules/@types/node": { - "version": "16.18.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.14.tgz", - "integrity": "sha512-wvzClDGQXOCVNU4APPopC2KtMYukaF1MN/W3xAmslx22Z4/IF1/izDMekuyoUlwfnDHYCIZGaj7jMwnJKBTxKw==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/engine.io-client": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz", - "integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.11.0", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", - "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "optional": true - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "dev": true, - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flora-colossus": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.1.tgz", - "integrity": "sha512-d+9na7t9FyH8gBJoNDSi28mE4NgQVGGvxQ4aHtFRetjyh5SXjuus+V5EZaxFmFdXVemSOrx0lsgEl/ZMjnOWJA==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^7.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/flora-colossus/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/flora-colossus/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/flora-colossus/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/format-duration": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/format-duration/-/format-duration-3.0.2.tgz", - "integrity": "sha512-pKzJDSRgK2lqAiPW3uizDaIJaJnataZclsahz25UMwfdryBGDa+1HlbXGjzpMvX/2kMh4O0sNevFXKaEfCjHsA==" - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "devOptional": true - }, - "node_modules/galactus": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz", - "integrity": "sha512-mDc8EQJKtxjp9PMYS3PbpjjbX3oXhBTxoGaPahw620XZBIHJ4+nvw5KN/tRtmmSDR9dypstGNvqQ3C29QGoGHQ==", - "dev": true, - "dependencies": { - "debug": "^3.1.0", - "flora-colossus": "^1.0.0", - "fs-extra": "^4.0.0" - } - }, - "node_modules/galactus/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/galactus/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/galactus/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/galactus/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/gar": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz", - "integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==", - "dev": true, - "optional": true - }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "dev": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/geojson-geometries": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/geojson-geometries/-/geojson-geometries-2.0.0.tgz", - "integrity": "sha512-HKljxKnbJrdkr7ijg5/nvcr1b81HP+C/rS48cJwRb3xEqiEynlGkRVkQ/msopw+EE3gf7DjEKdZyEGMck0bOpw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/geojson-geometries-lookup": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/geojson-geometries-lookup/-/geojson-geometries-lookup-0.5.0.tgz", - "integrity": "sha512-AfadxaBda6VTwwX4USLiVofFaz0HIjubC7ZC15hGTvc8K0di3pmCNWGFotKJeURSxYPbJLFoet34X3JrIKFX4A==", - "dependencies": { - "@turf/bbox": "^6.0.1", - "@turf/boolean-contains": "^6.0.1", - "geojson-geometries": "^2.0.0", - "rbush": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-folder-size": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz", - "integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==", - "dev": true, - "optional": true, - "dependencies": { - "gar": "^1.0.4", - "tiny-each-async": "2.0.3" - }, - "bin": { - "get-folder-size": "bin/get-folder-size" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-installed-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/get-installed-path/-/get-installed-path-2.1.1.tgz", - "integrity": "sha512-Qkn9eq6tW5/q9BDVdMpB8tOHljX9OSP0jRC5TRNVA4qRc839t4g8KQaR8t0Uv0EFVL0MlyG7m/ofjEgAROtYsA==", - "dev": true, - "dependencies": { - "global-modules": "1.0.0" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "optional": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", - "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", - "dev": true, - "dependencies": { - "bluebird": "^3.1.1", - "debug": "^2.2.0", - "lodash.get": "^4.0.0", - "read-pkg-up": "^2.0.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/get-package-info/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/get-package-info/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/get-port": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz", - "integrity": "sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, - "node_modules/github-url-to-object": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/github-url-to-object/-/github-url-to-object-4.0.6.tgz", - "integrity": "sha512-NaqbYHMUAlPcmWFdrAB7bcxrNIiiJWJe8s/2+iOc9vlcHlwHqSGrPk+Yi3nu6ebTwgsZEa7igz+NH2vEq3gYwQ==", - "dependencies": { - "is-url": "^1.1.0" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "optional": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "devOptional": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "optional": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "optional": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/htmlnano": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-2.0.3.tgz", - "integrity": "sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A==", - "dev": true, - "dependencies": { - "cosmiconfig": "^7.0.1", - "posthtml": "^0.16.5", - "timsort": "^0.3.0" - }, - "peerDependencies": { - "cssnano": "^5.0.11", - "postcss": "^8.3.11", - "purgecss": "^5.0.0", - "relateurl": "^0.2.7", - "srcset": "4.0.0", - "svgo": "^2.8.0", - "terser": "^5.10.0", - "uncss": "^0.17.3" - }, - "peerDependenciesMeta": { - "cssnano": { - "optional": true - }, - "postcss": { - "optional": true - }, - "purgecss": { - "optional": true - }, - "relateurl": { - "optional": true - }, - "srcset": { - "optional": true - }, - "svgo": { - "optional": true - }, - "terser": { - "optional": true - }, - "uncss": { - "optional": true - } - } - }, - "node_modules/htmlparser2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", - "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "dev": true, - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "dev": true - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", - "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", - "dev": true - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/jquery": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz", - "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==" - }, - "node_modules/jquery-ui-dist": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/jquery-ui-dist/-/jquery-ui-dist-1.13.2.tgz", - "integrity": "sha512-oVDRd1NLtTbBwpRKAYdIRgpWVDzeBhfy7Gu0RmY6JEaZtmBq6kDn1pm5SgDiAotrnDS+RoTRXO6xvcNTxA9tOA==", - "dependencies": { - "jquery": ">=1.8.0 <4.0.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json-schema-typed": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "optional": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/lightningcss": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.21.5.tgz", - "integrity": "sha512-/pEUPeih2EwIx9n4T82aOG6CInN83tl/mWlw6B5gWLf36UplQi1L+5p3FUHsdt4fXVfOkkh9KIaM3owoq7ss8A==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.21.5", - "lightningcss-darwin-x64": "1.21.5", - "lightningcss-linux-arm-gnueabihf": "1.21.5", - "lightningcss-linux-arm64-gnu": "1.21.5", - "lightningcss-linux-arm64-musl": "1.21.5", - "lightningcss-linux-x64-gnu": "1.21.5", - "lightningcss-linux-x64-musl": "1.21.5", - "lightningcss-win32-x64-msvc": "1.21.5" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.21.5.tgz", - "integrity": "sha512-z05hyLX85WY0UfhkFUOrWEFqD69lpVAmgl3aDzMKlIZJGygbhbegqb4PV8qfUrKKNBauut/qVNPKZglhTaDDxA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.21.5.tgz", - "integrity": "sha512-MSJhmej/U9MrdPxDk7+FWhO8+UqVoZUHG4VvKT5RQ4RJtqtANTiWiI97LvoVNMtdMnHaKs1Pkji6wHUFxjJsHQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.21.5.tgz", - "integrity": "sha512-xN6+5/JsMrbZHL1lPl+MiNJ3Xza12ueBKPepiyDCFQzlhFRTj7D0LG+cfNTzPBTO8KcYQynLpl1iBB8LGp3Xtw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.21.5.tgz", - "integrity": "sha512-KfzFNhC4XTbmG3ma/xcTs/IhCwieW89XALIusKmnV0N618ZDXEB0XjWOYQRCXeK9mfqPdbTBpurEHV/XZtkniQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.21.5.tgz", - "integrity": "sha512-bc0GytQO5Mn9QM6szaZ+31fQHNdidgpM1sSCwzPItz8hg3wOvKl8039rU0veMJV3ZgC9z0ypNRceLrSHeRHmXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.21.5.tgz", - "integrity": "sha512-JwMbgypPQgc2kW2av3OwzZ8cbrEuIiDiXPJdXRE6aVxu67yHauJawQLqJKTGUhiAhy6iLDG8Wg0a3/ziL+m+Kw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.21.5.tgz", - "integrity": "sha512-Ib8b6IQ/OR/VrPU6YBgy4T3QnuHY7DUa95O+nz+cwrTkMSN6fuHcTcIaz4t8TJ6HI5pl3uxUOZjmtls2pyQWow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.21.5.tgz", - "integrity": "sha512-A8cSi8lUpBeVmoF+DqqW7cd0FemDbCuKr490IXdjyeI+KL8adpSKUs8tcqO0OXPh1EoDqK7JNkD/dELmd4Iz5g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/listr2": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.7.tgz", - "integrity": "sha512-MD+qXHPmtivrHIDRwPYdfNkrzqDiuaKU/rfBcec3WMyMF3xylQj3jMq344OtvQxz7zaCFViRAeqlr2AFhPvXHw==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.19", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.8.0", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/lmdb": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", - "integrity": "sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "msgpackr": "^1.5.4", - "node-addon-api": "^4.3.0", - "node-gyp-build-optional-packages": "5.0.3", - "ordered-binary": "^1.2.4", - "weak-lru-cache": "^1.2.2" - }, - "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "2.5.2", - "@lmdb/lmdb-darwin-x64": "2.5.2", - "@lmdb/lmdb-linux-arm": "2.5.2", - "@lmdb/lmdb-linux-arm64": "2.5.2", - "@lmdb/lmdb-linux-x64": "2.5.2", - "@lmdb/lmdb-win32-x64": "2.5.2" - } - }, - "node_modules/lmdb/node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "dev": true - }, - "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "dev": true, - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", - "dev": true, - "optional": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "optional": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "optional": true, - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" - }, - "node_modules/lzma-native": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", - "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^3.1.0", - "node-gyp-build": "^4.2.1", - "readable-stream": "^3.6.0" - }, - "bin": { - "lzmajs": "bin/lzmajs" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/match-sorter": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz", - "integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "remove-accents": "0.4.2" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "dependencies": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mem/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "dev": true, - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, - "node_modules/mlly": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.4.0.tgz", - "integrity": "sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "pathe": "^1.1.1", - "pkg-types": "^1.0.3", - "ufo": "^1.1.2" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/msgpackr": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.8.4.tgz", - "integrity": "sha512-BE3hD3PqV7jsNaV022uq0jMW+ZVc32wSYyQmwAoJUc+vPtCeyro2MOtAW61Fd9ZKNySM6y913E9fBY0mG+hKXg==", - "dev": true, - "optionalDependencies": { - "msgpackr-extract": "^3.0.1" - } - }, - "node_modules/msgpackr-extract": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz", - "integrity": "sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build-optional-packages": "5.0.7" - }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" - }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.2", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.2" - } - }, - "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz", - "integrity": "sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==", - "dev": true, - "optional": true, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, - "node_modules/muggle-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.2.2.tgz", - "integrity": "sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-abi": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.33.0.tgz", - "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true - }, - "node_modules/node-api-version": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", - "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - } - }, - "node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz", - "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.13 || ^14.13 || >=16" - } - }, - "node_modules/node-gyp-build": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz", - "integrity": "sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==", - "dev": true, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" - } - }, - "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true - }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "dev": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ordered-binary": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.4.0.tgz", - "integrity": "sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==", - "dev": true - }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/parcel": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/parcel/-/parcel-2.8.3.tgz", - "integrity": "sha512-5rMBpbNE72g6jZvkdR5gS2nyhwIXaJy8i65osOqs/+5b7zgf3eMKgjSsDrv6bhz3gzifsba6MBJiZdBckl+vnA==", - "dev": true, - "dependencies": { - "@parcel/config-default": "2.8.3", - "@parcel/core": "2.8.3", - "@parcel/diagnostic": "2.8.3", - "@parcel/events": "2.8.3", - "@parcel/fs": "2.8.3", - "@parcel/logger": "2.8.3", - "@parcel/package-manager": "2.8.3", - "@parcel/reporter-cli": "2.8.3", - "@parcel/reporter-dev-server": "2.8.3", - "@parcel/utils": "2.8.3", - "chalk": "^4.1.0", - "commander": "^7.0.0", - "get-port": "^4.2.0", - "v8-compile-cache": "^2.0.0" - }, - "bin": { - "parcel": "lib/bin.js" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/parcel/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-author": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", - "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", - "dev": true, - "dependencies": { - "author-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", - "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/plist": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", - "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", - "dev": true, - "dependencies": { - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/postcss": { - "version": "8.4.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", - "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/posthtml": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.6.tgz", - "integrity": "sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==", - "dev": true, - "dependencies": { - "posthtml-parser": "^0.11.0", - "posthtml-render": "^3.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/posthtml-parser": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.10.2.tgz", - "integrity": "sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==", - "dev": true, - "dependencies": { - "htmlparser2": "^7.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/posthtml-render": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", - "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", - "dev": true, - "dependencies": { - "is-json": "^2.0.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/posthtml/node_modules/posthtml-parser": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", - "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", - "dev": true, - "dependencies": { - "htmlparser2": "^7.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" - }, - "node_modules/rbush": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", - "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", - "dependencies": { - "quickselect": "^2.0.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rcedit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-3.0.1.tgz", - "integrity": "sha512-XM0Jv40/y4hVAqj/MO70o/IWs4uOsaSoo2mLyk3klFDW+SStLnCtzuQu+1OBTIMGlM8CvaK9ftlYCp6DJ+cMsw==", - "dev": true, - "dependencies": { - "cross-spawn-windows-exe": "^1.1.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", - "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==", - "dev": true - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/react-refresh": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.9.0.tgz", - "integrity": "sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", - "dev": true, - "dependencies": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", - "dev": true, - "dependencies": { - "pify": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", - "integrity": "sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/remove-accents": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true, - "optional": true - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-package": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-package/-/resolve-package-1.0.1.tgz", - "integrity": "sha512-rzB7NnQpOkPHBWFPP3prUMqOP6yg3HkRGgcvR+lDyvyHoY3fZLFLYDkPXh78SPVBAE6VTCk/V+j8we4djg6o4g==", - "dev": true, - "dependencies": { - "get-installed-path": "^2.0.3" - }, - "engines": { - "node": ">=4", - "npm": ">=2" - } - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/roarr/node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "optional": true - }, - "node_modules/rollup": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz", - "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "optional": true - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socket.io-client": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz", - "integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.4.0", - "socket.io-parser": "~4.2.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", - "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "dev": true, - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "node_modules/srcset": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": true - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/std-env": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", - "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", - "dev": true, - "dependencies": { - "acorn": "^8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/sudo-prompt": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", - "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", - "dev": true - }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dependencies": { - "debug": "^4.1.0" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz", - "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/temp": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", - "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", - "dev": true, - "optional": true, - "dependencies": { - "mkdirp": "^0.5.1", - "rimraf": "~2.6.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/temp/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "optional": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/temp/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "optional": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/term-size": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.5.tgz", - "integrity": "sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true - }, - "node_modules/tiny-each-async": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", - "integrity": "sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==", - "dev": true, - "optional": true - }, - "node_modules/tinybench": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.0.tgz", - "integrity": "sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==", - "dev": true - }, - "node_modules/tinypool": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", - "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz", - "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tmi.js": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/tmi.js/-/tmi.js-1.8.5.tgz", - "integrity": "sha512-A9qrydfe1e0VWM9MViVhhxVgvLpnk7pFShVUWePsSTtoi+A1X+Zjdoa7OJd7/YsgHXGj3GkNEvnWop/1WwZuew==", - "dependencies": { - "node-fetch": "^2.6.1", - "ws": "^8.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "optional": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", - "dev": true, - "optional": true, - "dependencies": { - "tmp": "^0.2.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/ufo": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.2.0.tgz", - "integrity": "sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==", - "dev": true - }, - "node_modules/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/update-electron-app": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/update-electron-app/-/update-electron-app-2.0.1.tgz", - "integrity": "sha512-e4xEner89UZZaBGYJbYlMdL1uUrC0VjOsTAL2N4opPjzFtn+j7mdsJJsnyXZzUVeLY+8tuCX4XEsUM98oBHmZg==", - "dependencies": { - "electron-is-dev": "^0.3.0", - "github-url-to-object": "^4.0.4", - "is-url": "^1.2.4", - "ms": "^2.1.1" - }, - "peerDependencies": { - "electron": ">= 6.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/username": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", - "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", - "dev": true, - "dependencies": { - "execa": "^1.0.0", - "mem": "^4.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/username/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/username/node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/username/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/username/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/username/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/username/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/username/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/username/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/username/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/username/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", - "dev": true, - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.2.tgz", - "integrity": "sha512-JtW249Zm3FB+F7pQfH56uWSdlltCo1IOkZW5oHBzeQo0iX4jtC7o1t9aILMGd9kVekXBP2lfJBEQt9rBh07ebA==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "0.34.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.2.tgz", - "integrity": "sha512-WgaIvBbjsSYMq/oiMlXUI7KflELmzM43BEvkdC/8b5CAod4ryAiY2z8uR6Crbi5Pjnu5oOmhKa9sy7uk6paBxQ==", - "dev": true, - "dependencies": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.34.2", - "@vitest/runner": "0.34.2", - "@vitest/snapshot": "0.34.2", - "@vitest/spy": "0.34.2", - "@vitest/utils": "0.34.2", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", - "chai": "^4.3.7", - "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.7.0", - "vite": "^3.0.0 || ^4.0.0", - "vite-node": "0.34.2", - "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", - "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/vitest/node_modules/magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/vue": { - "version": "3.2.47", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.47.tgz", - "integrity": "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==", - "dependencies": { - "@vue/compiler-dom": "3.2.47", - "@vue/compiler-sfc": "3.2.47", - "@vue/runtime-dom": "3.2.47", - "@vue/server-renderer": "3.2.47", - "@vue/shared": "3.2.47" - } - }, - "node_modules/vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/vue-template-compiler": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz", - "integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==", - "dev": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, - "node_modules/vue-tsc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.2.0.tgz", - "integrity": "sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==", - "dev": true, - "dependencies": { - "@volar/vue-language-core": "1.2.0", - "@volar/vue-typescript": "1.2.0" - }, - "bin": { - "vue-tsc": "bin/vue-tsc.js" - }, - "peerDependencies": { - "typescript": "*" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/weak-lru-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", - "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "dependencies": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/when-dom-ready": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/when-dom-ready/-/when-dom-ready-1.2.12.tgz", - "integrity": "sha512-nEy7UvAylNMfOTTKE2c7QTFR2fyqTRaL/f+tuTpE4zU7iAF7Pk7aLmw6jZvhrwUTcK6pmnXFc0/N0Kzi/PHmEg==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true, - "optional": true - }, - "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/xxhash-wasm": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz", - "integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", - "engines": { - "node": ">=0.10.32" - } - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yarn-or-npm": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/yarn-or-npm/-/yarn-or-npm-3.0.1.tgz", - "integrity": "sha512-fTiQP6WbDAh5QZAVdbMQkecZoahnbOjClTQhzv74WX5h2Uaidj1isf9FDes11TKtsZ0/ZVfZsqZ+O3x6aLERHQ==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.5", - "pkg-dir": "^4.2.0" - }, - "bin": { - "yarn-or-npm": "bin/index.js", - "yon": "bin/index.js" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/yarn-or-npm/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/yarn-or-npm/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yarn-or-npm/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/yarn-or-npm/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yarn-or-npm/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yarn-or-npm/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } + "name": "chatguessr", + "version": "3.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "chatguessr", + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@supabase/supabase-js": "^2.42.0", + "axios": "^1.6.8", + "better-sqlite3": "^9.4.5", + "coordinate_to_country": "^1.1.0", + "electron-squirrel-startup": "^1.0.0", + "electron-store": "^8.2.0", + "format-duration": "^3.0.2", + "match-sorter": "^6.3.4", + "socket.io-client": "^4.7.5", + "tmi.js": "^1.8.5", + "update-electron-app": "^3.0.0", + "vue3-draggable-resizable": "^1.6.5", + "when-dom-ready": "^1.2.12" + }, + "devDependencies": { + "@electron-forge/cli": "^7.2.0", + "@electron-forge/maker-deb": "^7.2.0", + "@electron-forge/maker-squirrel": "^7.2.0", + "@electron-forge/maker-zip": "^7.2.0", + "@electron-forge/plugin-vite": "^7.2.0", + "@electron-forge/publisher-github": "^7.2.0", + "@types/better-sqlite3": "^7.6.8", + "@types/google.maps": "^3.55.7", + "@types/tmi.js": "^1.8.6", + "@types/when-dom-ready": "^1.2.2", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@vitejs/plugin-vue": "^5.0.4", + "@vue/eslint-config-prettier": "^9.0.0", + "@vue/eslint-config-typescript": "^13.0.0", + "@vueuse/core": "^10.9.0", + "electron": "^29.2.0", + "eslint": "^8.57.0", + "prettier": "^3.2.5", + "ts-node": "^10.9.2", + "typescript": "^5.4.4", + "vite-svg-loader": "^5.1.0", + "vitest": "^1.4.0", + "vue": "^3.4.21", + "vue-tsc": "^2.0.11" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/cli": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/cli/-/cli-7.2.0.tgz", + "integrity": "sha512-FJ8XzT4w6bTC3trvHHWL67W1zp7g2xmCC5riNa1rjk8Gd2C1j8wf0ul4ch9kbcaEAFaXuXwv98QKXxhCn4aLtQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-cli?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "@electron-forge/core": "7.2.0", + "@electron-forge/shared-types": "7.2.0", + "@electron/get": "^3.0.0", + "chalk": "^4.0.0", + "commander": "^4.1.1", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "listr2": "^5.0.3", + "semver": "^7.2.1" + }, + "bin": { + "electron-forge": "dist/electron-forge.js", + "electron-forge-vscode-nix": "script/vscode.sh", + "electron-forge-vscode-win": "script/vscode.cmd" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/core": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.2.0.tgz", + "integrity": "sha512-7Sh0KW79Z/y9MStU3sWTBbTkM4SvV6rL557/ndlfAbZrxcGMnmWHrzn/odAZW1eyfhKguBb7C1Ijw0YTpsdVsw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.electron-forge-core?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "@electron-forge/core-utils": "7.2.0", + "@electron-forge/maker-base": "7.2.0", + "@electron-forge/plugin-base": "7.2.0", + "@electron-forge/publisher-base": "7.2.0", + "@electron-forge/shared-types": "7.2.0", + "@electron-forge/template-base": "7.2.0", + "@electron-forge/template-vite": "7.2.0", + "@electron-forge/template-vite-typescript": "7.2.0", + "@electron-forge/template-webpack": "7.2.0", + "@electron-forge/template-webpack-typescript": "7.2.0", + "@electron-forge/tracer": "7.2.0", + "@electron/get": "^3.0.0", + "@electron/packager": "^18.0.0", + "@electron/rebuild": "^3.2.10", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "fast-glob": "^3.2.7", + "filenamify": "^4.1.0", + "find-up": "^5.0.0", + "fs-extra": "^10.0.0", + "got": "^11.8.5", + "interpret": "^3.1.1", + "listr2": "^5.0.3", + "lodash": "^4.17.20", + "log-symbols": "^4.0.0", + "node-fetch": "^2.6.7", + "progress": "^2.0.3", + "rechoir": "^0.8.0", + "resolve-package": "^1.0.1", + "semver": "^7.2.1", + "source-map-support": "^0.5.13", + "sudo-prompt": "^9.1.1", + "username": "^5.1.0", + "yarn-or-npm": "^3.0.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/core-utils": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.2.0.tgz", + "integrity": "sha512-PI1wETlF/+Cxm1m/IgURQ9S3LzHU70/S4CHmkw4xJg4wYVRTfiKpH2XRE9VqEJU854hEnsCGynAIn7/Z2h6SIA==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "@electron/rebuild": "^3.2.10", + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "find-up": "^5.0.0", + "fs-extra": "^10.0.0", + "log-symbols": "^4.0.0", + "semver": "^7.2.1", + "yarn-or-npm": "^3.0.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/maker-base": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.2.0.tgz", + "integrity": "sha512-5dCFiVo4WhSlLf/T9MP+jnMqP3qfmwvjCSiTRE08USeotNWhycztcFox94NbxMJkRt329tNeG2RRs7RzdCz21w==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "fs-extra": "^10.0.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/maker-deb": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-deb/-/maker-deb-7.2.0.tgz", + "integrity": "sha512-UYulMZpof+PIcapUFxQ5pVoSqa2FsS8crY8WGbVm1ALuknJUn4C2I37S8AujQH0l7oJRGnH95Y7Bcryyhe08yw==", + "dev": true, + "dependencies": { + "@electron-forge/maker-base": "7.2.0", + "@electron-forge/shared-types": "7.2.0" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-installer-debian": "^3.2.0" + } + }, + "node_modules/@electron-forge/maker-squirrel": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-squirrel/-/maker-squirrel-7.2.0.tgz", + "integrity": "sha512-SyPeFgJoMUcOPDM8+1AUPuseOqnl5YqnnjgKX9+YUIrsGKIsSz1cTtSOEu5R/l2yWNWFTmLnOlcuqIe7NayHBg==", + "dev": true, + "dependencies": { + "@electron-forge/maker-base": "7.2.0", + "@electron-forge/shared-types": "7.2.0", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + }, + "optionalDependencies": { + "electron-winstaller": "^5.0.0" + } + }, + "node_modules/@electron-forge/maker-zip": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/maker-zip/-/maker-zip-7.2.0.tgz", + "integrity": "sha512-U6FSSMcHogHDv+7SmF037lJ9m0stwwqyerw7Q6mD3jKQHX9GBxFApEzA5HSURGPAEBhPgPppYOSMGRB6LV5F2g==", + "dev": true, + "dependencies": { + "@electron-forge/maker-base": "7.2.0", + "@electron-forge/shared-types": "7.2.0", + "cross-zip": "^4.0.0", + "fs-extra": "^10.0.0", + "got": "^11.8.5" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-base": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.2.0.tgz", + "integrity": "sha512-c/pQK36BMBMKiemO68g1ZQOCXBA93x/aeX3lIXwK5bKVuaGt16Unfmby5Q7iIvY+/KsBuLYGkAder8HDN+4Nbw==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-vite": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/plugin-vite/-/plugin-vite-7.2.0.tgz", + "integrity": "sha512-gVQ98tNRVL1ildZgehdJWNogZq6WJnefayxPhT9zrWrRxNUKChRTugDAPrv8Og/fHwAT5em+wHOilqBr3X2K2A==", + "dev": true, + "dependencies": { + "@electron-forge/core-utils": "7.2.0", + "@electron-forge/plugin-base": "7.2.0", + "@electron-forge/shared-types": "7.2.0", + "@electron-forge/web-multi-logger": "7.2.0", + "chalk": "^4.0.0", + "debug": "^4.3.1", + "vite": "^4.1.1" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@electron-forge/plugin-vite/node_modules/vite": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", + "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/@electron-forge/publisher-base": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.2.0.tgz", + "integrity": "sha512-c0pwcQeMZi0S4iLlgA3pqm6ZdW2u7Ea4Ynat04Gw7su5GLtbrKRgYSL36ZRhzz7sgm4372niI0k91KaH5KToHg==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/publisher-github": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/publisher-github/-/publisher-github-7.2.0.tgz", + "integrity": "sha512-GWoDIxP4h2CuaGnpReJCvxiyWSF6lpbIpNgdtv6l6mdPKLHmSRownJ3aqVl4pD523d00Wuxrdv/wDxZ5RwyedQ==", + "dev": true, + "dependencies": { + "@electron-forge/publisher-base": "7.2.0", + "@electron-forge/shared-types": "7.2.0", + "@octokit/core": "^3.2.4", + "@octokit/plugin-retry": "^3.0.9", + "@octokit/rest": "^18.0.11", + "@octokit/types": "^6.1.2", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "mime-types": "^2.1.25" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/shared-types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.2.0.tgz", + "integrity": "sha512-d8i+pwPwBnlmFTRkq7QfaoRS9LywfyjDdHqQZuArFbL6NLAEbZ52irFiAE3NSLf4STew/BA6IK9sTPz3KRmvQw==", + "dev": true, + "dependencies": { + "@electron-forge/tracer": "7.2.0", + "@electron/packager": "^18.0.0", + "@electron/rebuild": "^3.2.10", + "listr2": "^5.0.3" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-base": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.2.0.tgz", + "integrity": "sha512-X7JrgQctgN0saFih/kKWVJ3KxiI1BpzdrkW58vs5H0kXXmA6UObE16/dWuKYfB06j0yIsfMbZ32Md1yAkgdCfg==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "fs-extra": "^10.0.0", + "username": "^5.1.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-vite": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.2.0.tgz", + "integrity": "sha512-Q5FSD+NVNMJKuAo/htQXpk3Q/eo116Xhx0zTzhSldAqpsgfxdAIJhl8TFmdVvCJIig1vEcLG2n/PgudxnuDuEQ==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "@electron-forge/template-base": "7.2.0", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-vite-typescript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.2.0.tgz", + "integrity": "sha512-knN3lxJY6UyXa2u5957K4ZyItCoCw22wrUhQARvdHOcgXvMFAcwvfEDT8zOQy6ki6A9W3cMHhSTys7dC8/ChVw==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "@electron-forge/template-base": "7.2.0", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-webpack": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.2.0.tgz", + "integrity": "sha512-h2LQ3vAzIraRqLUM5fKOLXknp7n5hrQXudRjO/vEEbm1a0jbl4yjp6liKk3yx8MFFO4eAHVDrXwRSsLR3a2Wew==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "@electron-forge/template-base": "7.2.0", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/template-webpack-typescript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.2.0.tgz", + "integrity": "sha512-eshvPcYXUgmpB+ts9/xRPvQexY46unfe0mGmLDaj8s/5fqCANgyUO5jusvMXlJdf3qwJ/rfi3jS0NuqnjsqskQ==", + "dev": true, + "dependencies": { + "@electron-forge/shared-types": "7.2.0", + "@electron-forge/template-base": "7.2.0", + "fs-extra": "^10.0.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron-forge/tracer": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.2.0.tgz", + "integrity": "sha512-EoJ07nptEuuY2fcs/bUWzIf11RQRx6Ch/dZ6A9WIRcFYe9cFrslQwvyUf0siY3jcqVvxETCz69JGuBxKGwak7A==", + "dev": true, + "dependencies": { + "chrome-trace-event": "^1.0.3" + }, + "engines": { + "node": ">= 14.17.5" + } + }, + "node_modules/@electron-forge/web-multi-logger": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@electron-forge/web-multi-logger/-/web-multi-logger-7.2.0.tgz", + "integrity": "sha512-RILwNWrcPvMIefpwho/xVu38cyjeAcJCfuJ9YpQDgsVyJzGtPVXbLeKCL8lepMu+I2j9lnYPMKkp2QzycLwMcg==", + "dev": true, + "dependencies": { + "express": "^4.17.1", + "express-ws": "^5.0.2", + "xterm": "^4.9.0", + "xterm-addon-fit": "^0.5.0", + "xterm-addon-search": "^0.8.0" + }, + "engines": { + "node": ">= 16.4.0" + } + }, + "node_modules/@electron/asar": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.8.tgz", + "integrity": "sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg==", + "dev": true, + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/asar/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@electron/get": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-3.0.0.tgz", + "integrity": "sha512-hLv4BYFiyrNRI+U0Mm2X7RxCCdJLkDUn8GCEp9QJzbLpZRko+UaLlCjOMkj6TEtirNLPyBA7y1SeGfnpOB21aQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@electron/notarize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.2.1.tgz", + "integrity": "sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.5.tgz", + "integrity": "sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==", + "dev": true, + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/packager": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.1.3.tgz", + "integrity": "sha512-21T5MxUf7DwV07IIes3jO/571mXCjOGVPdmYJFPCVDTimFiHQSW0Oy+OIGQaKBiNIXfnP29KylsCQbmds6O6Iw==", + "dev": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "@electron/get": "^3.0.0", + "@electron/notarize": "^2.1.0", + "@electron/osx-sign": "^1.0.5", + "@electron/universal": "^2.0.1", + "@electron/windows-sign": "^1.0.0", + "cross-spawn-windows-exe": "^1.2.0", + "debug": "^4.0.1", + "extract-zip": "^2.0.0", + "filenamify": "^4.1.0", + "fs-extra": "^11.1.0", + "galactus": "^1.0.0", + "get-package-info": "^1.0.0", + "junk": "^3.1.0", + "parse-author": "^2.0.0", + "plist": "^3.0.0", + "rcedit": "^4.0.0", + "resolve": "^1.1.6", + "semver": "^7.1.3", + "yargs-parser": "^21.1.1" + }, + "bin": { + "electron-packager": "bin/electron-packager.js" + }, + "engines": { + "node": ">= 16.13.0" + }, + "funding": { + "url": "https://github.com/electron/packager?sponsor=1" + } + }, + "node_modules/@electron/packager/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/rebuild": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.6.0.tgz", + "integrity": "sha512-zF4x3QupRU3uNGaP5X1wjpmcjfw1H87kyqZ00Tc3HvriV+4gmOGuvQjGNkrJuXdsApssdNyVwLsy+TaeTGGcVw==", + "dev": true, + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", + "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", + "dev": true, + "dependencies": { + "@electron/asar": "^3.2.7", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, + "engines": { + "node": ">=16.4" + } + }, + "node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/windows-sign": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.1.2.tgz", + "integrity": "sha512-eXEiZjDtxW3QORCWfRUarANPRTlH9B6At4jqBZJ0NzokSGutXQUVLPA6WmGpIhDW6w2yCMdHW1EJd1HrXtU5sg==", + "dev": true, + "dependencies": { + "cross-dirname": "^0.1.0", + "debug": "^4.3.4", + "fs-extra": "^11.1.1", + "minimist": "^1.2.8", + "postject": "^1.0.0-alpha.6" + }, + "bin": { + "electron-windows-sign": "bin/electron-windows-sign.js" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/windows-sign/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@malept/cross-spawn-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", + "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dev": true, + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", + "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.21.3", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", + "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.40.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.16.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", + "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.39.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-retry": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz", + "integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "bottleneck": "^2.15.3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dev": true, + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.41.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", + "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^12.11.0" + } + }, + "node_modules/@osm_borders/maritime_10m": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@osm_borders/maritime_10m/-/maritime_10m-1.1.0.tgz", + "integrity": "sha512-Mln0gqbYzjqNX7iGtEt3np16nfGwjwADTuUg7J5LQTqlqUBDxsWaxQmsKtkJCumvc/pl7QZu8lvEs41JMs+zbQ==" + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.0.tgz", + "integrity": "sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.0.tgz", + "integrity": "sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz", + "integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.0.tgz", + "integrity": "sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.0.tgz", + "integrity": "sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz", + "integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.0.tgz", + "integrity": "sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.0.tgz", + "integrity": "sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==", + "cpu": [ + "ppc64le" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.0.tgz", + "integrity": "sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.0.tgz", + "integrity": "sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz", + "integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.0.tgz", + "integrity": "sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.0.tgz", + "integrity": "sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.0.tgz", + "integrity": "sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.0.tgz", + "integrity": "sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, + "node_modules/@supabase/auth-js": { + "version": "2.63.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.63.0.tgz", + "integrity": "sha512-yIgcHnlgv24GxHtVGUhwGqAFDyJkPIC/xjx7HostN08A8yCy8HIfl4JEkTKyBqD1v1L05jNEJOUke4Lf4O1+Qg==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.2.2.tgz", + "integrity": "sha512-sJGq1nludmi7pY/fdtCpyY/pYonx7MfHdN408bqb736guWcVI1AChYVbI4kUM978EuOE4Ci6l7bUudfGg07QRw==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.0.tgz", + "integrity": "sha512-U4bwBOrhsXWqDjZiYNbVqMBtRGgIIYE0kE5ZNSwsIbeBWfr/UxOMrnkIQUBGIZRhpYW/tw1WnTdRl1AGNyaxcw==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.3.tgz", + "integrity": "sha512-lAp50s2n3FhGJFq+wTSXLNIDPw5Y0Wxrgt44eM5nLSA3jZNUUP3Oq2Ccd1CbZdVntPCWLZvJaU//pAd2NE+QnQ==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/ws": "^8.5.10", + "ws": "^8.14.2" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz", + "integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.42.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.42.0.tgz", + "integrity": "sha512-1PDqJiA4iG45w3AAu6xkccJ3wPqlGJUoz9CPhScRLLTStxhewYhz0mjryTpXz1kgtNHdUAsirALreezn8UZMjA==", + "dependencies": { + "@supabase/auth-js": "2.63.0", + "@supabase/functions-js": "2.2.2", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.15.0", + "@supabase/realtime-js": "2.9.3", + "@supabase/storage-js": "2.5.5" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@turf/bbox": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-6.5.0.tgz", + "integrity": "sha512-RBbLaao5hXTYyyg577iuMtDB8ehxMlUqHEJiMs8jT1GHkFhr6sYre3lmLsPeYEi/ZKj5TP5tt7fkzNdJ4GIVyw==", + "dependencies": { + "@turf/helpers": "^6.5.0", + "@turf/meta": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-contains": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-6.5.0.tgz", + "integrity": "sha512-4m8cJpbw+YQcKVGi8y0cHhBUnYT+QRfx6wzM4GI1IdtYH3p4oh/DOBJKrepQyiDzFDaNIjxuWXBh0ai1zVwOQQ==", + "dependencies": { + "@turf/bbox": "^6.5.0", + "@turf/boolean-point-in-polygon": "^6.5.0", + "@turf/boolean-point-on-line": "^6.5.0", + "@turf/helpers": "^6.5.0", + "@turf/invariant": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-point-in-polygon": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-6.5.0.tgz", + "integrity": "sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==", + "dependencies": { + "@turf/helpers": "^6.5.0", + "@turf/invariant": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/boolean-point-on-line": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-6.5.0.tgz", + "integrity": "sha512-A1BbuQ0LceLHvq7F/P7w3QvfpmZqbmViIUPHdNLvZimFNLo4e6IQunmzbe+8aSStH9QRZm3VOflyvNeXvvpZEQ==", + "dependencies": { + "@turf/helpers": "^6.5.0", + "@turf/invariant": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/helpers": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz", + "integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==", + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/invariant": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz", + "integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==", + "dependencies": { + "@turf/helpers": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@turf/meta": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-6.5.0.tgz", + "integrity": "sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA==", + "dependencies": { + "@turf/helpers": "^6.5.0" + }, + "funding": { + "url": "https://opencollective.com/turf" + } + }, + "node_modules/@types/better-sqlite3": { + "version": "7.6.9", + "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.9.tgz", + "integrity": "sha512-FvktcujPDj9XKMJQWFcl2vVl7OdRIqsSRX9b0acWwTmwLK9CF2eqo/FRcmMLNpugKoX/avA6pb7TorDLmpgTnQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/google.maps": { + "version": "3.55.7", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.7.tgz", + "integrity": "sha512-SlWFx0vo7RSAOC63+PTz8FeqLDaRYs7PrS/L0bZSKswxIN5TnCuckbeIwZpgD/S+DWalPteXfDbg5JsUER5Cyw==", + "dev": true + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "optional": true + }, + "node_modules/@types/node": { + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/phoenix": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz", + "integrity": "sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA==" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/tmi.js": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@types/tmi.js/-/tmi.js-1.8.6.tgz", + "integrity": "sha512-LVzNK7AxTMyh9qHLanAQR1o0I9XzfbIcXk85cx85igmCJHHO1Sm71sdhQ8Mj1WmRGzynPIoCXx6mVaFynWbsQw==", + "dev": true + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "dev": true + }, + "node_modules/@types/when-dom-ready": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/when-dom-ready/-/when-dom-ready-1.2.2.tgz", + "integrity": "sha512-9dxZKwe4Fzj6v6/RE5NJJilgwIMgvRySV4yxBMf6GniK47TjQIBKWAOTSSfOwOU5nSDYZA+KKocYsTsZ31XyUg==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz", + "integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/type-utils": "7.5.0", + "@typescript-eslint/utils": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz", + "integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz", + "integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz", + "integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.5.0", + "@typescript-eslint/utils": "7.5.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz", + "integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz", + "integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/visitor-keys": "7.5.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz", + "integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.5.0", + "@typescript-eslint/types": "7.5.0", + "@typescript-eslint/typescript-estree": "7.5.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz", + "integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.5.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", + "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vitest/expect": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.4.0.tgz", + "integrity": "sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==", + "dev": true, + "dependencies": { + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.4.0.tgz", + "integrity": "sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==", + "dev": true, + "dependencies": { + "@vitest/utils": "1.4.0", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.4.0.tgz", + "integrity": "sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==", + "dev": true, + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.4.0.tgz", + "integrity": "sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==", + "dev": true, + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==", + "dev": true, + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@volar/language-core": { + "version": "2.2.0-alpha.6", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.0-alpha.6.tgz", + "integrity": "sha512-GmT28LX2w4x82uuQqNN/P94VOCsZRHBbGcGe+5bFtA2hbIbH6f8tFdMfgXFtyhbft/pj6f3xl37xe+t+nomLIA==", + "dev": true, + "dependencies": { + "@volar/source-map": "2.2.0-alpha.6" + } + }, + "node_modules/@volar/source-map": { + "version": "2.2.0-alpha.6", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.0-alpha.6.tgz", + "integrity": "sha512-EztD2zoUopETY+ZCUZAGUHKgj4gOkY/2WnaOS+RSTc56xm85miSA4qOBS8Lt1Ruu5vV52WIZKHW/R9PbjkZWFA==", + "dev": true, + "dependencies": { + "muggle-string": "^0.4.0" + } + }, + "node_modules/@volar/typescript": { + "version": "2.2.0-alpha.6", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.0-alpha.6.tgz", + "integrity": "sha512-wTr0jO3wVXQ9FjBbWE2iX8GgDoiHp1Nttsb+tKk5IeUUb6f1uOjyeIXuS4KfeMBpCufthRO2st2O2uatAs/UXQ==", + "dev": true, + "dependencies": { + "@volar/language-core": "2.2.0-alpha.6", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", + "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.21", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-core/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", + "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", + "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.21", + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.7", + "postcss": "^8.4.35", + "source-map-js": "^1.0.2" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", + "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/eslint-config-prettier": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==", + "dev": true, + "dependencies": { + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.0" + }, + "peerDependencies": { + "eslint": ">= 8.0.0", + "prettier": ">= 3.0.0" + } + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz", + "integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "vue-eslint-parser": "^9.3.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "peerDependencies": { + "eslint": "^8.56.0", + "eslint-plugin-vue": "^9.0.0", + "typescript": ">=4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.11.tgz", + "integrity": "sha512-5ivg8Vem/yckzXI3L3n0mdKBPRcHSlsGt6/dpbEx42PcH3MIHAjSAJBYvENXeWJxv2ClQc8BS2mH1Ho2U7jZig==", + "dev": true, + "dependencies": { + "@volar/language-core": "~2.2.0-alpha.6", + "@vue/compiler-dom": "^3.4.0", + "@vue/shared": "^3.4.0", + "computeds": "^0.0.1", + "minimatch": "^9.0.3", + "path-browserify": "^1.0.1", + "vue-template-compiler": "^2.7.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/language-core/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vue/language-core/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz", + "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", + "dev": true, + "dependencies": { + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz", + "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.4.21", + "@vue/shared": "3.4.21" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", + "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", + "dev": true, + "dependencies": { + "@vue/runtime-core": "3.4.21", + "@vue/shared": "3.4.21", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz", + "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", + "dev": true, + "dependencies": { + "@vue/compiler-ssr": "3.4.21", + "@vue/shared": "3.4.21" + }, + "peerDependencies": { + "vue": "3.4.21" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", + "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==", + "dev": true + }, + "node_modules/@vueuse/core": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz", + "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==", + "dev": true, + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.9.0", + "@vueuse/shared": "10.9.0", + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz", + "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz", + "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==", + "dev": true, + "dependencies": { + "vue-demi": ">=0.14.7" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", + "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dev": true, + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asar": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/asar/-/asar-3.2.0.tgz", + "integrity": "sha512-COdw2ZQvKdFGFxXwX3oYh2/sOsJWJegrdJCGxnN4MZ7IULgRBp9P6665aqj9z1v9VwP4oP1hRBojRDQ//IGgAg==", + "deprecated": "Please use @electron/asar moving forward. There is no API change, just a package name change", + "dev": true, + "optional": true, + "dependencies": { + "chromium-pickle-js": "^0.2.0", + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + }, + "optionalDependencies": { + "@types/glob": "^7.1.1" + } + }, + "node_modules/asar/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/author-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", + "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "node_modules/better-sqlite3": { + "version": "9.4.5", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.4.5.tgz", + "integrity": "sha512-uFVyoyZR9BNcjSca+cp3MWCv6upAv+tbMC4SWM51NIMhoQOm4tjIkyxFO/ZsYdGAF61WJBgdzyJcz4OokJi0gQ==", + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "dev": true, + "optional": true + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", + "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true, + "optional": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/computeds": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/conf": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "dependencies": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/coordinate_to_country": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/coordinate_to_country/-/coordinate_to_country-1.1.0.tgz", + "integrity": "sha512-kLMIFZpnZb1W7KcJnTehWBTOLZjVnx0udZaHj8b5nN5Qmoj+mYQrWEhNm8lBDZm+r12BEIaZFhmrHgWkD6IAXQ==", + "dependencies": { + "@osm_borders/maritime_10m": "^1.1.0", + "geojson-geometries-lookup": "^0.5.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-dirname": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", + "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn-windows-exe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cross-spawn-windows-exe/-/cross-spawn-windows-exe-1.2.0.tgz", + "integrity": "sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-cross-spawn-windows-exe?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "@malept/cross-spawn-promise": "^1.1.0", + "is-wsl": "^2.2.0", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cross-spawn-windows-exe/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/cross-zip": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-4.0.0.tgz", + "integrity": "sha512-MEzGfZo0rqE10O/B+AEcCSJLZsrWuRUvmqJTqHNqBtALhaJc3E3ixLGLJNTRzEA2K34wbmOHC4fwYs9sVsdcCA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=12.10" + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "peer": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true + }, + "node_modules/debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "dependencies": { + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "optional": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/electron": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.2.0.tgz", + "integrity": "sha512-ALKrCN52RG4g9prx4DriXSPnY5WoiyRUCNp7zEVQuoiNOpHTNqMMpRidQAHzntV4hajF1LMWHVoBkwqIs1jHhg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-installer-common": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/electron-installer-common/-/electron-installer-common-0.10.3.tgz", + "integrity": "sha512-mYbP+6i+nHMIm0WZHXgGdmmXMe+KXncl6jZYQNcCF9C1WsNA9C5SZ2VP4TLQMSIoFO+X4ugkMEA5uld1bmyEvA==", + "dev": true, + "optional": true, + "dependencies": { + "@malept/cross-spawn-promise": "^1.0.0", + "asar": "^3.0.0", + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "glob": "^7.1.4", + "lodash": "^4.17.15", + "parse-author": "^2.0.0", + "semver": "^7.1.1", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "url": "https://github.com/electron-userland/electron-installer-common?sponsor=1" + }, + "optionalDependencies": { + "@types/fs-extra": "^9.0.1" + } + }, + "node_modules/electron-installer-common/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-common/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "optional": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-debian": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-installer-debian/-/electron-installer-debian-3.2.0.tgz", + "integrity": "sha512-58ZrlJ1HQY80VucsEIG9tQ//HrTlG6sfofA3nRGr6TmkX661uJyu4cMPPh6kXW+aHdq/7+q25KyQhDrXvRL7jw==", + "dev": true, + "optional": true, + "os": [ + "darwin", + "linux" + ], + "dependencies": { + "@malept/cross-spawn-promise": "^1.0.0", + "debug": "^4.1.1", + "electron-installer-common": "^0.10.2", + "fs-extra": "^9.0.0", + "get-folder-size": "^2.0.1", + "lodash": "^4.17.4", + "word-wrap": "^1.2.3", + "yargs": "^16.0.2" + }, + "bin": { + "electron-installer-debian": "src/cli.js" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-installer-debian/node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "optional": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/electron-installer-debian/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "optional": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/electron-installer-debian/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "optional": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-debian/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "optional": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-installer-debian/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-squirrel-startup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz", + "integrity": "sha512-Oce8mvgGdFmwr+DsAcXBmFK8jFfN6yaFAP9IvyhTfupM3nFkBku/7VS/mdtJteWumImkC6P+BKGsxScoDDkv9Q==", + "dependencies": { + "debug": "^2.2.0" + } + }, + "node_modules/electron-squirrel-startup/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/electron-squirrel-startup/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/electron-store": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.2.0.tgz", + "integrity": "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==", + "dependencies": { + "conf": "^10.2.0", + "type-fest": "^2.17.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-winstaller": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.3.0.tgz", + "integrity": "sha512-ml77/OmeeLFFc+dk3YCwPQrl8rthwYcAea6mMZPFq7cGXlpWyRmmT0LY73XdCukPnevguXJFs+4Xu+aGHJwFDA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash.template": "^4.2.2", + "temp": "^0.9.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "@electron/windows-sign": "^1.1.2" + } + }, + "node_modules/electron-winstaller/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/electron-winstaller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optional": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-winstaller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/electron/node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/electron/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/electron/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/electron/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", + "integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-vue": { + "version": "9.21.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.21.1.tgz", + "integrity": "sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "natural-compare": "^1.4.0", + "nth-check": "^2.1.1", + "postcss-selector-parser": "^6.0.13", + "semver": "^7.5.4", + "vue-eslint-parser": "^9.4.2", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-ws": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", + "integrity": "sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==", + "dev": true, + "dependencies": { + "ws": "^7.4.6" + }, + "engines": { + "node": ">=4.5.0" + }, + "peerDependencies": { + "express": "^4.0.0 || ^5.0.0-alpha.1" + } + }, + "node_modules/express-ws/node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", + "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/flora-colossus": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", + "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/format-duration": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/format-duration/-/format-duration-3.0.2.tgz", + "integrity": "sha512-pKzJDSRgK2lqAiPW3uizDaIJaJnataZclsahz25UMwfdryBGDa+1HlbXGjzpMvX/2kMh4O0sNevFXKaEfCjHsA==" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/galactus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", + "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "flora-colossus": "^2.0.0", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/gar": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.4.tgz", + "integrity": "sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==", + "dev": true, + "optional": true + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/geojson-geometries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/geojson-geometries/-/geojson-geometries-2.0.0.tgz", + "integrity": "sha512-HKljxKnbJrdkr7ijg5/nvcr1b81HP+C/rS48cJwRb3xEqiEynlGkRVkQ/msopw+EE3gf7DjEKdZyEGMck0bOpw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/geojson-geometries-lookup": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/geojson-geometries-lookup/-/geojson-geometries-lookup-0.5.0.tgz", + "integrity": "sha512-AfadxaBda6VTwwX4USLiVofFaz0HIjubC7ZC15hGTvc8K0di3pmCNWGFotKJeURSxYPbJLFoet34X3JrIKFX4A==", + "dependencies": { + "@turf/bbox": "^6.0.1", + "@turf/boolean-contains": "^6.0.1", + "geojson-geometries": "^2.0.0", + "rbush": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-folder-size": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/get-folder-size/-/get-folder-size-2.0.1.tgz", + "integrity": "sha512-+CEb+GDCM7tkOS2wdMKTn9vU7DgnKUTuDlehkNJKNSovdCOVxs14OfKCk4cvSaR3za4gj+OBdl9opPN9xrJ0zA==", + "dev": true, + "optional": true, + "dependencies": { + "gar": "^1.0.4", + "tiny-each-async": "2.0.3" + }, + "bin": { + "get-folder-size": "bin/get-folder-size" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-installed-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/get-installed-path/-/get-installed-path-2.1.1.tgz", + "integrity": "sha512-Qkn9eq6tW5/q9BDVdMpB8tOHljX9OSP0jRC5TRNVA4qRc839t4g8KQaR8t0Uv0EFVL0MlyG7m/ofjEgAROtYsA==", + "dev": true, + "dependencies": { + "global-modules": "1.0.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-info": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", + "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", + "dev": true, + "dependencies": { + "bluebird": "^3.1.1", + "debug": "^2.2.0", + "lodash.get": "^4.0.0", + "read-pkg-up": "^2.0.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/get-package-info/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/get-package-info/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, + "node_modules/github-url-to-object": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/github-url-to-object/-/github-url-to-object-4.0.6.tgz", + "integrity": "sha512-NaqbYHMUAlPcmWFdrAB7bcxrNIiiJWJe8s/2+iOc9vlcHlwHqSGrPk+Yi3nu6ebTwgsZEa7igz+NH2vEq3gYwQ==", + "dependencies": { + "is-url": "^1.1.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "optional": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==" + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "optional": true + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/listr2": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.19", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.8.0", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true, + "optional": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "optional": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "optional": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", + "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/match-sorter": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", + "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "remove-accents": "0.5.0" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/mlly": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.5.0.tgz", + "integrity": "sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-abi": { + "version": "3.54.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", + "integrity": "sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-api-version": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz", + "integrity": "sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-author": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", + "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", + "dev": true, + "dependencies": { + "author-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-types": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", + "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", + "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", + "dev": true, + "dependencies": { + "commander": "^9.4.0" + }, + "bin": { + "postject": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/postject/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/quickselect": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", + "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rbush": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", + "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", + "dependencies": { + "quickselect": "^2.0.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rcedit": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-4.0.1.tgz", + "integrity": "sha512-bZdaQi34krFWhrDn+O53ccBDw0MkAT2Vhu75SqhtvhQu4OPyFM4RoVheyYiVQYdjhUi6EJMVWQ0tR6bCIYVkUg==", + "dev": true, + "dependencies": { + "cross-spawn-windows-exe": "^1.1.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/read-binary-file-arch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", + "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-package/-/resolve-package-1.0.1.tgz", + "integrity": "sha512-rzB7NnQpOkPHBWFPP3prUMqOP6yg3HkRGgcvR+lDyvyHoY3fZLFLYDkPXh78SPVBAE6VTCk/V+j8we4djg6o4g==", + "dev": true, + "dependencies": { + "get-installed-path": "^2.0.3" + }, + "engines": { + "node": ">=4", + "npm": ">=2" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rollup": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz", + "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.14.0", + "@rollup/rollup-android-arm64": "4.14.0", + "@rollup/rollup-darwin-arm64": "4.14.0", + "@rollup/rollup-darwin-x64": "4.14.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.14.0", + "@rollup/rollup-linux-arm64-gnu": "4.14.0", + "@rollup/rollup-linux-arm64-musl": "4.14.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.14.0", + "@rollup/rollup-linux-riscv64-gnu": "4.14.0", + "@rollup/rollup-linux-s390x-gnu": "4.14.0", + "@rollup/rollup-linux-x64-gnu": "4.14.0", + "@rollup/rollup-linux-x64-musl": "4.14.0", + "@rollup/rollup-win32-arm64-msvc": "4.14.0", + "@rollup/rollup-win32-ia32-msvc": "4.14.0", + "@rollup/rollup-win32-x64-msvc": "4.14.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true + }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "optional": true + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io-client": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", + "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz", + "integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz", + "integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sudo-prompt": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", + "integrity": "sha512-Mu7R0g4ig9TUuGSxJavny5Rv0egCEtpZRNMrZaYS1vxkiIxGiGUwoezU3LazIQ+KE04hTrTfNPgxU5gzi7F5Pw==", + "dev": true + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svgo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", + "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dev": true, + "optional": true, + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "optional": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tiny-each-async": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tiny-each-async/-/tiny-each-async-2.0.3.tgz", + "integrity": "sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA==", + "dev": true, + "optional": true + }, + "node_modules/tinybench": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", + "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", + "dev": true + }, + "node_modules/tinypool": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", + "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tmi.js": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/tmi.js/-/tmi.js-1.8.5.tgz", + "integrity": "sha512-A9qrydfe1e0VWM9MViVhhxVgvLpnk7pFShVUWePsSTtoi+A1X+Zjdoa7OJd7/YsgHXGj3GkNEvnWop/1WwZuew==", + "dependencies": { + "node-fetch": "^2.6.1", + "ws": "^8.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "optional": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "optional": true, + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", + "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", + "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-electron-app": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/update-electron-app/-/update-electron-app-3.0.0.tgz", + "integrity": "sha512-Ccs46fgUEcMpSRPMNw82DFMux2MGi5tkKkEpV723JmtPNI3qAtxvTeiYkKczN2/LehA3U7JGrGr4MhraxGdRTw==", + "dependencies": { + "github-url-to-object": "^4.0.4", + "is-url": "^1.2.4", + "ms": "^2.1.1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/username": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", + "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "mem": "^4.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", + "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", + "integrity": "sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-svg-loader": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/vite-svg-loader/-/vite-svg-loader-5.1.0.tgz", + "integrity": "sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==", + "dev": true, + "dependencies": { + "svgo": "^3.0.2" + }, + "peerDependencies": { + "vue": ">=3.2.13" + } + }, + "node_modules/vitest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", + "integrity": "sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.4.0", + "@vitest/runner": "1.4.0", + "@vitest/snapshot": "1.4.0", + "@vitest/spy": "1.4.0", + "@vitest/utils": "1.4.0", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.2", + "vite": "^5.0.0", + "vite-node": "1.4.0", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.4.0", + "@vitest/ui": "1.4.0", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/vitest/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vitest/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/vue": { + "version": "3.4.21", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz", + "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.4.21", + "@vue/compiler-sfc": "3.4.21", + "@vue/runtime-dom": "3.4.21", + "@vue/server-renderer": "3.4.21", + "@vue/shared": "3.4.21" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-eslint-parser": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz", + "integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.6" + }, + "engines": { + "node": "^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", + "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", + "dev": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/vue-tsc": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.11.tgz", + "integrity": "sha512-dl5MEU4VGZdQFGBnKfPpAfV3SQmBDWs9o4YhUPvDmwk+zmb/RprzFJK2sagR6EWazogZhXENvykd3wBXWS9kng==", + "dev": true, + "dependencies": { + "@volar/typescript": "~2.2.0-alpha.6", + "@vue/language-core": "2.0.11", + "semver": "^7.5.4" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/vue3-draggable-resizable": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/vue3-draggable-resizable/-/vue3-draggable-resizable-1.6.5.tgz", + "integrity": "sha512-31142E31fGNnq3HKqvmFLSsqIbhck7TyGuQWhUKrDw6DOcGAuRx4ddRjaxvT6fe7dgeKH53qAh+i0ZlWtPLl2g==" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/when-dom-ready": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/when-dom-ready/-/when-dom-ready-1.2.12.tgz", + "integrity": "sha512-nEy7UvAylNMfOTTKE2c7QTFR2fyqTRaL/f+tuTpE4zU7iAF7Pk7aLmw6jZvhrwUTcK6pmnXFc0/N0Kzi/PHmEg==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", + "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xterm": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.19.0.tgz", + "integrity": "sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ==", + "dev": true + }, + "node_modules/xterm-addon-fit": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz", + "integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==", + "dev": true, + "peerDependencies": { + "xterm": "^4.0.0" + } + }, + "node_modules/xterm-addon-search": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/xterm-addon-search/-/xterm-addon-search-0.8.2.tgz", + "integrity": "sha512-I1863mjn8P6uVrqm/X+btalVsqjAKLhnhpbP7SavAOpEkI1jJhbHU2UTp7NjeRtcKTks6UWk/ycgds5snDSejg==", + "dev": true, + "peerDependencies": { + "xterm": "^4.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yarn-or-npm": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/yarn-or-npm/-/yarn-or-npm-3.0.1.tgz", + "integrity": "sha512-fTiQP6WbDAh5QZAVdbMQkecZoahnbOjClTQhzv74WX5h2Uaidj1isf9FDes11TKtsZ0/ZVfZsqZ+O3x6aLERHQ==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.5", + "pkg-dir": "^4.2.0" + }, + "bin": { + "yarn-or-npm": "bin/index.js", + "yon": "bin/index.js" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/yarn-or-npm/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/yarn-or-npm/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yarn-or-npm/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/yarn-or-npm/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yarn-or-npm/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yarn-or-npm/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } } diff --git a/package.json b/package.json index 4bf5463..5bfe5f4 100644 --- a/package.json +++ b/package.json @@ -1,144 +1,66 @@ { - "name": "chatguessr", - "productName": "ChatGuessr", - "version": "2.3.4", - "description": "The original GeoGuessr Twitch Chatbot", - "author": "ChatGuessr", - "license": "MIT", - "main": "./dist/cg-main/main.js", - "repository": "https://github.com/tzhf/chatguessr", - "dependencies": { - "@sentry/electron": "^4.1.1", - "@supabase/supabase-js": "^2.1.0", - "@vueuse/core": "^9.13.0", - "axios": "^1.1.3", - "better-sqlite3": "^8.0.0", - "coordinate_to_country": "^1.1.0", - "datatables.net": "^1.11.3", - "datatables.net-buttons": "^2.0.1", - "datatables.net-plugins": "^1.10.24", - "datatables.net-scroller": "^2.0.5", - "dotenv": "^16.0.3", - "electron-squirrel-startup": "^1.0.0", - "electron-store": "^8.0.1", - "find-up": "^5.0.0", - "format-duration": "^3.0.2", - "jquery": "^3.6.0", - "jquery-ui-dist": "^1.12.1", - "match-sorter": "^6.3.1", - "p-map": "^4.0.0", - "socket.io-client": "^4.4.1", - "tmi.js": "^1.8.5", - "update-electron-app": "^2.0.1", - "vue": "^3.2.47", - "when-dom-ready": "^1.2.12" - }, - "devDependencies": { - "@electron-forge/cli": "^6.0.0", - "@electron-forge/maker-deb": "^6.0.0", - "@electron-forge/maker-squirrel": "^6.0.0", - "@electron-forge/maker-zip": "^6.0.0", - "@electron-forge/publisher-github": "^6.0.0", - "@parcel/transformer-inline-string": "^2.0.0", - "@parcel/transformer-vue": "^2.8.3", - "@tsconfig/node16": "^1.0.3", - "@types/better-sqlite3": "^7.6.1", - "@types/datatables.net-buttons": "^1.4.7", - "@types/datatables.net-scroller": "^1.4.1", - "@types/google.maps": "^3.45.6", - "@types/jquery": "^3.5.7", - "@types/jqueryui": "^1.12.16", - "@types/node": "^17.0.18", - "@types/tmi.js": "^1.8.0", - "@types/when-dom-ready": "^1.2.0", - "electron": "^22.0.3", - "parcel": "^2.0.0", - "typescript": "^4.4.4", - "vitest": "^0.34.2", - "vue-tsc": "^1.2.0" - }, - "scripts": { - "start": "parcel build --no-optimize && electron-forge start", - "package": "parcel build && electron-forge package", - "make": "parcel build && electron-forge make", - "publish": "parcel build && electron-forge publish", - "typecheck": "vue-tsc --noEmit", - "test": "vitest run" - }, - "config": { - "forge": { - "packagerConfig": { - "asar": true, - "ignore": "\\.parcel-cache", - "icon": "build/icon", - "executableName": "chatguessr" - }, - "makers": [ - { - "name": "@electron-forge/maker-squirrel", - "config": { - "name": "chatguessr", - "setupIcon": "build/icon.ico", - "loadingGif": "build/icon_installer.gif", - "iconUrl": "file://build/icon.ico" - } - }, - { - "name": "@electron-forge/maker-zip", - "platforms": [ - "darwin" - ] - }, - { - "name": "@electron-forge/maker-deb", - "config": { - "options": { - "bin": "chatguessr" - } - } - } - ], - "publishers": [ - { - "name": "@electron-forge/publisher-github", - "config": { - "repository": { - "owner": "tzhf", - "name": "chatguessr" - } - } - } - ] - } - }, - "targets": { - "cg-main": { - "context": "electron-main", - "source": "./src/main.js" - }, - "cg-preload": { - "context": "electron-renderer", - "source": "./src/preload.ts", - "scopeHoist": false - }, - "cg-renderer": { - "context": "browser", - "source": "./src/renderer.js" - }, - "auth-preload": { - "context": "electron-renderer", - "source": "./src/Windows/auth/preload.js" - }, - "auth": { - "context": "browser", - "source": "./src/Windows/auth/index.html", - "publicUrl": "." - }, - "settings": { - "context": "electron-renderer", - "outputFormat": "commonjs", - "source": "./src/Windows/settings/settings.html", - "publicUrl": "." - } - } + "name": "chatguessr", + "version": "3.0.0", + "description": "ChatGuessr", + "repository": "https://github.com/tzhf/chatguessr", + "homepage": "https://chatguessr.com", + "main": ".vite/build/main.js", + "author": { + "name": "ChatGuessr", + "email": "chatguessr@gmail.com" + }, + "license": "MIT", + "scripts": { + "dev": "npm run typecheck && electron-forge start", + "typecheck": "npm run typecheck:node && npm run typecheck:web", + "typecheck:node": "tsc -p tsconfig.node.json", + "typecheck:web": "vue-tsc -p tsconfig.web.json", + "lint": "eslint . --ext .js,.cjs,.mjs,.ts,.vue --fix", + "format": "prettier 'src/**/*.{ts,vue,json}' --write", + "package": "electron-forge package", + "make": "electron-forge make", + "publish": "electron-forge publish", + "test": "vitest run" + }, + "dependencies": { + "@supabase/supabase-js": "^2.42.0", + "axios": "^1.6.8", + "better-sqlite3": "^9.4.5", + "coordinate_to_country": "^1.1.0", + "electron-squirrel-startup": "^1.0.0", + "electron-store": "^8.2.0", + "format-duration": "^3.0.2", + "match-sorter": "^6.3.4", + "socket.io-client": "^4.7.5", + "tmi.js": "^1.8.5", + "update-electron-app": "^3.0.0", + "vue3-draggable-resizable": "^1.6.5", + "when-dom-ready": "^1.2.12" + }, + "devDependencies": { + "@electron-forge/cli": "^7.2.0", + "@electron-forge/maker-deb": "^7.2.0", + "@electron-forge/maker-squirrel": "^7.2.0", + "@electron-forge/maker-zip": "^7.2.0", + "@electron-forge/plugin-vite": "^7.2.0", + "@electron-forge/publisher-github": "^7.2.0", + "@types/better-sqlite3": "^7.6.8", + "@types/google.maps": "^3.55.7", + "@types/tmi.js": "^1.8.6", + "@types/when-dom-ready": "^1.2.2", + "@typescript-eslint/eslint-plugin": "^7.5.0", + "@vitejs/plugin-vue": "^5.0.4", + "@vue/eslint-config-prettier": "^9.0.0", + "@vue/eslint-config-typescript": "^13.0.0", + "@vueuse/core": "^10.9.0", + "electron": "^29.2.0", + "eslint": "^8.57.0", + "prettier": "^3.2.5", + "ts-node": "^10.9.2", + "typescript": "^5.4.4", + "vite-svg-loader": "^5.1.0", + "vitest": "^1.4.0", + "vue": "^3.4.21", + "vue-tsc": "^2.0.11" + } } diff --git a/public/assets/avatar-default.jpg b/public/assets/avatar-default.jpg new file mode 100644 index 0000000..54d85a0 Binary files /dev/null and b/public/assets/avatar-default.jpg differ diff --git a/assets/flags/AD.svg b/public/assets/flags/AD.svg similarity index 100% rename from assets/flags/AD.svg rename to public/assets/flags/AD.svg diff --git a/assets/flags/AE.svg b/public/assets/flags/AE.svg similarity index 100% rename from assets/flags/AE.svg rename to public/assets/flags/AE.svg diff --git a/assets/flags/AF.svg b/public/assets/flags/AF.svg similarity index 100% rename from assets/flags/AF.svg rename to public/assets/flags/AF.svg diff --git a/assets/flags/AG.svg b/public/assets/flags/AG.svg similarity index 100% rename from assets/flags/AG.svg rename to public/assets/flags/AG.svg diff --git a/assets/flags/AI.svg b/public/assets/flags/AI.svg similarity index 100% rename from assets/flags/AI.svg rename to public/assets/flags/AI.svg diff --git a/assets/flags/AL.svg b/public/assets/flags/AL.svg similarity index 100% rename from assets/flags/AL.svg rename to public/assets/flags/AL.svg diff --git a/assets/flags/AM.svg b/public/assets/flags/AM.svg similarity index 100% rename from assets/flags/AM.svg rename to public/assets/flags/AM.svg diff --git a/assets/flags/AO.svg b/public/assets/flags/AO.svg similarity index 100% rename from assets/flags/AO.svg rename to public/assets/flags/AO.svg diff --git a/assets/flags/AQ.svg b/public/assets/flags/AQ.svg similarity index 100% rename from assets/flags/AQ.svg rename to public/assets/flags/AQ.svg diff --git a/assets/flags/AR.svg b/public/assets/flags/AR.svg similarity index 100% rename from assets/flags/AR.svg rename to public/assets/flags/AR.svg diff --git a/assets/flags/AS.svg b/public/assets/flags/AS.svg similarity index 100% rename from assets/flags/AS.svg rename to public/assets/flags/AS.svg diff --git a/assets/flags/AT.svg b/public/assets/flags/AT.svg similarity index 100% rename from assets/flags/AT.svg rename to public/assets/flags/AT.svg diff --git a/assets/flags/AU.svg b/public/assets/flags/AU.svg similarity index 100% rename from assets/flags/AU.svg rename to public/assets/flags/AU.svg diff --git a/assets/flags/AUABORIGINAL.svg b/public/assets/flags/AUABORIGINAL.svg similarity index 100% rename from assets/flags/AUABORIGINAL.svg rename to public/assets/flags/AUABORIGINAL.svg diff --git a/assets/flags/AW.svg b/public/assets/flags/AW.svg similarity index 100% rename from assets/flags/AW.svg rename to public/assets/flags/AW.svg diff --git a/assets/flags/AX.svg b/public/assets/flags/AX.svg similarity index 100% rename from assets/flags/AX.svg rename to public/assets/flags/AX.svg diff --git a/assets/flags/AZ.svg b/public/assets/flags/AZ.svg similarity index 100% rename from assets/flags/AZ.svg rename to public/assets/flags/AZ.svg diff --git a/assets/flags/BA.svg b/public/assets/flags/BA.svg similarity index 100% rename from assets/flags/BA.svg rename to public/assets/flags/BA.svg diff --git a/assets/flags/BB.svg b/public/assets/flags/BB.svg similarity index 100% rename from assets/flags/BB.svg rename to public/assets/flags/BB.svg diff --git a/assets/flags/BD.svg b/public/assets/flags/BD.svg similarity index 100% rename from assets/flags/BD.svg rename to public/assets/flags/BD.svg diff --git a/assets/flags/BE.svg b/public/assets/flags/BE.svg similarity index 100% rename from assets/flags/BE.svg rename to public/assets/flags/BE.svg diff --git a/assets/flags/BF.svg b/public/assets/flags/BF.svg similarity index 100% rename from assets/flags/BF.svg rename to public/assets/flags/BF.svg diff --git a/assets/flags/BG.svg b/public/assets/flags/BG.svg similarity index 100% rename from assets/flags/BG.svg rename to public/assets/flags/BG.svg diff --git a/assets/flags/BH.svg b/public/assets/flags/BH.svg similarity index 100% rename from assets/flags/BH.svg rename to public/assets/flags/BH.svg diff --git a/assets/flags/BI.svg b/public/assets/flags/BI.svg similarity index 100% rename from assets/flags/BI.svg rename to public/assets/flags/BI.svg diff --git a/assets/flags/BJ.svg b/public/assets/flags/BJ.svg similarity index 100% rename from assets/flags/BJ.svg rename to public/assets/flags/BJ.svg diff --git a/assets/flags/BL.svg b/public/assets/flags/BL.svg similarity index 100% rename from assets/flags/BL.svg rename to public/assets/flags/BL.svg diff --git a/assets/flags/BLACK.svg b/public/assets/flags/BLACK.svg similarity index 100% rename from assets/flags/BLACK.svg rename to public/assets/flags/BLACK.svg diff --git a/assets/flags/BM.svg b/public/assets/flags/BM.svg similarity index 100% rename from assets/flags/BM.svg rename to public/assets/flags/BM.svg diff --git a/assets/flags/BN.svg b/public/assets/flags/BN.svg similarity index 100% rename from assets/flags/BN.svg rename to public/assets/flags/BN.svg diff --git a/assets/flags/BO.svg b/public/assets/flags/BO.svg similarity index 100% rename from assets/flags/BO.svg rename to public/assets/flags/BO.svg diff --git a/assets/flags/BR.svg b/public/assets/flags/BR.svg similarity index 100% rename from assets/flags/BR.svg rename to public/assets/flags/BR.svg diff --git a/assets/flags/BS.svg b/public/assets/flags/BS.svg similarity index 100% rename from assets/flags/BS.svg rename to public/assets/flags/BS.svg diff --git a/assets/flags/BT.svg b/public/assets/flags/BT.svg similarity index 100% rename from assets/flags/BT.svg rename to public/assets/flags/BT.svg diff --git a/assets/flags/BV.svg b/public/assets/flags/BV.svg similarity index 100% rename from assets/flags/BV.svg rename to public/assets/flags/BV.svg diff --git a/assets/flags/BW.svg b/public/assets/flags/BW.svg similarity index 100% rename from assets/flags/BW.svg rename to public/assets/flags/BW.svg diff --git a/assets/flags/BY.svg b/public/assets/flags/BY.svg similarity index 100% rename from assets/flags/BY.svg rename to public/assets/flags/BY.svg diff --git a/assets/flags/BZ.svg b/public/assets/flags/BZ.svg similarity index 100% rename from assets/flags/BZ.svg rename to public/assets/flags/BZ.svg diff --git a/assets/flags/BZH.svg b/public/assets/flags/BZH.svg similarity index 100% rename from assets/flags/BZH.svg rename to public/assets/flags/BZH.svg diff --git a/assets/flags/CA.svg b/public/assets/flags/CA.svg similarity index 100% rename from assets/flags/CA.svg rename to public/assets/flags/CA.svg diff --git a/assets/flags/CC.svg b/public/assets/flags/CC.svg similarity index 100% rename from assets/flags/CC.svg rename to public/assets/flags/CC.svg diff --git a/assets/flags/CD.svg b/public/assets/flags/CD.svg similarity index 100% rename from assets/flags/CD.svg rename to public/assets/flags/CD.svg diff --git a/assets/flags/CF.svg b/public/assets/flags/CF.svg similarity index 100% rename from assets/flags/CF.svg rename to public/assets/flags/CF.svg diff --git a/assets/flags/CG.svg b/public/assets/flags/CG.svg similarity index 100% rename from assets/flags/CG.svg rename to public/assets/flags/CG.svg diff --git a/assets/flags/CH.svg b/public/assets/flags/CH.svg similarity index 100% rename from assets/flags/CH.svg rename to public/assets/flags/CH.svg diff --git a/assets/flags/CHECKERED.svg b/public/assets/flags/CHECKERED.svg similarity index 100% rename from assets/flags/CHECKERED.svg rename to public/assets/flags/CHECKERED.svg diff --git a/assets/flags/CI.svg b/public/assets/flags/CI.svg similarity index 100% rename from assets/flags/CI.svg rename to public/assets/flags/CI.svg diff --git a/assets/flags/CK.svg b/public/assets/flags/CK.svg similarity index 100% rename from assets/flags/CK.svg rename to public/assets/flags/CK.svg diff --git a/assets/flags/CL.svg b/public/assets/flags/CL.svg similarity index 100% rename from assets/flags/CL.svg rename to public/assets/flags/CL.svg diff --git a/assets/flags/CM.svg b/public/assets/flags/CM.svg similarity index 100% rename from assets/flags/CM.svg rename to public/assets/flags/CM.svg diff --git a/assets/flags/CN.svg b/public/assets/flags/CN.svg similarity index 100% rename from assets/flags/CN.svg rename to public/assets/flags/CN.svg diff --git a/assets/flags/CO.svg b/public/assets/flags/CO.svg similarity index 100% rename from assets/flags/CO.svg rename to public/assets/flags/CO.svg diff --git a/assets/flags/CR.svg b/public/assets/flags/CR.svg similarity index 100% rename from assets/flags/CR.svg rename to public/assets/flags/CR.svg diff --git a/assets/flags/CU.svg b/public/assets/flags/CU.svg similarity index 100% rename from assets/flags/CU.svg rename to public/assets/flags/CU.svg diff --git a/assets/flags/CV.svg b/public/assets/flags/CV.svg similarity index 100% rename from assets/flags/CV.svg rename to public/assets/flags/CV.svg diff --git a/assets/flags/CW.svg b/public/assets/flags/CW.svg similarity index 100% rename from assets/flags/CW.svg rename to public/assets/flags/CW.svg diff --git a/assets/flags/CX.svg b/public/assets/flags/CX.svg similarity index 100% rename from assets/flags/CX.svg rename to public/assets/flags/CX.svg diff --git a/assets/flags/CY.svg b/public/assets/flags/CY.svg similarity index 100% rename from assets/flags/CY.svg rename to public/assets/flags/CY.svg diff --git a/assets/flags/CZ.svg b/public/assets/flags/CZ.svg similarity index 100% rename from assets/flags/CZ.svg rename to public/assets/flags/CZ.svg diff --git a/assets/flags/DE.svg b/public/assets/flags/DE.svg similarity index 100% rename from assets/flags/DE.svg rename to public/assets/flags/DE.svg diff --git a/assets/flags/DJ.svg b/public/assets/flags/DJ.svg similarity index 100% rename from assets/flags/DJ.svg rename to public/assets/flags/DJ.svg diff --git a/assets/flags/DK.svg b/public/assets/flags/DK.svg similarity index 100% rename from assets/flags/DK.svg rename to public/assets/flags/DK.svg diff --git a/assets/flags/DM.svg b/public/assets/flags/DM.svg similarity index 100% rename from assets/flags/DM.svg rename to public/assets/flags/DM.svg diff --git a/assets/flags/DO.svg b/public/assets/flags/DO.svg similarity index 100% rename from assets/flags/DO.svg rename to public/assets/flags/DO.svg diff --git a/assets/flags/DZ.svg b/public/assets/flags/DZ.svg similarity index 100% rename from assets/flags/DZ.svg rename to public/assets/flags/DZ.svg diff --git a/assets/flags/EC.svg b/public/assets/flags/EC.svg similarity index 100% rename from assets/flags/EC.svg rename to public/assets/flags/EC.svg diff --git a/assets/flags/EE.svg b/public/assets/flags/EE.svg similarity index 100% rename from assets/flags/EE.svg rename to public/assets/flags/EE.svg diff --git a/assets/flags/EG.svg b/public/assets/flags/EG.svg similarity index 100% rename from assets/flags/EG.svg rename to public/assets/flags/EG.svg diff --git a/assets/flags/EH.svg b/public/assets/flags/EH.svg similarity index 100% rename from assets/flags/EH.svg rename to public/assets/flags/EH.svg diff --git a/assets/flags/ER.svg b/public/assets/flags/ER.svg similarity index 100% rename from assets/flags/ER.svg rename to public/assets/flags/ER.svg diff --git a/assets/flags/ES.svg b/public/assets/flags/ES.svg similarity index 100% rename from assets/flags/ES.svg rename to public/assets/flags/ES.svg diff --git a/assets/flags/ESCT.svg b/public/assets/flags/ESCT.svg similarity index 100% rename from assets/flags/ESCT.svg rename to public/assets/flags/ESCT.svg diff --git a/assets/flags/ESGA.svg b/public/assets/flags/ESGA.svg similarity index 100% rename from assets/flags/ESGA.svg rename to public/assets/flags/ESGA.svg diff --git a/assets/flags/ESPV.svg b/public/assets/flags/ESPV.svg similarity index 100% rename from assets/flags/ESPV.svg rename to public/assets/flags/ESPV.svg diff --git a/assets/flags/ET.svg b/public/assets/flags/ET.svg similarity index 100% rename from assets/flags/ET.svg rename to public/assets/flags/ET.svg diff --git a/assets/flags/EU.svg b/public/assets/flags/EU.svg similarity index 100% rename from assets/flags/EU.svg rename to public/assets/flags/EU.svg diff --git a/assets/flags/FI.svg b/public/assets/flags/FI.svg similarity index 100% rename from assets/flags/FI.svg rename to public/assets/flags/FI.svg diff --git a/assets/flags/FJ.svg b/public/assets/flags/FJ.svg similarity index 100% rename from assets/flags/FJ.svg rename to public/assets/flags/FJ.svg diff --git a/assets/flags/FK.svg b/public/assets/flags/FK.svg similarity index 100% rename from assets/flags/FK.svg rename to public/assets/flags/FK.svg diff --git a/assets/flags/FM.svg b/public/assets/flags/FM.svg similarity index 100% rename from assets/flags/FM.svg rename to public/assets/flags/FM.svg diff --git a/assets/flags/FO.svg b/public/assets/flags/FO.svg similarity index 100% rename from assets/flags/FO.svg rename to public/assets/flags/FO.svg diff --git a/assets/flags/FR.svg b/public/assets/flags/FR.svg similarity index 100% rename from assets/flags/FR.svg rename to public/assets/flags/FR.svg diff --git a/assets/flags/FRBRE.svg b/public/assets/flags/FRBRE.svg similarity index 100% rename from assets/flags/FRBRE.svg rename to public/assets/flags/FRBRE.svg diff --git a/assets/flags/FRCOR.svg b/public/assets/flags/FRCOR.svg similarity index 100% rename from assets/flags/FRCOR.svg rename to public/assets/flags/FRCOR.svg diff --git a/assets/flags/GA.svg b/public/assets/flags/GA.svg similarity index 100% rename from assets/flags/GA.svg rename to public/assets/flags/GA.svg diff --git a/assets/flags/GB.svg b/public/assets/flags/GB.svg similarity index 100% rename from assets/flags/GB.svg rename to public/assets/flags/GB.svg diff --git a/assets/flags/GBENG.svg b/public/assets/flags/GBENG.svg similarity index 100% rename from assets/flags/GBENG.svg rename to public/assets/flags/GBENG.svg diff --git a/assets/flags/GBSCT.svg b/public/assets/flags/GBSCT.svg similarity index 100% rename from assets/flags/GBSCT.svg rename to public/assets/flags/GBSCT.svg diff --git a/assets/flags/GBWLS.svg b/public/assets/flags/GBWLS.svg similarity index 100% rename from assets/flags/GBWLS.svg rename to public/assets/flags/GBWLS.svg diff --git a/assets/flags/GD.svg b/public/assets/flags/GD.svg similarity index 100% rename from assets/flags/GD.svg rename to public/assets/flags/GD.svg diff --git a/assets/flags/GE.svg b/public/assets/flags/GE.svg similarity index 100% rename from assets/flags/GE.svg rename to public/assets/flags/GE.svg diff --git a/assets/flags/GF.svg b/public/assets/flags/GF.svg similarity index 100% rename from assets/flags/GF.svg rename to public/assets/flags/GF.svg diff --git a/assets/flags/GG.svg b/public/assets/flags/GG.svg similarity index 100% rename from assets/flags/GG.svg rename to public/assets/flags/GG.svg diff --git a/assets/flags/GH.svg b/public/assets/flags/GH.svg similarity index 100% rename from assets/flags/GH.svg rename to public/assets/flags/GH.svg diff --git a/assets/flags/GI.svg b/public/assets/flags/GI.svg similarity index 100% rename from assets/flags/GI.svg rename to public/assets/flags/GI.svg diff --git a/assets/flags/GL.svg b/public/assets/flags/GL.svg similarity index 100% rename from assets/flags/GL.svg rename to public/assets/flags/GL.svg diff --git a/assets/flags/GM.svg b/public/assets/flags/GM.svg similarity index 100% rename from assets/flags/GM.svg rename to public/assets/flags/GM.svg diff --git a/assets/flags/GN.svg b/public/assets/flags/GN.svg similarity index 100% rename from assets/flags/GN.svg rename to public/assets/flags/GN.svg diff --git a/assets/flags/GP.svg b/public/assets/flags/GP.svg similarity index 100% rename from assets/flags/GP.svg rename to public/assets/flags/GP.svg diff --git a/assets/flags/GQ.svg b/public/assets/flags/GQ.svg similarity index 100% rename from assets/flags/GQ.svg rename to public/assets/flags/GQ.svg diff --git a/assets/flags/GR.svg b/public/assets/flags/GR.svg similarity index 100% rename from assets/flags/GR.svg rename to public/assets/flags/GR.svg diff --git a/assets/flags/GS.svg b/public/assets/flags/GS.svg similarity index 100% rename from assets/flags/GS.svg rename to public/assets/flags/GS.svg diff --git a/assets/flags/GT.svg b/public/assets/flags/GT.svg similarity index 100% rename from assets/flags/GT.svg rename to public/assets/flags/GT.svg diff --git a/assets/flags/GU.svg b/public/assets/flags/GU.svg similarity index 100% rename from assets/flags/GU.svg rename to public/assets/flags/GU.svg diff --git a/assets/flags/GW.svg b/public/assets/flags/GW.svg similarity index 100% rename from assets/flags/GW.svg rename to public/assets/flags/GW.svg diff --git a/assets/flags/GY.svg b/public/assets/flags/GY.svg similarity index 100% rename from assets/flags/GY.svg rename to public/assets/flags/GY.svg diff --git a/assets/flags/HK.svg b/public/assets/flags/HK.svg similarity index 100% rename from assets/flags/HK.svg rename to public/assets/flags/HK.svg diff --git a/assets/flags/HM.svg b/public/assets/flags/HM.svg similarity index 100% rename from assets/flags/HM.svg rename to public/assets/flags/HM.svg diff --git a/assets/flags/HN.svg b/public/assets/flags/HN.svg similarity index 100% rename from assets/flags/HN.svg rename to public/assets/flags/HN.svg diff --git a/assets/flags/HR.svg b/public/assets/flags/HR.svg similarity index 100% rename from assets/flags/HR.svg rename to public/assets/flags/HR.svg diff --git a/assets/flags/HT.svg b/public/assets/flags/HT.svg similarity index 100% rename from assets/flags/HT.svg rename to public/assets/flags/HT.svg diff --git a/assets/flags/HU.svg b/public/assets/flags/HU.svg similarity index 100% rename from assets/flags/HU.svg rename to public/assets/flags/HU.svg diff --git a/assets/flags/ID.svg b/public/assets/flags/ID.svg similarity index 100% rename from assets/flags/ID.svg rename to public/assets/flags/ID.svg diff --git a/assets/flags/IE.svg b/public/assets/flags/IE.svg similarity index 100% rename from assets/flags/IE.svg rename to public/assets/flags/IE.svg diff --git a/assets/flags/IL.svg b/public/assets/flags/IL.svg similarity index 100% rename from assets/flags/IL.svg rename to public/assets/flags/IL.svg diff --git a/assets/flags/IM.svg b/public/assets/flags/IM.svg similarity index 100% rename from assets/flags/IM.svg rename to public/assets/flags/IM.svg diff --git a/assets/flags/IN.svg b/public/assets/flags/IN.svg similarity index 100% rename from assets/flags/IN.svg rename to public/assets/flags/IN.svg diff --git a/assets/flags/IO.svg b/public/assets/flags/IO.svg similarity index 100% rename from assets/flags/IO.svg rename to public/assets/flags/IO.svg diff --git a/assets/flags/IQ.svg b/public/assets/flags/IQ.svg similarity index 100% rename from assets/flags/IQ.svg rename to public/assets/flags/IQ.svg diff --git a/assets/flags/IR.svg b/public/assets/flags/IR.svg similarity index 100% rename from assets/flags/IR.svg rename to public/assets/flags/IR.svg diff --git a/assets/flags/IS.svg b/public/assets/flags/IS.svg similarity index 100% rename from assets/flags/IS.svg rename to public/assets/flags/IS.svg diff --git a/assets/flags/IT.svg b/public/assets/flags/IT.svg similarity index 100% rename from assets/flags/IT.svg rename to public/assets/flags/IT.svg diff --git a/assets/flags/ITSRD.svg b/public/assets/flags/ITSRD.svg similarity index 100% rename from assets/flags/ITSRD.svg rename to public/assets/flags/ITSRD.svg diff --git a/assets/flags/JE.svg b/public/assets/flags/JE.svg similarity index 100% rename from assets/flags/JE.svg rename to public/assets/flags/JE.svg diff --git a/assets/flags/JM.svg b/public/assets/flags/JM.svg similarity index 100% rename from assets/flags/JM.svg rename to public/assets/flags/JM.svg diff --git a/assets/flags/JO.svg b/public/assets/flags/JO.svg similarity index 100% rename from assets/flags/JO.svg rename to public/assets/flags/JO.svg diff --git a/assets/flags/JP.svg b/public/assets/flags/JP.svg similarity index 100% rename from assets/flags/JP.svg rename to public/assets/flags/JP.svg diff --git a/assets/flags/KE.svg b/public/assets/flags/KE.svg similarity index 100% rename from assets/flags/KE.svg rename to public/assets/flags/KE.svg diff --git a/assets/flags/KG.svg b/public/assets/flags/KG.svg similarity index 100% rename from assets/flags/KG.svg rename to public/assets/flags/KG.svg diff --git a/assets/flags/KH.svg b/public/assets/flags/KH.svg similarity index 100% rename from assets/flags/KH.svg rename to public/assets/flags/KH.svg diff --git a/assets/flags/KI.svg b/public/assets/flags/KI.svg similarity index 100% rename from assets/flags/KI.svg rename to public/assets/flags/KI.svg diff --git a/assets/flags/KM.svg b/public/assets/flags/KM.svg similarity index 100% rename from assets/flags/KM.svg rename to public/assets/flags/KM.svg diff --git a/assets/flags/KN.svg b/public/assets/flags/KN.svg similarity index 100% rename from assets/flags/KN.svg rename to public/assets/flags/KN.svg diff --git a/assets/flags/KP.svg b/public/assets/flags/KP.svg similarity index 100% rename from assets/flags/KP.svg rename to public/assets/flags/KP.svg diff --git a/assets/flags/KR.svg b/public/assets/flags/KR.svg similarity index 100% rename from assets/flags/KR.svg rename to public/assets/flags/KR.svg diff --git a/assets/flags/KW.svg b/public/assets/flags/KW.svg similarity index 100% rename from assets/flags/KW.svg rename to public/assets/flags/KW.svg diff --git a/assets/flags/KY.svg b/public/assets/flags/KY.svg similarity index 100% rename from assets/flags/KY.svg rename to public/assets/flags/KY.svg diff --git a/assets/flags/KZ.svg b/public/assets/flags/KZ.svg similarity index 100% rename from assets/flags/KZ.svg rename to public/assets/flags/KZ.svg diff --git a/assets/flags/LA.svg b/public/assets/flags/LA.svg similarity index 100% rename from assets/flags/LA.svg rename to public/assets/flags/LA.svg diff --git a/assets/flags/LB.svg b/public/assets/flags/LB.svg similarity index 100% rename from assets/flags/LB.svg rename to public/assets/flags/LB.svg diff --git a/assets/flags/LC.svg b/public/assets/flags/LC.svg similarity index 100% rename from assets/flags/LC.svg rename to public/assets/flags/LC.svg diff --git a/assets/flags/LGBT.svg b/public/assets/flags/LGBT.svg similarity index 100% rename from assets/flags/LGBT.svg rename to public/assets/flags/LGBT.svg diff --git a/assets/flags/LI.svg b/public/assets/flags/LI.svg similarity index 100% rename from assets/flags/LI.svg rename to public/assets/flags/LI.svg diff --git a/assets/flags/LK.svg b/public/assets/flags/LK.svg similarity index 100% rename from assets/flags/LK.svg rename to public/assets/flags/LK.svg diff --git a/assets/flags/LR.svg b/public/assets/flags/LR.svg similarity index 100% rename from assets/flags/LR.svg rename to public/assets/flags/LR.svg diff --git a/assets/flags/LS.svg b/public/assets/flags/LS.svg similarity index 100% rename from assets/flags/LS.svg rename to public/assets/flags/LS.svg diff --git a/assets/flags/LT.svg b/public/assets/flags/LT.svg similarity index 100% rename from assets/flags/LT.svg rename to public/assets/flags/LT.svg diff --git a/assets/flags/LU.svg b/public/assets/flags/LU.svg similarity index 100% rename from assets/flags/LU.svg rename to public/assets/flags/LU.svg diff --git a/assets/flags/LV.svg b/public/assets/flags/LV.svg similarity index 100% rename from assets/flags/LV.svg rename to public/assets/flags/LV.svg diff --git a/assets/flags/LY.svg b/public/assets/flags/LY.svg similarity index 100% rename from assets/flags/LY.svg rename to public/assets/flags/LY.svg diff --git a/assets/flags/MA.svg b/public/assets/flags/MA.svg similarity index 100% rename from assets/flags/MA.svg rename to public/assets/flags/MA.svg diff --git a/assets/flags/MC.svg b/public/assets/flags/MC.svg similarity index 100% rename from assets/flags/MC.svg rename to public/assets/flags/MC.svg diff --git a/assets/flags/MD.svg b/public/assets/flags/MD.svg similarity index 100% rename from assets/flags/MD.svg rename to public/assets/flags/MD.svg diff --git a/assets/flags/ME.svg b/public/assets/flags/ME.svg similarity index 100% rename from assets/flags/ME.svg rename to public/assets/flags/ME.svg diff --git a/assets/flags/MF.svg b/public/assets/flags/MF.svg similarity index 100% rename from assets/flags/MF.svg rename to public/assets/flags/MF.svg diff --git a/assets/flags/MG.svg b/public/assets/flags/MG.svg similarity index 100% rename from assets/flags/MG.svg rename to public/assets/flags/MG.svg diff --git a/assets/flags/MH.svg b/public/assets/flags/MH.svg similarity index 100% rename from assets/flags/MH.svg rename to public/assets/flags/MH.svg diff --git a/assets/flags/MK.svg b/public/assets/flags/MK.svg similarity index 100% rename from assets/flags/MK.svg rename to public/assets/flags/MK.svg diff --git a/assets/flags/ML.svg b/public/assets/flags/ML.svg similarity index 100% rename from assets/flags/ML.svg rename to public/assets/flags/ML.svg diff --git a/assets/flags/MM.svg b/public/assets/flags/MM.svg similarity index 100% rename from assets/flags/MM.svg rename to public/assets/flags/MM.svg diff --git a/assets/flags/MN.svg b/public/assets/flags/MN.svg similarity index 100% rename from assets/flags/MN.svg rename to public/assets/flags/MN.svg diff --git a/assets/flags/MO.svg b/public/assets/flags/MO.svg similarity index 100% rename from assets/flags/MO.svg rename to public/assets/flags/MO.svg diff --git a/assets/flags/MP.svg b/public/assets/flags/MP.svg similarity index 100% rename from assets/flags/MP.svg rename to public/assets/flags/MP.svg diff --git a/assets/flags/MQ.svg b/public/assets/flags/MQ.svg similarity index 100% rename from assets/flags/MQ.svg rename to public/assets/flags/MQ.svg diff --git a/assets/flags/MR.svg b/public/assets/flags/MR.svg similarity index 100% rename from assets/flags/MR.svg rename to public/assets/flags/MR.svg diff --git a/assets/flags/MS.svg b/public/assets/flags/MS.svg similarity index 100% rename from assets/flags/MS.svg rename to public/assets/flags/MS.svg diff --git a/assets/flags/MT.svg b/public/assets/flags/MT.svg similarity index 100% rename from assets/flags/MT.svg rename to public/assets/flags/MT.svg diff --git a/assets/flags/MU.svg b/public/assets/flags/MU.svg similarity index 100% rename from assets/flags/MU.svg rename to public/assets/flags/MU.svg diff --git a/assets/flags/MV.svg b/public/assets/flags/MV.svg similarity index 100% rename from assets/flags/MV.svg rename to public/assets/flags/MV.svg diff --git a/assets/flags/MW.svg b/public/assets/flags/MW.svg similarity index 100% rename from assets/flags/MW.svg rename to public/assets/flags/MW.svg diff --git a/assets/flags/MX.svg b/public/assets/flags/MX.svg similarity index 100% rename from assets/flags/MX.svg rename to public/assets/flags/MX.svg diff --git a/assets/flags/MY.svg b/public/assets/flags/MY.svg similarity index 100% rename from assets/flags/MY.svg rename to public/assets/flags/MY.svg diff --git a/assets/flags/MYPG.svg b/public/assets/flags/MYPG.svg similarity index 100% rename from assets/flags/MYPG.svg rename to public/assets/flags/MYPG.svg diff --git a/assets/flags/MYSB.svg b/public/assets/flags/MYSB.svg similarity index 100% rename from assets/flags/MYSB.svg rename to public/assets/flags/MYSB.svg diff --git a/assets/flags/MYSWK.svg b/public/assets/flags/MYSWK.svg similarity index 100% rename from assets/flags/MYSWK.svg rename to public/assets/flags/MYSWK.svg diff --git a/assets/flags/MZ.svg b/public/assets/flags/MZ.svg similarity index 100% rename from assets/flags/MZ.svg rename to public/assets/flags/MZ.svg diff --git a/assets/flags/NA.svg b/public/assets/flags/NA.svg similarity index 100% rename from assets/flags/NA.svg rename to public/assets/flags/NA.svg diff --git a/assets/flags/NC.svg b/public/assets/flags/NC.svg similarity index 100% rename from assets/flags/NC.svg rename to public/assets/flags/NC.svg diff --git a/assets/flags/NE.svg b/public/assets/flags/NE.svg similarity index 100% rename from assets/flags/NE.svg rename to public/assets/flags/NE.svg diff --git a/assets/flags/NF.svg b/public/assets/flags/NF.svg similarity index 100% rename from assets/flags/NF.svg rename to public/assets/flags/NF.svg diff --git a/assets/flags/NG.svg b/public/assets/flags/NG.svg similarity index 100% rename from assets/flags/NG.svg rename to public/assets/flags/NG.svg diff --git a/assets/flags/NI.svg b/public/assets/flags/NI.svg similarity index 100% rename from assets/flags/NI.svg rename to public/assets/flags/NI.svg diff --git a/assets/flags/NL.svg b/public/assets/flags/NL.svg similarity index 100% rename from assets/flags/NL.svg rename to public/assets/flags/NL.svg diff --git a/assets/flags/NO.svg b/public/assets/flags/NO.svg similarity index 100% rename from assets/flags/NO.svg rename to public/assets/flags/NO.svg diff --git a/assets/flags/NP.svg b/public/assets/flags/NP.svg similarity index 100% rename from assets/flags/NP.svg rename to public/assets/flags/NP.svg diff --git a/assets/flags/NR.svg b/public/assets/flags/NR.svg similarity index 100% rename from assets/flags/NR.svg rename to public/assets/flags/NR.svg diff --git a/assets/flags/NU.svg b/public/assets/flags/NU.svg similarity index 100% rename from assets/flags/NU.svg rename to public/assets/flags/NU.svg diff --git a/assets/flags/NZ.svg b/public/assets/flags/NZ.svg similarity index 100% rename from assets/flags/NZ.svg rename to public/assets/flags/NZ.svg diff --git a/assets/flags/NZMAORI.svg b/public/assets/flags/NZMAORI.svg similarity index 100% rename from assets/flags/NZMAORI.svg rename to public/assets/flags/NZMAORI.svg diff --git a/assets/flags/OM.svg b/public/assets/flags/OM.svg similarity index 100% rename from assets/flags/OM.svg rename to public/assets/flags/OM.svg diff --git a/assets/flags/PA.svg b/public/assets/flags/PA.svg similarity index 100% rename from assets/flags/PA.svg rename to public/assets/flags/PA.svg diff --git a/assets/flags/PE.svg b/public/assets/flags/PE.svg similarity index 100% rename from assets/flags/PE.svg rename to public/assets/flags/PE.svg diff --git a/assets/flags/PF.svg b/public/assets/flags/PF.svg similarity index 100% rename from assets/flags/PF.svg rename to public/assets/flags/PF.svg diff --git a/assets/flags/PG.svg b/public/assets/flags/PG.svg similarity index 100% rename from assets/flags/PG.svg rename to public/assets/flags/PG.svg diff --git a/assets/flags/PH.svg b/public/assets/flags/PH.svg similarity index 100% rename from assets/flags/PH.svg rename to public/assets/flags/PH.svg diff --git a/assets/flags/PIRATE.svg b/public/assets/flags/PIRATE.svg similarity index 100% rename from assets/flags/PIRATE.svg rename to public/assets/flags/PIRATE.svg diff --git a/assets/flags/PK.svg b/public/assets/flags/PK.svg similarity index 100% rename from assets/flags/PK.svg rename to public/assets/flags/PK.svg diff --git a/assets/flags/PL.svg b/public/assets/flags/PL.svg similarity index 100% rename from assets/flags/PL.svg rename to public/assets/flags/PL.svg diff --git a/assets/flags/PM.svg b/public/assets/flags/PM.svg similarity index 100% rename from assets/flags/PM.svg rename to public/assets/flags/PM.svg diff --git a/assets/flags/PN.svg b/public/assets/flags/PN.svg similarity index 100% rename from assets/flags/PN.svg rename to public/assets/flags/PN.svg diff --git a/assets/flags/PR.svg b/public/assets/flags/PR.svg similarity index 100% rename from assets/flags/PR.svg rename to public/assets/flags/PR.svg diff --git a/assets/flags/PS.svg b/public/assets/flags/PS.svg similarity index 100% rename from assets/flags/PS.svg rename to public/assets/flags/PS.svg diff --git a/assets/flags/PT.svg b/public/assets/flags/PT.svg similarity index 100% rename from assets/flags/PT.svg rename to public/assets/flags/PT.svg diff --git a/assets/flags/PW.svg b/public/assets/flags/PW.svg similarity index 100% rename from assets/flags/PW.svg rename to public/assets/flags/PW.svg diff --git a/assets/flags/PY.svg b/public/assets/flags/PY.svg similarity index 100% rename from assets/flags/PY.svg rename to public/assets/flags/PY.svg diff --git a/assets/flags/QA.svg b/public/assets/flags/QA.svg similarity index 100% rename from assets/flags/QA.svg rename to public/assets/flags/QA.svg diff --git a/assets/flags/QC.svg b/public/assets/flags/QC.svg similarity index 100% rename from assets/flags/QC.svg rename to public/assets/flags/QC.svg diff --git a/assets/flags/RE.svg b/public/assets/flags/RE.svg similarity index 100% rename from assets/flags/RE.svg rename to public/assets/flags/RE.svg diff --git a/assets/flags/RO.svg b/public/assets/flags/RO.svg similarity index 100% rename from assets/flags/RO.svg rename to public/assets/flags/RO.svg diff --git a/assets/flags/RS.svg b/public/assets/flags/RS.svg similarity index 100% rename from assets/flags/RS.svg rename to public/assets/flags/RS.svg diff --git a/assets/flags/RU.svg b/public/assets/flags/RU.svg similarity index 100% rename from assets/flags/RU.svg rename to public/assets/flags/RU.svg diff --git a/assets/flags/RW.svg b/public/assets/flags/RW.svg similarity index 100% rename from assets/flags/RW.svg rename to public/assets/flags/RW.svg diff --git a/assets/flags/SA.svg b/public/assets/flags/SA.svg similarity index 100% rename from assets/flags/SA.svg rename to public/assets/flags/SA.svg diff --git a/assets/flags/SB.svg b/public/assets/flags/SB.svg similarity index 100% rename from assets/flags/SB.svg rename to public/assets/flags/SB.svg diff --git a/assets/flags/SC.svg b/public/assets/flags/SC.svg similarity index 100% rename from assets/flags/SC.svg rename to public/assets/flags/SC.svg diff --git a/assets/flags/SD.svg b/public/assets/flags/SD.svg similarity index 100% rename from assets/flags/SD.svg rename to public/assets/flags/SD.svg diff --git a/assets/flags/SE.svg b/public/assets/flags/SE.svg similarity index 100% rename from assets/flags/SE.svg rename to public/assets/flags/SE.svg diff --git a/assets/flags/SG.svg b/public/assets/flags/SG.svg similarity index 100% rename from assets/flags/SG.svg rename to public/assets/flags/SG.svg diff --git a/assets/flags/SH.svg b/public/assets/flags/SH.svg similarity index 100% rename from assets/flags/SH.svg rename to public/assets/flags/SH.svg diff --git a/assets/flags/SI.svg b/public/assets/flags/SI.svg similarity index 100% rename from assets/flags/SI.svg rename to public/assets/flags/SI.svg diff --git a/assets/flags/SJ.svg b/public/assets/flags/SJ.svg similarity index 100% rename from assets/flags/SJ.svg rename to public/assets/flags/SJ.svg diff --git a/assets/flags/SK.svg b/public/assets/flags/SK.svg similarity index 100% rename from assets/flags/SK.svg rename to public/assets/flags/SK.svg diff --git a/assets/flags/SL.svg b/public/assets/flags/SL.svg similarity index 100% rename from assets/flags/SL.svg rename to public/assets/flags/SL.svg diff --git a/assets/flags/SM.svg b/public/assets/flags/SM.svg similarity index 100% rename from assets/flags/SM.svg rename to public/assets/flags/SM.svg diff --git a/assets/flags/SN.svg b/public/assets/flags/SN.svg similarity index 100% rename from assets/flags/SN.svg rename to public/assets/flags/SN.svg diff --git a/assets/flags/SO.svg b/public/assets/flags/SO.svg similarity index 100% rename from assets/flags/SO.svg rename to public/assets/flags/SO.svg diff --git a/assets/flags/SR.svg b/public/assets/flags/SR.svg similarity index 100% rename from assets/flags/SR.svg rename to public/assets/flags/SR.svg diff --git a/assets/flags/SS.svg b/public/assets/flags/SS.svg similarity index 100% rename from assets/flags/SS.svg rename to public/assets/flags/SS.svg diff --git a/assets/flags/ST.svg b/public/assets/flags/ST.svg similarity index 100% rename from assets/flags/ST.svg rename to public/assets/flags/ST.svg diff --git a/assets/flags/SV.svg b/public/assets/flags/SV.svg similarity index 100% rename from assets/flags/SV.svg rename to public/assets/flags/SV.svg diff --git a/assets/flags/SX.svg b/public/assets/flags/SX.svg similarity index 100% rename from assets/flags/SX.svg rename to public/assets/flags/SX.svg diff --git a/assets/flags/SY.svg b/public/assets/flags/SY.svg similarity index 100% rename from assets/flags/SY.svg rename to public/assets/flags/SY.svg diff --git a/assets/flags/SZ.svg b/public/assets/flags/SZ.svg similarity index 100% rename from assets/flags/SZ.svg rename to public/assets/flags/SZ.svg diff --git a/assets/flags/TB.svg b/public/assets/flags/TB.svg similarity index 100% rename from assets/flags/TB.svg rename to public/assets/flags/TB.svg diff --git a/assets/flags/TC.svg b/public/assets/flags/TC.svg similarity index 100% rename from assets/flags/TC.svg rename to public/assets/flags/TC.svg diff --git a/assets/flags/TD.svg b/public/assets/flags/TD.svg similarity index 100% rename from assets/flags/TD.svg rename to public/assets/flags/TD.svg diff --git a/assets/flags/TF.svg b/public/assets/flags/TF.svg similarity index 100% rename from assets/flags/TF.svg rename to public/assets/flags/TF.svg diff --git a/assets/flags/TG.svg b/public/assets/flags/TG.svg similarity index 100% rename from assets/flags/TG.svg rename to public/assets/flags/TG.svg diff --git a/assets/flags/TH.svg b/public/assets/flags/TH.svg similarity index 100% rename from assets/flags/TH.svg rename to public/assets/flags/TH.svg diff --git a/assets/flags/TJ.svg b/public/assets/flags/TJ.svg similarity index 100% rename from assets/flags/TJ.svg rename to public/assets/flags/TJ.svg diff --git a/assets/flags/TK.svg b/public/assets/flags/TK.svg similarity index 100% rename from assets/flags/TK.svg rename to public/assets/flags/TK.svg diff --git a/assets/flags/TL.svg b/public/assets/flags/TL.svg similarity index 100% rename from assets/flags/TL.svg rename to public/assets/flags/TL.svg diff --git a/assets/flags/TM.svg b/public/assets/flags/TM.svg similarity index 100% rename from assets/flags/TM.svg rename to public/assets/flags/TM.svg diff --git a/assets/flags/TN.svg b/public/assets/flags/TN.svg similarity index 100% rename from assets/flags/TN.svg rename to public/assets/flags/TN.svg diff --git a/assets/flags/TO.svg b/public/assets/flags/TO.svg similarity index 100% rename from assets/flags/TO.svg rename to public/assets/flags/TO.svg diff --git a/assets/flags/TR.svg b/public/assets/flags/TR.svg similarity index 100% rename from assets/flags/TR.svg rename to public/assets/flags/TR.svg diff --git a/assets/flags/TRANS.svg b/public/assets/flags/TRANS.svg similarity index 100% rename from assets/flags/TRANS.svg rename to public/assets/flags/TRANS.svg diff --git a/assets/flags/TT.svg b/public/assets/flags/TT.svg similarity index 100% rename from assets/flags/TT.svg rename to public/assets/flags/TT.svg diff --git a/assets/flags/TV.svg b/public/assets/flags/TV.svg similarity index 100% rename from assets/flags/TV.svg rename to public/assets/flags/TV.svg diff --git a/assets/flags/TW.svg b/public/assets/flags/TW.svg similarity index 100% rename from assets/flags/TW.svg rename to public/assets/flags/TW.svg diff --git a/assets/flags/TZ.svg b/public/assets/flags/TZ.svg similarity index 100% rename from assets/flags/TZ.svg rename to public/assets/flags/TZ.svg diff --git a/assets/flags/UA.svg b/public/assets/flags/UA.svg similarity index 100% rename from assets/flags/UA.svg rename to public/assets/flags/UA.svg diff --git a/assets/flags/UG.svg b/public/assets/flags/UG.svg similarity index 100% rename from assets/flags/UG.svg rename to public/assets/flags/UG.svg diff --git a/assets/flags/US.svg b/public/assets/flags/US.svg similarity index 100% rename from assets/flags/US.svg rename to public/assets/flags/US.svg diff --git a/assets/flags/USAK.svg b/public/assets/flags/USAK.svg similarity index 100% rename from assets/flags/USAK.svg rename to public/assets/flags/USAK.svg diff --git a/assets/flags/USAL.svg b/public/assets/flags/USAL.svg similarity index 100% rename from assets/flags/USAL.svg rename to public/assets/flags/USAL.svg diff --git a/assets/flags/USAR.svg b/public/assets/flags/USAR.svg similarity index 100% rename from assets/flags/USAR.svg rename to public/assets/flags/USAR.svg diff --git a/assets/flags/USAZ.svg b/public/assets/flags/USAZ.svg similarity index 100% rename from assets/flags/USAZ.svg rename to public/assets/flags/USAZ.svg diff --git a/assets/flags/USCA.svg b/public/assets/flags/USCA.svg similarity index 100% rename from assets/flags/USCA.svg rename to public/assets/flags/USCA.svg diff --git a/assets/flags/USCO.svg b/public/assets/flags/USCO.svg similarity index 100% rename from assets/flags/USCO.svg rename to public/assets/flags/USCO.svg diff --git a/assets/flags/USCT.svg b/public/assets/flags/USCT.svg similarity index 100% rename from assets/flags/USCT.svg rename to public/assets/flags/USCT.svg diff --git a/assets/flags/USDE.svg b/public/assets/flags/USDE.svg similarity index 100% rename from assets/flags/USDE.svg rename to public/assets/flags/USDE.svg diff --git a/assets/flags/USFL.svg b/public/assets/flags/USFL.svg similarity index 100% rename from assets/flags/USFL.svg rename to public/assets/flags/USFL.svg diff --git a/assets/flags/USGA.svg b/public/assets/flags/USGA.svg similarity index 100% rename from assets/flags/USGA.svg rename to public/assets/flags/USGA.svg diff --git a/assets/flags/USHI.svg b/public/assets/flags/USHI.svg similarity index 100% rename from assets/flags/USHI.svg rename to public/assets/flags/USHI.svg diff --git a/assets/flags/USIA.svg b/public/assets/flags/USIA.svg similarity index 100% rename from assets/flags/USIA.svg rename to public/assets/flags/USIA.svg diff --git a/assets/flags/USID.svg b/public/assets/flags/USID.svg similarity index 100% rename from assets/flags/USID.svg rename to public/assets/flags/USID.svg diff --git a/assets/flags/USIL.svg b/public/assets/flags/USIL.svg similarity index 100% rename from assets/flags/USIL.svg rename to public/assets/flags/USIL.svg diff --git a/assets/flags/USIN.svg b/public/assets/flags/USIN.svg similarity index 100% rename from assets/flags/USIN.svg rename to public/assets/flags/USIN.svg diff --git a/assets/flags/USKS.svg b/public/assets/flags/USKS.svg similarity index 100% rename from assets/flags/USKS.svg rename to public/assets/flags/USKS.svg diff --git a/assets/flags/USKY.svg b/public/assets/flags/USKY.svg similarity index 100% rename from assets/flags/USKY.svg rename to public/assets/flags/USKY.svg diff --git a/assets/flags/USLA.svg b/public/assets/flags/USLA.svg similarity index 100% rename from assets/flags/USLA.svg rename to public/assets/flags/USLA.svg diff --git a/assets/flags/USMA.svg b/public/assets/flags/USMA.svg similarity index 100% rename from assets/flags/USMA.svg rename to public/assets/flags/USMA.svg diff --git a/assets/flags/USMD.svg b/public/assets/flags/USMD.svg similarity index 100% rename from assets/flags/USMD.svg rename to public/assets/flags/USMD.svg diff --git a/public/assets/flags/USME.svg b/public/assets/flags/USME.svg new file mode 100644 index 0000000..abab5c7 --- /dev/null +++ b/public/assets/flags/USME.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/flags/USMI.svg b/public/assets/flags/USMI.svg similarity index 100% rename from assets/flags/USMI.svg rename to public/assets/flags/USMI.svg diff --git a/assets/flags/USMN.svg b/public/assets/flags/USMN.svg similarity index 100% rename from assets/flags/USMN.svg rename to public/assets/flags/USMN.svg diff --git a/assets/flags/USMO.svg b/public/assets/flags/USMO.svg similarity index 100% rename from assets/flags/USMO.svg rename to public/assets/flags/USMO.svg diff --git a/assets/flags/USMS.svg b/public/assets/flags/USMS.svg similarity index 100% rename from assets/flags/USMS.svg rename to public/assets/flags/USMS.svg diff --git a/public/assets/flags/USMT.svg b/public/assets/flags/USMT.svg new file mode 100644 index 0000000..3486509 --- /dev/null +++ b/public/assets/flags/USMT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/flags/USNC.svg b/public/assets/flags/USNC.svg similarity index 100% rename from assets/flags/USNC.svg rename to public/assets/flags/USNC.svg diff --git a/assets/flags/USND.svg b/public/assets/flags/USND.svg similarity index 100% rename from assets/flags/USND.svg rename to public/assets/flags/USND.svg diff --git a/assets/flags/USNE.svg b/public/assets/flags/USNE.svg similarity index 100% rename from assets/flags/USNE.svg rename to public/assets/flags/USNE.svg diff --git a/assets/flags/USNH.svg b/public/assets/flags/USNH.svg similarity index 100% rename from assets/flags/USNH.svg rename to public/assets/flags/USNH.svg diff --git a/assets/flags/USNJ.svg b/public/assets/flags/USNJ.svg similarity index 100% rename from assets/flags/USNJ.svg rename to public/assets/flags/USNJ.svg diff --git a/assets/flags/USNM.svg b/public/assets/flags/USNM.svg similarity index 100% rename from assets/flags/USNM.svg rename to public/assets/flags/USNM.svg diff --git a/assets/flags/USNV.svg b/public/assets/flags/USNV.svg similarity index 100% rename from assets/flags/USNV.svg rename to public/assets/flags/USNV.svg diff --git a/assets/flags/USNY.svg b/public/assets/flags/USNY.svg similarity index 100% rename from assets/flags/USNY.svg rename to public/assets/flags/USNY.svg diff --git a/assets/flags/USOH.svg b/public/assets/flags/USOH.svg similarity index 100% rename from assets/flags/USOH.svg rename to public/assets/flags/USOH.svg diff --git a/assets/flags/USOK.svg b/public/assets/flags/USOK.svg similarity index 100% rename from assets/flags/USOK.svg rename to public/assets/flags/USOK.svg diff --git a/assets/flags/USOR.svg b/public/assets/flags/USOR.svg similarity index 100% rename from assets/flags/USOR.svg rename to public/assets/flags/USOR.svg diff --git a/assets/flags/USPA.svg b/public/assets/flags/USPA.svg similarity index 100% rename from assets/flags/USPA.svg rename to public/assets/flags/USPA.svg diff --git a/assets/flags/USRI.svg b/public/assets/flags/USRI.svg similarity index 100% rename from assets/flags/USRI.svg rename to public/assets/flags/USRI.svg diff --git a/assets/flags/USSC.svg b/public/assets/flags/USSC.svg similarity index 100% rename from assets/flags/USSC.svg rename to public/assets/flags/USSC.svg diff --git a/assets/flags/USSD.svg b/public/assets/flags/USSD.svg similarity index 100% rename from assets/flags/USSD.svg rename to public/assets/flags/USSD.svg diff --git a/assets/flags/USSR.svg b/public/assets/flags/USSR.svg similarity index 100% rename from assets/flags/USSR.svg rename to public/assets/flags/USSR.svg diff --git a/assets/flags/USTN.svg b/public/assets/flags/USTN.svg similarity index 100% rename from assets/flags/USTN.svg rename to public/assets/flags/USTN.svg diff --git a/assets/flags/USTX.svg b/public/assets/flags/USTX.svg similarity index 100% rename from assets/flags/USTX.svg rename to public/assets/flags/USTX.svg diff --git a/assets/flags/USUT.svg b/public/assets/flags/USUT.svg similarity index 100% rename from assets/flags/USUT.svg rename to public/assets/flags/USUT.svg diff --git a/assets/flags/USVA.svg b/public/assets/flags/USVA.svg similarity index 100% rename from assets/flags/USVA.svg rename to public/assets/flags/USVA.svg diff --git a/public/assets/flags/USVT.svg b/public/assets/flags/USVT.svg new file mode 100644 index 0000000..25a27e4 --- /dev/null +++ b/public/assets/flags/USVT.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/flags/USWA.svg b/public/assets/flags/USWA.svg similarity index 100% rename from assets/flags/USWA.svg rename to public/assets/flags/USWA.svg diff --git a/assets/flags/USWI.svg b/public/assets/flags/USWI.svg similarity index 100% rename from assets/flags/USWI.svg rename to public/assets/flags/USWI.svg diff --git a/assets/flags/USWV.svg b/public/assets/flags/USWV.svg similarity index 100% rename from assets/flags/USWV.svg rename to public/assets/flags/USWV.svg diff --git a/assets/flags/USWY.svg b/public/assets/flags/USWY.svg similarity index 100% rename from assets/flags/USWY.svg rename to public/assets/flags/USWY.svg diff --git a/assets/flags/UY.svg b/public/assets/flags/UY.svg similarity index 100% rename from assets/flags/UY.svg rename to public/assets/flags/UY.svg diff --git a/assets/flags/UZ.svg b/public/assets/flags/UZ.svg similarity index 100% rename from assets/flags/UZ.svg rename to public/assets/flags/UZ.svg diff --git a/assets/flags/VA.svg b/public/assets/flags/VA.svg similarity index 100% rename from assets/flags/VA.svg rename to public/assets/flags/VA.svg diff --git a/assets/flags/VC.svg b/public/assets/flags/VC.svg similarity index 100% rename from assets/flags/VC.svg rename to public/assets/flags/VC.svg diff --git a/assets/flags/VE.svg b/public/assets/flags/VE.svg similarity index 100% rename from assets/flags/VE.svg rename to public/assets/flags/VE.svg diff --git a/assets/flags/VG.svg b/public/assets/flags/VG.svg similarity index 100% rename from assets/flags/VG.svg rename to public/assets/flags/VG.svg diff --git a/assets/flags/VI.svg b/public/assets/flags/VI.svg similarity index 100% rename from assets/flags/VI.svg rename to public/assets/flags/VI.svg diff --git a/assets/flags/VN.svg b/public/assets/flags/VN.svg similarity index 100% rename from assets/flags/VN.svg rename to public/assets/flags/VN.svg diff --git a/assets/flags/VU.svg b/public/assets/flags/VU.svg similarity index 100% rename from assets/flags/VU.svg rename to public/assets/flags/VU.svg diff --git a/assets/flags/WF.svg b/public/assets/flags/WF.svg similarity index 100% rename from assets/flags/WF.svg rename to public/assets/flags/WF.svg diff --git a/assets/flags/WHITE.svg b/public/assets/flags/WHITE.svg similarity index 100% rename from assets/flags/WHITE.svg rename to public/assets/flags/WHITE.svg diff --git a/assets/flags/WS.svg b/public/assets/flags/WS.svg similarity index 100% rename from assets/flags/WS.svg rename to public/assets/flags/WS.svg diff --git a/assets/flags/XK.svg b/public/assets/flags/XK.svg similarity index 100% rename from assets/flags/XK.svg rename to public/assets/flags/XK.svg diff --git a/assets/flags/YE.svg b/public/assets/flags/YE.svg similarity index 100% rename from assets/flags/YE.svg rename to public/assets/flags/YE.svg diff --git a/assets/flags/YT.svg b/public/assets/flags/YT.svg similarity index 100% rename from assets/flags/YT.svg rename to public/assets/flags/YT.svg diff --git a/assets/flags/YU.svg b/public/assets/flags/YU.svg similarity index 100% rename from assets/flags/YU.svg rename to public/assets/flags/YU.svg diff --git a/assets/flags/ZA.svg b/public/assets/flags/ZA.svg similarity index 100% rename from assets/flags/ZA.svg rename to public/assets/flags/ZA.svg diff --git a/assets/flags/ZM.svg b/public/assets/flags/ZM.svg similarity index 100% rename from assets/flags/ZM.svg rename to public/assets/flags/ZM.svg diff --git a/assets/flags/ZW.svg b/public/assets/flags/ZW.svg similarity index 100% rename from assets/flags/ZW.svg rename to public/assets/flags/ZW.svg diff --git a/src/Classes/Game.js b/src/Classes/Game.js deleted file mode 100644 index 4edf2cf..0000000 --- a/src/Classes/Game.js +++ /dev/null @@ -1,385 +0,0 @@ -"use strict"; - -const pMap = require("p-map"); -const GameHelper = require("../utils/GameHelper"); - -/** @typedef {import('../types').LatLng} LatLng */ -/** @typedef {import('../types').Location} Location */ -/** @typedef {import('../types').Seed} Seed */ -/** @typedef {import('../types').Guess} Guess */ -/** @typedef {import('../utils/Settings')} Settings */ - -/** - * @param {LatLng} a - * @param {LatLng} b - */ -function latLngEqual(a, b) { - return a.lat === b.lat && a.lng === b.lng; -} - -class Game { - /** @type {import('../utils/Database')} */ - #db; - - /** - * Play link for the current game. - * - * @type {string|undefined} - */ - #url; - - /** @type {Settings} */ - #settings; - - /** - * The database UUID of the current round. - * - * @type {string|undefined} - */ - #roundId; - - /** - * Country code for the current round's location. - * - * @type {string|undefined} - */ - #country; - - /** - * @type {Seed | undefined} - */ - seed; - /** @type {number | undefined} */ - mapScale; - /** @type {Location | undefined} */ - location; - - isInGame = false; - guessesOpen = false; - isMultiGuess = false; - - /** - * @param {import('../utils/Database')} db - * @param {Settings} settings - */ - constructor(db, settings) { - this.#db = db; - this.#settings = settings; - /** @type {LatLng | undefined} */ - this.lastLocation = this.#db.getLastRoundLocation(); - } - - /** - * - * @param {string} url - * @param {boolean} isMultiGuess - */ - async start(url, isMultiGuess) { - this.isInGame = true; - this.isMultiGuess = isMultiGuess; - if (this.#url === url) { - await this.refreshSeed(); - } else { - this.#url = url; - this.seed = await this.#getSeed(); - if (!this.seed) { - throw new Error("Could not load seed for this game"); - } - - try { - this.#db.createGame(this.seed); - this.#roundId = this.#db.createRound(this.seed.token, this.seed.rounds[0]); - } catch (err) { - // In this case we are restoring an existing game. - if (err instanceof Error && err.message.includes("UNIQUE constraint failed: games.id")) { - this.#roundId = this.#db.getCurrentRound(this.seed.token); - } else { - throw err; - } - } - - this.mapScale = GameHelper.calculateScale(this.seed.bounds); - this.#getCountry(); - } - } - - outGame() { - this.isInGame = false; - this.closeGuesses(); - } - - /** @param {Seed} newSeed */ - #streamerHasGuessed(newSeed) { - return newSeed.player.guesses.length != this.seed.player.guesses.length; - } - - /** @param {Seed} newSeed */ - #locHasChanged(newSeed) { - return !latLngEqual(newSeed.rounds.at(-1), this.getLocation()); - } - - async refreshSeed() { - const newSeed = await this.#getSeed(); - // If a guess has been comitted, process streamer guess then return scores - if (this.#streamerHasGuessed(newSeed)) { - this.closeGuesses(); - - this.seed = newSeed; - const location = this.location; - await this.#makeGuess(); - - const roundResults = this.getRoundResults(); - - if (this.seed.state !== "finished") { - this.#roundId = this.#db.createRound(this.seed.token, this.seed.rounds.at(-1)); - this.#getCountry(); - } else { - this.#roundId = undefined; - } - - return { location, roundResults }; - // Else, if only the loc has changed, the location was skipped, replace current loc - } else if (this.#locHasChanged(newSeed)) { - this.seed = newSeed; - this.#roundId = this.#db.createRound(this.seed.token, this.seed.rounds.at(-1)); - - this.#getCountry(); - - return false; - } - } - - async #getSeed() { - return this.#url ? await GameHelper.fetchSeed(this.#url) : undefined; - } - - async #getCountry() { - this.location = this.getLocation(); - this.#country = await GameHelper.getCountryCode(this.location); - - this.#db.setRoundCountry(this.#roundId, this.#country); - } - - async #makeGuess() { - this.seed = await this.#getSeed(); - - if (this.isMultiGuess) { - await this.#processMultiGuesses(); - } - await this.#processStreamerGuess(); - - this.lastLocation = { ...this.location }; - } - - /** - * Update streaks for multi-guesses. - */ - async #processMultiGuesses() { - const guesses = this.#db.getRoundResultsSimplified(this.#roundId); - await pMap( - guesses, - async (guess) => { - if (guess.country === this.#country) { - this.#db.addUserStreak(guess.userId, this.#roundId); - } else { - this.#db.resetUserStreak(guess.userId); - } - }, - { concurrency: 10 } - ); - } - - /** - */ - async #processStreamerGuess() { - const index = this.seed.state === "finished" ? 1 : 2; - const streamerGuess = this.seed.player.guesses[this.seed.round - index]; - const location = { lat: streamerGuess.lat, lng: streamerGuess.lng }; - - const dbUser = this.#db.getOrCreateUser("BROADCASTER", this.#settings.channelName); - - const guessedCountry = await GameHelper.getCountryCode(location); - const lastStreak = this.#db.getUserStreak(dbUser.id); - const correct = guessedCountry === this.#country; - if (correct) { - this.#db.addUserStreak(dbUser.id, this.#roundId); - } else { - this.#db.resetUserStreak(dbUser.id); - } - - const distance = GameHelper.haversineDistance(location, this.location); - const score = streamerGuess.timedOut ? 0 : GameHelper.calculateScore(distance, this.mapScale); - - const streak = this.#db.getUserStreak(dbUser.id); - - this.#db.createGuess(this.#roundId, dbUser.id, { - color: "#fff", - flag: dbUser.flag, - location, - country: guessedCountry, - streak: streak?.count ?? 0, - lastStreak: lastStreak?.count && !correct ? lastStreak.count : null, - distance, - score, - }); - } - - /** - * - * @param {import("tmi.js").ChatUserstate} userstate - * @param {LatLng} location - */ - async handleUserGuess(userstate, location) { - const dbUser = this.#db.getOrCreateUser(userstate["user-id"], userstate["display-name"]); - - const existingGuess = this.#db.getUserGuess(this.#roundId, dbUser.id); - if (!this.isMultiGuess && existingGuess) { - throw Object.assign(new Error("User already guessed"), { code: "alreadyGuessed" }); - } - - if (dbUser.previousGuess && latLngEqual(dbUser.previousGuess, location)) { - throw Object.assign(new Error("Same guess"), { code: "submittedPreviousGuess" }); - } - - userstate.color = userstate.color || "#FFF"; - const distance = GameHelper.haversineDistance(location, this.location); - const score = GameHelper.calculateScore(distance, this.mapScale); - - /** @type {string | null} */ - const guessedCountry = await GameHelper.getCountryCode(location); - const correct = guessedCountry === this.#country; - const lastStreak = this.#db.getUserStreak(dbUser.id); - - // Reset streak if the player skipped a round - if (lastStreak && this.lastLocation && !latLngEqual(lastStreak.lastLocation, this.lastLocation)) { - this.#db.resetUserStreak(dbUser.id); - } - - // this.#db.setUserLastLocation(dbUser.id, this.location); - - if (!this.isMultiGuess) { - if (guessedCountry === this.#country) { - this.#db.addUserStreak(dbUser.id, this.#roundId); - } else { - this.#db.resetUserStreak(dbUser.id); - } - } - - /** @type {{ id?: string, count: number, location?: string } | undefined} */ - let streak = this.#db.getUserStreak(dbUser.id); - - // With this we no longer need to update guess streak in processMultiGuesses() which was slow - if (this.isMultiGuess) { - if (correct) { - streak ? streak.count++ : (streak = { count: 1 }); - } else { - streak = null; - } - } - - const guess = { - color: userstate.color, - flag: dbUser.flag, - location, - country: guessedCountry, - streak: streak?.count ?? 0, - lastStreak: lastStreak?.count && !correct ? lastStreak.count : null, - distance, - score, - }; - - // Modify guess or push it - let modified = false; - if (this.isMultiGuess && existingGuess) { - this.#db.updateGuess(existingGuess.id, guess); - modified = true; - } else { - this.#db.createGuess(this.#roundId, dbUser.id, guess); - } - - // TODO save previous guess? No, fetch previous guess from the DB - this.#db.setUserPreviousGuess(dbUser.id, location); - - // Old shape, for the scoreboard UI - return { - user: userstate.username, - username: userstate["display-name"], - color: userstate.color, - flag: dbUser.flag, - position: location, - streak: streak?.count ?? 0, - lastStreak: lastStreak?.count && !correct ? lastStreak.count : null, - distance, - score, - modified, - }; - } - - /** @returns {Location} */ - getLocation() { - return this.seed.rounds.at(-1); - } - - /** @returns {Location[]} */ - getLocations() { - return this.seed.rounds.map((round) => ({ - lat: round.lat, - lng: round.lng, - panoId: round.panoId, - heading: Math.round(round.heading), - pitch: Math.round(round.pitch), - zoom: round.zoom, - })); - } - - openGuesses() { - this.guessesOpen = true; - } - - closeGuesses() { - this.guessesOpen = false; - } - - /** - * Get the participants for the current round, sorted by who guessed first. - */ - getMultiGuesses() { - return this.#db.getRoundParticipants(this.#roundId); - } - - /** - * Get the scores for the current round, sorted by distance from closest to farthest away. - */ - getRoundResults() { - return this.#db.getRoundResults(this.#roundId); - } - - finishGame() { - return this.#db.finishGame(this.seed.token); - } - - /** - * Get the combined scores for the current game, sorted from highest to lowest score. - */ - getGameResults() { - return this.#db.getGameResults(this.seed.token); - } - - get isFinished() { - return this.seed.state === "finished"; - } - - get mapName() { - return this.seed.mapName; - } - - get mode() { - return { noMove: this.seed.forbidMoving, noPan: this.seed.forbidRotating, noZoom: this.seed.forbidZooming }; - } - - get round() { - return this.seed.round; - } -} - -module.exports = Game; diff --git a/src/Classes/Scoreboard.js b/src/Classes/Scoreboard.js deleted file mode 100644 index 6650f40..0000000 --- a/src/Classes/Scoreboard.js +++ /dev/null @@ -1,510 +0,0 @@ -import formatDuration from "format-duration"; -import "../utils/globalJquery"; -import "jquery-ui-dist/jquery-ui"; -import dataTables from "datatables.net/js/jquery.dataTables"; -dataTables(window, $); -import scrollResize from "datatables.net-plugins/features/scrollResize/dataTables.scrollResize"; -scrollResize(window, $); -import buttons from "datatables.net-buttons/js/dataTables.buttons"; -buttons(window, $); -import colVis from "datatables.net-buttons/js/buttons.colVis"; -colVis(window, $); -import scroller from "datatables.net-scroller/js/dataTables.scroller"; -scroller(window, $); - -// We'll rely on this race condition getting loaded before it's necessary… -// import("datatables.net-plugins/sorting/natural"); - -/** @typedef {import('../types').Guess} Guess */ -/** @typedef {import('../types').RoundScore} RoundScore */ -/** @typedef {import('../types').GameResult} GameResult */ -/** @typedef {import("../types").LatLng} LatLng */ -/** @typedef {import("../types").Location} Location */ - -/** - * @typedef {object} Options - * @prop {(open: boolean) => void} onToggleGuesses - * @prop {import('../types').RendererApi['focusOnGuess']} focusOnGuess - * @prop {import('../types').RendererApi['drawPlayerResults']} drawPlayerResults - */ - -class Scoreboard { - /** - * @param {HTMLElement} container - * @param {Options} props - */ - constructor(container, props) { - this.isMultiGuess = false; - this.isResults = false; - this.isScrolling = false; - this.speed = 50; - this.onToggleGuesses = props.onToggleGuesses; - this.focusOnGuess = props.focusOnGuess; - this.drawPlayerResults = props.drawPlayerResults; - - this.position = JSON.parse(localStorage.getItem("scoreboard_position")) || { - top: 20, - left: 5, - width: 380, - height: 180, - }; - this.container = $(container); - this.scoreboard = $(` -
-
- - GUESSES (0) - -
-
-
- - - - - - - - - - - -
#PlayerStreakDistanceScore
-
- `); - this.container.append(this.scoreboard); - this.title = this.scoreboard.find(".scoreboardTitle"); - this.switchContainer = this.scoreboard.find("#switchContainer"); - this.switchBtn = this.scoreboard.find("#switchBtn"); - - this.scoreboard - .css({ - top: this.position.top, - left: this.position.left, - width: this.position.width, - height: this.position.height, - }) - .resizable({ - handles: "n, e, s, w, ne, se, sw, nw", - containment: this.container, - }) - .draggable({ - containment: this.container, - }) - .on("mouseup", () => { - const currentPosition = this.getPosition(); - if (JSON.stringify(this.position) !== JSON.stringify(currentPosition)) { - this.setPosition(currentPosition); - localStorage.setItem("scoreboard_position", JSON.stringify(currentPosition)); - } - }); - - this.switchBtn.on("change", () => { - this.onToggleGuesses(this.switchBtn.is(":checked")); - }); - - /** @type {{ column: number, state: boolean }[]} */ - this.columnState = JSON.parse(localStorage.getItem("CG_ColVis")) || [ - { column: 0, state: true }, - { column: 2, state: true }, - { column: 3, state: true }, - { column: 4, state: true }, - ]; - - this.table = this.scoreboard.find("#datatable").DataTable({ - info: false, - searching: false, - paging: false, - scrollY: "100px", - scrollResize: true, - scrollCollapse: true, - language: { zeroRecords: " " }, - dom: "Bfrtip", - buttons: [ - { - extend: "colvis", - text: "⚙️", - className: "colvis-btn", - columns: ":not(.noVis)", - }, - ], - columns: [ - { data: "Position" }, - { data: "Player" }, - { - data: "Streak", - render: (data, type) => { - if (type === "display" && data.last != null) { - return `${data.current} [${data.last}]`; - } - return data.current; - }, - }, - { - data: "Distance", - render: (data, type) => { - if (type === "display" || type === "filter") { - return data.display; - } - return data.value; - }, - }, - { - data: "Score", - render: (data, type) => { - if (type === "display" || type === "filter") { - return data.display; - } - return data.value; - }, - }, - ], - columnDefs: [ - { targets: 0, width: "35px", className: "noVis" }, - { targets: 1, width: "auto", className: "noVis" }, - { targets: 2, width: "55px" }, - { targets: 3, width: "100px" }, - { targets: 4, width: "75px", type: "natural" }, - ], - }); - - // Handle ColVis change - this.table.on("column-visibility.dt", (e, settings, column, state) => { - if (this.isResults || this.isMultiGuess) return; - - const i = this.columnState.findIndex((o) => o.column === column); - if (this.columnState[i]) { - this.columnState[i] = { column, state }; - } else { - this.columnState.push({ column, state }); - } - - localStorage.setItem("CG_ColVis", JSON.stringify(this.columnState)); - }); - - // SCROLLER - const slider = $(``).on( - "input", - (e) => { - // @ts-ignore - this.speed = e.currentTarget.value; - this.scroller(".dataTables_scrollBody"); - } - ); - - this.scoreboard.find(".scoreboardSlider").append(slider); - - this.table.buttons().container().appendTo(this.scoreboard.find(".scoreboardSettings")); - - this.table.buttons().container().prepend(` -
- -
- `); - - this.scoreboard.find("#scrollBtn").on( - "change", - /** @param {JQuery.ChangeEvent} e */ (e) => { - if (e.currentTarget.checked != true) { - this.isScrolling = $(e.currentTarget).is(":checked"); - this.stop(".dataTables_scrollBody"); - this.scoreboard.toggleClass("is-slider-visible", false); - } else { - this.isScrolling = $(e.currentTarget).is(":checked"); - this.scroller(".dataTables_scrollBody"); - this.scoreboard.toggleClass("is-slider-visible", true); - } - } - ); - } - - /** - * @param {boolean} isMultiGuess - */ - reset(isMultiGuess) { - this.isMultiGuess = isMultiGuess; - this.setColVis(); - this.isResults = false; - this.setTitle("GUESSES (0)"); - if (this.isMultiGuess) { - this.#setHint("Ordered by guess time"); - } else { - this.#setHint(null); - } - this.showSwitch(true); - - // Removes onClick focusOnGuess - $("#datatable tbody").off("click"); - - this.table.clear().draw(); - } - - /** - * @param {Guess} guess - */ - renderGuess(guess) { - const guessRow = { - Position: "", - Player: `${ - guess.flag ? `` : "" - }${guess.username}`, - Streak: { current: guess.streak, last: null }, - Distance: { value: guess.distance, display: this.toMeter(guess.distance) }, - Score: { value: guess.score, display: guess.score }, - }; - - // @ts-ignore - const rowNode = this.table.row.add(guessRow).node(); - rowNode.classList.add("expand"); - setTimeout(() => { - rowNode.classList.remove("expand"); - }, 200); - - this.table.order([3, "asc"]).draw(false); - this.table - .column(0) - .nodes() - .each((cell, i) => { - cell.innerHTML = i + 1; - }); - - this.setTitle(`GUESSES (${this.table.rows().data().length})`); - } - - /** - * @param {{ username: string, flag: string | null, color: string }[]} guesses - */ - renderMultiGuess(guesses) { - const rows = guesses.map((guess) => { - return { - Position: "", - Player: `${ - guess.flag - ? `` - : "" - }${guess.username}`, - Streak: { current: 0, last: null }, - Distance: { value: 0, display: "" }, - Score: { value: 0, display: "" }, - }; - }); - - this.table.clear().draw(); - this.table.rows.add(rows).draw(); - - this.setTitle(`GUESSES (${this.table.rows().data().length})`); - } - - /** - * @param {RoundScore[]} roundResults - * @param {number} limit - */ - displayRoundResults(roundResults, limit = 100) { - this.isResults = true; - this.#setHint(null); - - const rows = roundResults.map((result) => { - const isTimed5k = result.score === 5000; - const distanceDisplay = this.toMeter(result.distance); - return { - Position: "", - Player: `${ - result.flag - ? `` - : "" - }${result.username}`, - Streak: { current: result.streak, last: result.lastStreak }, - Distance: { - value: result.distance, - display: isTimed5k ? `${distanceDisplay} [${formatDuration(result.time * 1000)}]` : distanceDisplay, - }, - Score: { value: result.score, display: result.score }, - }; - }); - - this.table.clear().draw(); - this.table.rows.add(rows); - this.table.order([4, "desc"]).draw(false); - - let content; - this.table - .column(0) - .nodes() - .each((cell, i) => { - content = i + 1; - cell.innerHTML = content; - }); - - // onClick focusOnGuess - const self = this; - $("#datatable tbody").on("click", "tr", function () { - const index = self.table.row(this).index(); - if (index >= limit) return; - self.focusOnGuess(roundResults[index].position); - }); - - // Restore columns visibility - this.table.columns().visible(true); - this.toTop(".dataTables_scrollBody"); - } - - /** - * @param {Location[]} locations - * @param {GameResult[]} gameResults - */ - displayGameResults(locations = [], gameResults) { - this.isResults = true; - this.#setHint(null); - - const rows = gameResults.map((result) => { - const distanceDisplay = this.toMeter(result.totalDistance); - return { - Position: "", - Player: `${ - result.flag - ? `` - : "" - }${result.username}`, - Streak: { current: result.streak }, - Distance: { - value: result.totalDistance, - display: distanceDisplay, - }, - Score: { - value: result.totalScore, - display: `${result.totalScore} [${result.guesses.filter(Boolean).length}]`, - }, - }; - }); - - this.table.clear().draw(); - this.table.rows.add(rows); - this.table.order([4, "desc"]).draw(false); - - let content; - this.table - .column(0) - .nodes() - .each((cell, i) => { - content = i + 1; - if (i == 0) content = "🏆"; - else if (i == 1) content = "🥈"; - else if (i == 2) content = "🥉"; - cell.innerHTML = content; - }); - - // Removes previous onClick focusOnGuess - $("#datatable tbody").off("click"); - - const self = this; - $("#datatable tbody").on("click", "tr", function () { - const index = self.table.row(this).index(); - self.drawPlayerResults(locations, gameResults[index]); - }); - - // Restore columns visibility - this.table.columns().visible(true); - this.toTop(".dataTables_scrollBody"); - } - - scroller(elem) { - const div = $(elem); - - const loop = () => { - if (!this.isScrolling) return; - div.stop().animate( - { scrollTop: div[0].scrollHeight }, - (div[0].scrollHeight - div.scrollTop() - 84) * this.speed, - "linear", - () => { - setTimeout(() => { - div.stop().animate({ scrollTop: 0 }, 1000, "swing", () => { - setTimeout(() => { - loop(); - }, 3000); - }); - }, 1000); - } - ); - }; - loop(); - } - - toTop(elem) { - this.stop(elem); - setTimeout(() => { - this.scroller(elem); - }, 3000); - } - - stop(elem) { - $(elem).stop(); - } - - setColVis() { - if (this.isMultiGuess) { - this.table.columns([0, 2, 3, 4]).visible(false); - } else { - this.columnState.forEach((column) => { - this.table.column(column.column).visible(column.state); - }); - } - } - - getPosition() { - return { - top: this.scoreboard.position().top, - left: this.scoreboard.position().left, - width: this.scoreboard.width(), - height: this.scoreboard.height(), - }; - } - - setPosition(position) { - return (this.position = position); - } - - setTitle(title) { - return this.title.text(title); - } - /** - * @param {string|null} text - */ - #setHint(text) { - this.scoreboard.toggleClass("is-hint-visible", !!text); - this.scoreboard.find(".scoreboardHint").text(text || ""); - } - - showSwitch(state) { - return this.switchContainer.css("display", state ? "block" : "none"); - } - - /** - * @param {boolean} state - */ - switchOn(state) { - return this.switchBtn.prop("checked", state); - } - - /** - * @param {number} distance - */ - toMeter(distance) { - return distance >= 1 ? distance.toFixed(1) + "km" : Math.floor(distance * 1000) + "m"; - } - - show() { - this.scoreboard.show(); - } - - hide() { - this.scoreboard.hide(); - } -} - -export default Scoreboard; diff --git a/src/GameHandler.js b/src/GameHandler.js deleted file mode 100644 index 2a83a62..0000000 --- a/src/GameHandler.js +++ /dev/null @@ -1,680 +0,0 @@ -import { ipcMain } from "electron"; -import { once } from "events"; -import Game from "./Classes/Game"; -import GameHelper from "./utils/GameHelper"; -import Settings from "./utils/Settings"; -import TwitchBackend from "./backend/twitch"; -import flags from "./utils/flags"; -import createSettingsWindow from "./Windows/settings/SettingsWindow"; -import store from "./utils/sharedStore"; -import { io } from "socket.io-client"; - -const SOCKET_SERVER_URL = process.env.SOCKET_SERVER_URL ?? "https://chatguessr-server.herokuapp.com"; -const settings = Settings.read(); - -/** @typedef {import('./types').Guess} Guess */ -/** @typedef {import('./types').RoundScore} RoundScore */ -/** @typedef {import('./types').Location} Location */ -/** @typedef {import('./utils/Database')} Database */ -/** @typedef {import('./Windows/MainWindow')} MainWindow */ -/** @typedef {import('electron').BrowserWindow} BrowserWindow */ -/** @typedef {import('socket.io-client').Socket} Socket */ - -class GameHandler { - /** @type {Database} */ - #db; - - /** - * @type {MainWindow} - */ - #win; - - /** - * @type {BrowserWindow|undefined} - */ - #settingsWindow; - - /** - * @type {import("@supabase/supabase-js").Session|undefined} - */ - #session; - - /** - * @type {TwitchBackend|undefined} - */ - #backend; - - /** - * @type {Socket} - */ - #socket; - - /** - * @type {Game} - */ - #game; - - #requestAuthentication; - - /** - * @param {Database} db - * @param {MainWindow} win - * @param {{ requestAuthentication: () => Promise }} options - */ - constructor(db, win, options) { - this.#db = db; - this.#win = win; - this.#backend = undefined; - this.#socket = undefined; - this.#game = new Game(db, settings); - this.#requestAuthentication = options.requestAuthentication; - this.init(); - } - - openGuesses() { - this.#game.openGuesses(); - this.#win.webContents.send("switch-on"); - this.#backend.sendMessage("Guesses are open...", { system: true }); - } - - closeGuesses() { - this.#game.closeGuesses(); - this.#win.webContents.send("switch-off"); - this.#backend.sendMessage("Guesses are closed.", { system: true }); - } - - nextRound() { - if (this.#game.isFinished) { - this.#game.finishGame(); - this.#showGameResults(); - } else { - this.#win.webContents.send("next-round", this.#game.isMultiGuess, this.#game.getLocation()); - this.#backend.sendMessage(`🌎 Round ${this.#game.round} has started`, { system: true }); - this.openGuesses(); - } - } - - returnToMapPage() { - const mapUrl = this.#game.seed.map; - this.#win.loadURL(`https://www.geoguessr.com/maps/${mapUrl}/play`); - } - - /** - * @param {Location} location - * @param {RoundScore[]} roundResults - */ - #showRoundResults(location, roundResults) { - const round = this.#game.isFinished ? this.#game.round : this.#game.round - 1; - - if (roundResults[0]) roundResults[0].color = "#E3BB39"; - if (roundResults[1]) roundResults[1].color = "#C9C9C9"; - if (roundResults[2]) roundResults[2].color = "#A3682E"; - - const { guessMarkersLimit } = Settings.read(); - this.#win.webContents.send("show-round-results", round, location, roundResults, guessMarkersLimit); - this.#backend.sendMessage( - `🌎 Round ${round} has finished. Congrats ${flags.getEmoji(roundResults[0].flag)} ${ - roundResults[0].username - } !`, - { system: true } - ); - } - - async #showGameResults() { - const gameResults = this.#game.getGameResults(); - const locations = this.#game.getLocations(); - - if (gameResults[0]) gameResults[0].color = "#E3BB39"; - if (gameResults[1]) gameResults[1].color = "#C9C9C9"; - if (gameResults[2]) gameResults[2].color = "#A3682E"; - - this.#win.webContents.send("show-game-results", locations, gameResults); - - /** @type {string|undefined} */ - let link; - try { - link = await GameHelper.makeLink( - this.#session.access_token, - this.#session.user.user_metadata.name, - settings.channelName, - this.#game.mapName, - this.#game.mode, - locations, - gameResults - ); - } catch (error) { - console.error("could not upload summary", error); - } - await this.#backend.sendMessage( - `🌎 Game finished. Congrats ${flags.getEmoji(gameResults[0].flag)} ${gameResults[0].username} 🏆! ${ - link != undefined ? `Game summary: ${link}` : "" - }`, - { system: true } - ); - } - - init() { - // Browser Listening - this.#win.webContents.on("did-navigate-in-page", (_event, url) => { - if (GameHelper.isGameURL(url)) { - // TODO(reanna) warn about the thing not being connected - if (!this.#backend) return; - - this.#game - .start(url, settings.isMultiGuess) - .then(() => { - const guesses = this.#game.isMultiGuess - ? this.#game.getMultiGuesses() - : this.#game.getRoundResults(); - this.#win.webContents.send( - "game-started", - this.#game.isMultiGuess, - guesses, - this.#game.getLocation() - ); - - if (guesses.length > 0) { - this.#backend.sendMessage(`🌎 Round ${this.#game.round} has resumed`, { system: true }); - } else if (this.#game.round === 1) { - this.#backend.sendMessage(`🌎 A new seed of ${this.#game.mapName} has started`, { - system: true, - }); - } else { - this.#backend.sendMessage(`🌎 Round ${this.#game.round} has started`, { system: true }); - } - - this.openGuesses(); - }) - .catch((error) => { - console.error(error); - }); - } else { - this.#game.outGame(); - this.#win.webContents.send("game-quitted"); - } - }); - - this.#win.webContents.on("did-frame-finish-load", () => { - if (!this.#game.isInGame) return; - - this.#win.webContents.executeJavaScript(` - window.nextRoundBtn = document.querySelector('[data-qa="close-round-result"]'); - window.playAgainBtn = document.querySelector('[data-qa="play-again-button"]'); - - if (window.nextRoundBtn) { - nextRoundBtn.addEventListener("click", () => { - nextRoundBtn.setAttribute('disabled', 'disabled'); - chatguessrApi.startNextRound(); - }); - } - - if (window.playAgainBtn) { - playAgainBtn.addEventListener("click", () => { - playAgainBtn.setAttribute('disabled', 'disabled'); - chatguessrApi.returnToMapPage(); - }); - } - `); - - if (this.#game.isFinished) return; - - this.#win.webContents.send("refreshed-in-game", this.#game.getLocation()); - // Checks and update seed when the this.game has refreshed - // update the current location if it was skipped - // if the streamer has guessed returns scores - this.#game.refreshSeed().then((roundResults) => { - if (roundResults) { - this.#showRoundResults(roundResults.location, roundResults.roundResults); - } - }); - }); - - ipcMain.on("next-round-click", () => { - this.nextRound(); - }); - - ipcMain.on("return-to-map-page", () => { - this.returnToMapPage(); - }); - - ipcMain.on("open-guesses", () => { - this.openGuesses(); - }); - - ipcMain.on("close-guesses", () => { - if (this.#game.guessesOpen) this.closeGuesses(); - }); - - ipcMain.on("save-global-settings", (_event, globalSettings) => { - settings.saveGlobalSettings(globalSettings); - this.#settingsWindow?.close(); - }); - - ipcMain.on("save-twitch-settings", (_event, channelName) => { - settings.saveTwitchSettings(channelName); - this.#requestAuthentication(); - }); - - ipcMain.on("add-banned-user", (_event, username) => { - this.#db.addBannedUser(username); - }); - - ipcMain.on("delete-banned-user", (_event, username) => { - this.#db.deleteBannedUser(username); - }); - - ipcMain.on("closeSettings", () => { - this.closeSettingsWindow(); - }); - - ipcMain.on("openSettings", () => { - this.openSettingsWindow(); - }); - - ipcMain.on("clearStats", async () => { - store.delete("users"); // from pre-sqlite chatguessr versions - store.delete("lastRoundPlayers"); // from even older versions - await this.#db.clear(); - await this.#backend.sendMessage("All stats cleared 🗑️", { system: true }); - }); - } - - getConnectionState() { - if (!this.#backend) { - return { state: "disconnected" }; - } else if (this.#backend.isConnected()) { - return { - state: "connected", - botUsername: this.#backend.botUsername, - channelName: this.#backend.channelName, - }; - } - return { state: "connecting" }; - } - - /** - * @param {import("@supabase/supabase-js").Session} session - */ - async authenticate(session) { - this.#session = session; - await this.#initBackend(session); - await this.#initSocket(session); - } - - /** - * @param {import("@supabase/supabase-js").Session} session - */ - async #initBackend(session) { - this.#backend?.close(); - this.#backend = undefined; - if (!settings.channelName) { - return; - } - if (session.user.app_metadata.provider === "twitch") { - this.#backend = new TwitchBackend({ - botUsername: session.user.user_metadata.name, - channelName: settings.channelName, - whisperToken: session.provider_token, - }); - } else { - throw new Error("unsupported provider"); - } - - const emitConnectionState = () => { - const state = this.getConnectionState(); - this.#win.webContents.send("connection-state", state); - this.#settingsWindow?.webContents.send("connection-state", state); - }; - - this.#backend.on("connected", () => { - emitConnectionState(); - this.#backend.sendMessage("is now connected", { system: true }); - }); - this.#backend.on("disconnected", (requestedClose) => { - emitConnectionState(); - if (!requestedClose) { - // Try to reconnect. - this.#requestAuthentication(); - } - }); - - this.#backend.on("guess", (userstate, message) => { - this.#handleGuess(userstate, message).catch((error) => { - console.error(error); - }); - }); - - this.#backend.on("message", (userstate, message) => { - this.#handleMessage(userstate, message).catch((error) => { - console.error(error); - }); - }); - - emitConnectionState(); - try { - await this.#backend.connect(); - } catch (error) { - if (this.#settingsWindow) { - this.#settingsWindow.webContents.send("twitch-error", error); - } - console.error(error); - } - } - - /** - * @param {import("tmi.js").ChatUserstate} userstate - * @param {string} message - */ - async #handleGuess(userstate, message) { - if (!message.startsWith("!g") || !this.#game.guessesOpen) return; - // Ignore guesses made by the broadcaster with the CG map: prevents seemingly duplicate guesses - if (userstate.username.toLowerCase() === settings.channelName.toLowerCase()) return; - - // Check if user is banned - const bannedUsers = this.#db.getBannedUsers(); - const isBanned = bannedUsers.some((user) => user.username === userstate.username); - if (isBanned) return; - - const location = GameHelper.parseCoordinates(message.replace(/^!g\s+/, "")); - - if (!location) return; - - try { - const guess = await this.#game.handleUserGuess(userstate, location); - - if (!this.#game.isMultiGuess) { - this.#win.webContents.send("render-guess", guess); - if (settings.showHasGuessed) { - await this.#backend.sendMessage( - `${flags.getEmoji(guess.flag)} ${userstate["display-name"]} has guessed` - ); - } - } else { - const guesses = this.#game.getMultiGuesses(); - this.#win.webContents.send("render-multiguess", guesses); - if (!guess.modified) { - if (settings.showHasGuessed) { - await this.#backend.sendMessage( - `${flags.getEmoji(guess.flag)} ${userstate["display-name"]} has guessed` - ); - } - } else { - if (settings.showGuessChanged) { - await this.#backend.sendMessage( - `${flags.getEmoji(guess.flag)} ${userstate["display-name"]} guess changed` - ); - } - } - } - } catch (err) { - if (err.code === "alreadyGuessed") { - if (settings.showHasAlreadyGuessed) { - await this.#backend.sendMessage(`${userstate["display-name"]} you already guessed`); - } - } else if (err.code === "submittedPreviousGuess") { - if (settings.showSubmittedPreviousGuess) { - await this.#backend.sendMessage(`${userstate["display-name"]} you submitted your previous guess`); - } - } else { - console.error(err); - } - } - } - - /** - * @type {boolean} - */ - #cgCooldown = false; - - /** - * @type {boolean} - */ - #mapCooldown = false; - - /** - * @param {import("tmi.js").ChatUserstate} userstate - * @param {string} message - */ - async #handleMessage(userstate, message) { - if (!message.startsWith("!")) return; - message = message.trim().toLowerCase(); - - const userId = userstate.badges?.broadcaster === "1" ? "BROADCASTER" : userstate["user-id"]; - - if (message === settings.cgCmd) { - if (userId === "BROADCASTER") { - await this.#backend.sendMessage( - settings.cgMsg.replace("", `chatguessr.com/map/${this.#backend.botUsername}`) - ); - } else if (!this.#cgCooldown) { - await this.#backend.sendMessage( - settings.cgMsg.replace("", `chatguessr.com/map/${this.#backend.botUsername}`) - ); - this.#cgCooldown = true; - setTimeout(() => { - this.#cgCooldown = false; - }, settings.cgCmdCooldown * 1000); - } - return; - } - - if (message.startsWith("!flag ")) { - const countryReq = message.slice(message.indexOf(" ") + 1).trim(); - const dbUser = this.#db.getOrCreateUser(userId, userstate["display-name"]); - - let newFlag; - if (countryReq === "none") { - newFlag = null; - } else if (countryReq === "random") { - newFlag = flags.randomCountryFlag(); - } else { - newFlag = flags.selectFlag(countryReq); - if (!newFlag) { - await this.#backend.sendMessage(`${userstate["display-name"]} no flag found`); - return; - } - } - - this.#db.setUserFlag(dbUser.id, newFlag); - - if (countryReq === "none") { - await this.#backend.sendMessage(`${userstate["display-name"]} flag removed`); - } else if (countryReq === "random") { - await this.#backend.sendMessage(`${userstate["display-name"]} got ${flags.getEmoji(newFlag)}`); - } - return; - } - - if (message === settings.flagsCmd) { - await this.#backend.sendMessage(settings.flagsCmdMsg); - } - - if (message === settings.mapCmd) { - // We'll only have a map ID if we're - if(!this.#game.isInGame || !this.#game.seed || !this.#game.seed.map) { - return; - } - - // Allow the broadcaster to circumvent the cooldown - if(this.#mapCooldown && userId !== "BROADCASTER") { - return; - } - this.#mapCooldown = true; - - const map = await GameHelper.fetchMap(this.#game.seed.map); - await this.#backend.sendMessage(`🌎 Now playing '${map.name}' by ${map.creator.nick}, played ${map.numFinishedGames} times with ${map.likes} likes: ${map.description}` ); - - setTimeout(() => { - this.#mapCooldown = false; - }, settings.mapCmdCooldown * 1000); - } - - if (message === settings.getUserStatsCmd) { - const userInfo = this.#db.getUserStats(userId); - if (!userInfo) { - await this.#backend.sendMessage(`${userstate["display-name"]} you've never guessed yet.`); - } else { - await this.#backend.sendMessage(` - ${flags.getEmoji(userInfo.flag)} ${userInfo.username} : Current streak: ${userInfo.streak}. - Best streak: ${userInfo.bestStreak}. - Correct countries: ${userInfo.correctGuesses}/${userInfo.nbGuesses}${ - userInfo.nbGuesses > 0 - ? ` (${((userInfo.correctGuesses / userInfo.nbGuesses) * 100).toFixed(2)}%).` - : "." - } - Avg. score: ${Math.round(userInfo.meanScore)}. - Victories: ${userInfo.victories}. - Perfects: ${userInfo.perfects}. - `); - } - return; - } - - if (message === settings.getBestStatsCmd) { - const { streak, victories, perfects } = this.#db.getGlobalStats(); - if (!streak && !victories && !perfects) { - await this.#backend.sendMessage("No stats available."); - } else { - let msg = ""; - if (streak) { - msg += `Streak: ${streak.streak} (${streak.username}). `; - } - if (victories) { - msg += `Victories: ${victories.victories} (${victories.username}). `; - } - if (perfects) { - msg += `Perfects: ${perfects.perfects} (${perfects.username}). `; - } - await this.#backend.sendMessage(`Channels best: ${msg}`); - } - return; - } - - if (message === settings.clearUserStatsCmd) { - // @ts-ignore - store.delete(`users.${userstate.username}`); - - const dbUser = this.#db.getUser(userId); - if (dbUser) { - this.#db.resetUserStats(dbUser.id); - await this.#backend.sendMessage( - `${flags.getEmoji(dbUser.flag)} ${userstate["display-name"]} 🗑️ stats cleared !` - ); - } else { - await this.#backend.sendMessage(`${userstate["display-name"]} you've never guessed yet.`); - } - - return; - } - - if (message === settings.randomPlonkCmd) { - const { lat, lng } = await GameHelper.getRandomCoordsInLand(this.#game.seed.bounds); - const randomGuess = `!g ${lat}, ${lng}`; - this.#handleGuess(userstate, randomGuess).catch((error) => { - console.error(error); - }); - } - - // streamer commands - if (userstate.badges?.broadcaster !== "1") { - return; - } - if (process.env.NODE_ENV !== "development") { - return; - } - - if (message.startsWith("!spamguess")) { - const max = parseInt(message.split(" ")[1] ?? "50", 10); - let i = 0; - const interval = setInterval(async () => { - const { lat, lng } = await GameHelper.getRandomCoordsInLand(); - await this.#handleGuess( - { - "user-id": `123450${i}`, - username: `fake_${i}`, - "display-name": `fake_${i}`, - color: `#${Math.random().toString(16).slice(2, 8).padStart(6, "0")}`, - }, - `!g ${lat},${lng}` - ); - i++; - if (i === max) { - clearInterval(interval); - } - }, 200); - } - } - - /** - * @param {import("@supabase/supabase-js").Session} session - */ - async #initSocket(session) { - if (this.#socket?.connected) { - this.#socket.disconnect(); - } - - const botUsername = session.user.user_metadata.name; - - this.#socket = io(SOCKET_SERVER_URL, { - transportOptions: { - polling: { - extraHeaders: { - access_token: session.access_token, - channelname: settings.channelName, - bot: botUsername, - }, - }, - }, - }); - - this.#socket.on("connect", () => { - this.#socket.emit("join", botUsername); - if (this.#settingsWindow) { - this.#settingsWindow.webContents.send("socket-connected"); - } - }); - - this.#socket.on("disconnect", (reason) => { - if (this.#settingsWindow) { - this.#settingsWindow.webContents.send("socket-disconnected"); - } - }); - - this.#socket.on("guess", (userData, guess) => { - this.#handleGuess(userData, guess).catch((error) => { - console.error(error); - }); - }); - - await once(this.#socket, "connect"); - } - - openSettingsWindow() { - // Initialise the window if it doesn't exist, - // especially important in non-windows systems where Chatguessr may not be able - // to prevent the window from being completely closed. - if (!this.#settingsWindow) { - this.#settingsWindow = createSettingsWindow(this.#win).on("closed", () => { - this.#settingsWindow = undefined; - }); - - this.#settingsWindow.webContents.on("did-finish-load", () => { - this.#settingsWindow.webContents.send( - "render-settings", - settings, - this.#db.getBannedUsers(), - this.getConnectionState(), - this.#socket?.connected - ); - - this.#settingsWindow.show(); - }); - } - } - - closeSettingsWindow() { - this.#settingsWindow?.close(); - } -} - -export default GameHandler; diff --git a/src/Windows/MainWindow.js b/src/Windows/MainWindow.js deleted file mode 100644 index 25b9c6d..0000000 --- a/src/Windows/MainWindow.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; - -const path = require("path"); -const fs = require("fs"); -const { BrowserWindow, shell } = require("electron"); -const styles = ` - ${require("bundle-text:../../assets/styles.css")} - ${fs.readFileSync(path.join(__dirname, "../../dist/cg-renderer/renderer.css"), "utf8")} -`; -const js = fs.readFileSync(path.join(__dirname, "../../dist/cg-renderer/renderer.js"), "utf8"); - -function mainWindow() { - let win = new BrowserWindow({ - show: false, - webPreferences: { - preload: path.join(__dirname, "../../dist/cg-preload/preload.js"), - contextIsolation: true, - nodeIntegration: false, - sandbox: false, // TODO enable - webSecurity: false, - devTools: process.env.NODE_ENV === "development", - }, - }); - - if (process.env.NODE_ENV === "development") win.webContents.openDevTools(); - win.setMenuBarVisibility(false); - - win.webContents.on("dom-ready", async () => { - await win.webContents.insertCSS(styles); - await win.webContents.executeJavaScript(js); - }); - - win.webContents.setWindowOpenHandler(({ url }) => { - if ( - url.startsWith('https://www.facebook.com') || - url.startsWith('https://accounts.google.com') || - url.startsWith('https://appleid.apple.com') - ) { - return { action: "allow" }; - } else { - shell.openExternal(url); - return { action: "deny" }; - } - }) - - win.loadURL("https://www.geoguessr.com/community/maps"); - - return win; -} - -module.exports = mainWindow(); diff --git a/src/Windows/auth/AuthWindow.js b/src/Windows/auth/AuthWindow.js deleted file mode 100644 index 298d75f..0000000 --- a/src/Windows/auth/AuthWindow.js +++ /dev/null @@ -1,55 +0,0 @@ -"use strict"; - -const path = require("path"); -const { BrowserWindow, shell } = require("electron"); - -/** - * @param {BrowserWindow} parentWindow - * @param {{ authUrl?: string | undefined, clearStorageData: boolean }} options - */ -async function createAuthWindow(parentWindow, options) { - let win = new BrowserWindow({ - height: 800, - parent: parentWindow, - show: false, - modal: true, - webPreferences: { - preload: path.join(__dirname, "../../../dist/auth-preload/preload.js"), - // Use a separate browser session so we can force log people out of - // Twitch without logging them out of GeoGuessr. - partition: "persist:backendAuth", - contextIsolation: true, - nodeIntegration: false, - devTools: process.env.NODE_ENV === "development", - }, - }); - win.setMenuBarVisibility(false); - - win.webContents.setWindowOpenHandler(({ url }) => { - shell.openExternal(url); - return { action: "deny" }; - }); - - win.webContents.on("did-navigate", (_event, url) => { - // If we can go through the auth process without user interaction, we would end up at /streamer/redirect. - // We don't need to show the window at all then. - const isTwitchHeadlessUrl = url.startsWith("https://id.twitch.tv/oauth2/authorize?client_id"); - const isSuccessfulRedirectUrl = url.includes("streamer/redirect#access_token"); - if (!isTwitchHeadlessUrl && !isSuccessfulRedirectUrl) { - win.show(); - } - }); - - if (options.clearStorageData) { - await win.webContents.session.clearStorageData(); - } - - win.loadURL(options.authUrl ?? `file://${path.join(__dirname, "../../../dist/auth/index.html")}`); - if (process.env.NODE_ENV === "development") { - win.webContents.openDevTools(); - } - - return win; -} - -module.exports = createAuthWindow; diff --git a/src/Windows/auth/impl.js b/src/Windows/auth/impl.js deleted file mode 100644 index 344ec67..0000000 --- a/src/Windows/auth/impl.js +++ /dev/null @@ -1,11 +0,0 @@ -import { supabase } from "../../utils/supabase"; - -/** @type {HTMLButtonElement} */ -const startAuth = document.querySelector("#start-auth"); -startAuth.addEventListener("click", () => { - startAuth.disabled = true; - supabase.auth.signOut().finally(() => { - // @ts-expect-error TS2304: defined by preload script - chatguessrApi.startAuth(); - }); -}); \ No newline at end of file diff --git a/src/Windows/auth/index.html b/src/Windows/auth/index.html deleted file mode 100644 index 0b086f5..0000000 --- a/src/Windows/auth/index.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Twitch Setup - - - -
-
-

- To use ChatGuessr, you have to log in with Twitch. We recommend logging in using a bot account or second account, not your main streamer account. -

- - -
-
- - - diff --git a/src/Windows/auth/preload.js b/src/Windows/auth/preload.js deleted file mode 100644 index 75bcd5e..0000000 --- a/src/Windows/auth/preload.js +++ /dev/null @@ -1,13 +0,0 @@ -const { contextBridge, ipcRenderer } = require("electron"); - -contextBridge.exposeInMainWorld("chatguessrApi", { - startAuth() { - ipcRenderer.invoke("start-auth"); - }, - /** - * @param {import('@supabase/supabase-js').Session} session - */ - setSession(session) { - ipcRenderer.send("set-session", session); - }, -}); \ No newline at end of file diff --git a/src/Windows/auth/styles.css b/src/Windows/auth/styles.css deleted file mode 100644 index c4759d2..0000000 --- a/src/Windows/auth/styles.css +++ /dev/null @@ -1,118 +0,0 @@ -@font-face { - font-family: Comfortaa; - src: url(asset:fonts/Comfortaa-Regular.ttf) format("ttf"); - font-weight: 300; - font-style: normal; -} -@font-face { - font-family: Comfortaa; - src: url(asset:fonts/Comfortaa-Bold.ttf) format("ttf"); - font-weight: 700; - font-style: normal; -} - -:root { - --clr-primary: #59ffd8; - --clr-secondary: #a159ff; - --clr-notice: #fbfd70; - --clr-danger: #ff8e65; - --bg-color: #252525; -} - -html { - background: var(--bg-color); - font-family: "Comfortaa", sans-serif; - font-size: 14px; - color: #fff; - letter-spacing: 0.03rem; - -webkit-font-smoothing: antialiased; - font-weight: 300; -} - -.container { - padding: 0.5rem; -} - -.flex { - display: flex; - justify-content: center; - align-items: center; - flex-wrap: wrap; -} - -.card, -.notif { - background: rgba(180, 180, 180, 0.1); - border-radius: 5px; - box-shadow: 1px 0px 5px rgb(0, 0, 0, 0.15); - padding: 0.5rem; -} -.notif { - margin: 0 auto; -} - -.cards { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(100%, 1fr)); - grid-gap: 0.5rem; -} - -@media only screen and (min-width: 600px) { - .cards { - grid-template-columns: repeat(auto-fit, minmax(370px, 1fr)); - } -} - -.btn { - font-family: inherit; - border: 0; - border-radius: 5px; - outline: 0; - position: relative; - color: rgb(255, 255, 255); - padding: 10px; - font-weight: 700; - margin: 2px; - cursor: pointer; - background: none; - transition: transform 100ms ease-in-out; - box-shadow: 0 1px 3px rgb(0 0 0 / 12%), 0 1px 2px rgb(0 0 0 / 24%); -} -.btn:hover { - transform: translateY(1px); -} -.btn:active { - transform: translateY(2px); -} - -.btn-sep { - width: 100%; - padding-left: 30px; -} -.btn-sep:before { - font-weight: 300; - font-family: "FontAwesome"; - background: var(--clr-primary); - color: black; - position: absolute; - height: 100%; - left: 0; - top: 0; - line-height: 1.6; - font-size: 1.5rem; - width: 40px; -} -.btn-sep:after { - content: ""; - position: absolute; -} - -.danger { - background: var(--clr-danger); - color: black; -} - -.btn.twitch { - background: var(--clr-secondary); - color: white; -} \ No newline at end of file diff --git a/src/Windows/settings/SettingsWindow.js b/src/Windows/settings/SettingsWindow.js deleted file mode 100644 index 268fd6a..0000000 --- a/src/Windows/settings/SettingsWindow.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -const path = require("path"); -const { BrowserWindow, shell } = require("electron"); - -/** - * @param {BrowserWindow} parentWindow - */ -function createSettingsWindow(parentWindow) { - const isLinux = process.platform === "linux"; - - const win = new BrowserWindow({ - title: "Chatguessr Settings", - parent: parentWindow, - width: 750, - height: 720, - minWidth: 750, - minHeight: 720, - show: false, - fullscreen: false, - maximizable: false, - frame: isLinux ? true : false, - transparent: isLinux ? false : true, - webPreferences: { - nodeIntegration: true, - contextIsolation: false, - devTools: process.env.NODE_ENV === "development", - }, - }); - win.setMenuBarVisibility(false); - win.loadURL(`file://${path.join(__dirname, "../../../dist/settings/settings.html")}`); - - win.webContents.setWindowOpenHandler(({ url }) => { - shell.openExternal(url); - return { action: "deny" }; - }); - - return win; -} - -module.exports = createSettingsWindow; diff --git a/src/Windows/settings/settings.css b/src/Windows/settings/settings.css deleted file mode 100644 index d385e17..0000000 --- a/src/Windows/settings/settings.css +++ /dev/null @@ -1,301 +0,0 @@ -@font-face { - font-family: Montserrat; - src: url(asset:fonts/montserrat-regular-webfont.woff2) format("woff2"), - url(asset:fonts/montserrat-regular-webfont.woff) format("woff"); - font-weight: 400; - font-style: normal; -} -*, -::after, -::before { - margin: 0; - box-sizing: border-box; -} -body { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - font-size: 14px; -} -h2, -h3 { - margin: 0.8rem 0; -} -a { - color: #70e2a9; - text-decoration: inherit; - -webkit-app-region: no-drag; -} -a:hover { - color: #8ce9ba; -} -input, -label, -textarea, -button { - -webkit-app-region: no-drag; -} -input::-webkit-outer-spin-button, -input::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; -} -textarea { - resize: vertical; -} -hr { - margin: 1rem; - border: 1px solid #70e2a9; -} -small { - font-size: 0.8rem; -} -.settings-container { - position: relative; - height: 100%; - width: 100%; - background: rgba(0, 0, 0, 0.8); - font-family: Montserrat, sans-serif; - color: #fff; - border-radius: 0.3rem; - -webkit-app-region: drag; - -webkit-user-select: none; - user-select: none; -} -.grid__col { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 1rem; -} -.tab { - overflow: hidden; - border-radius: 0.3rem; - display: grid; - grid-template-columns: 1fr 1fr 1fr 40px; -} -.tab button { - float: left; - border: none; - outline: 0; - cursor: pointer; - height: 40px; - transition: 0.3s; - font-size: 17px; - font-weight: 700; - color: #fff; - -webkit-app-region: no-drag; -} -.tablinks { - background: #2e2e2ead; -} -.tablinks:hover { - background: #4fc489; -} -.tablinks.active { - background: #70e2a9; -} -.tabcontent { - display: none; - padding: 0.5rem 1rem; - border-top: none; -} -.close { - background: #c91414; -} -.close:hover { - background: #a02727; -} -.close:active { - background: #a02727; -} -.form__group { - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 1rem; -} -.form__field { - font-family: inherit; - /* font-size: 1rem; */ - border: 0; - outline: 0; - color: #fff; - background: none; - border-bottom: 1px solid #fff; -} -.form__field:focus { - font-weight: 700; - border-color: #70e2a9; -} -textarea.form__field { - width: 100%; -} -.form__label { - font-weight: 700; -} -.btn { - padding: 10px 20px; - font-family: inherit; - font-weight: 700; - border-radius: 0.5rem; - border: none; - color: #000; - box-shadow: 0 1px 3px rgb(0 0 0 / 12%), 0 1px 2px rgb(0 0 0 / 24%); - cursor: pointer; -} -.btn:focus { - outline: 0; -} - -input[type="number"] { - padding: 0.18rem 0; - background: #292929; - color: #fff; - text-align: center; - border-radius: 5px; - border: 1px solid #fff; - overflow: hidden; - outline: 0; - cursor: pointer; -} -input[type="number"]:focus { - border-color: #70e2a9; -} - -.checkbox-container { - display: block; - position: relative; - margin-bottom: 10px; - padding-left: 25px; - cursor: pointer; -} -.checkbox-container input { - position: absolute; - opacity: 0; - cursor: pointer; - height: 0; - width: 0; -} -.checkmark { - position: absolute; - top: 0; - left: 0; - height: 16px; - width: 16px; - background: #eee; -} -.checkbox-container:hover input ~ .checkmark { - background: #dddddd; -} -.checkbox-container input:checked ~ .checkmark { - background: #55cf92; -} -.checkmark:after { - content: ""; - position: absolute; - display: none; -} -.checkbox-container input:checked ~ .checkmark:after { - display: block; -} -.checkbox-container .checkmark:after { - left: 5px; - width: 7px; - height: 12px; - border: solid #fff; - border-width: 0 3px 3px 0; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} -[data-tip] { - position: relative; -} -[data-tip]:before { - content: ""; - display: none; - content: ""; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid #fff; - position: absolute; - top: 30px; - right: 35px; - z-index: 8; - font-size: 0; - line-height: 0; - width: 0; - height: 0; -} -[data-tip]:after { - width: 200px; - display: none; - content: attr(data-tip); - position: absolute; - top: 35px; - right: 0; - padding: 12px; - background: #fff; - color: #1a1a1a; - z-index: 999; - font-size: 14px; - font-weight: 700; - border-radius: 5px; - word-wrap: break-word; - text-align: center; -} -[data-tip]:hover:after, -[data-tip]:hover:before { - display: block; -} - -.flex { - display: flex; -} -.flex-center { - display: flex; - align-items: center; -} -.flex-around { - display: flex; - justify-content: space-around; -} -.wrap { - flex-wrap: wrap; -} -.gap-05 { - gap: 0.5rem; -} -.w-full { - width: 100%; -} -.success { - background: #5ad497; -} -.success:hover { - background: #56ca90; -} -.success:active { - background: #4eb883; -} -.danger { - background: #c9534e; -} -.danger:hover { - background: #bd4e4a; -} -.danger:active { - background: #b64945; -} -#bannedUsersList { - -webkit-app-region: no-drag; -} -.badge { - cursor: pointer; - padding: 5px; - border-radius: 5px; - box-shadow: 0 1px 3px rgb(0 0 0 / 12%), 0 1px 2px rgb(0 0 0 / 24%); -} diff --git a/src/Windows/settings/settings.html b/src/Windows/settings/settings.html deleted file mode 100644 index 2436121..0000000 --- a/src/Windows/settings/settings.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - Settings - - - -
-
- - - - -
- -
-

Game Settings

-
- -
- -
- -
- -
- -

Twitch notifications

- - - - - - - - -
- -

Twitch commands (leave empty to disable)

-
-
-
- -
- -
-
-
- -
-
- -
- -
-
-
-
- -
- - -
- -
-
-
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
-
- -
-
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
-
-
- - - -
- -

- -

- -
- -
-
- -
-
-

Status :

- -
- - -
- -
- -
- -
- -
- -
-
- - - -
-
- -
-
-
- - -
-
-

Banned users :

-
-
-
- - - diff --git a/src/Windows/settings/settings.js b/src/Windows/settings/settings.js deleted file mode 100644 index ff1099c..0000000 --- a/src/Windows/settings/settings.js +++ /dev/null @@ -1,295 +0,0 @@ -"use strict"; - -// Parcel prevents us from `require`ing things in a "standard" script -// and ONLY wants to output ES modules in a module. We must use `require` -// for electron reasons. This hack prevents Parcel from seeing what we're -// doing. -/** @type {typeof require} */ -// @ts-ignore -const secretRequire = (0, eval("require")); -const { ipcRenderer } = secretRequire("electron"); -const { version } = secretRequire("../../package.json"); // path relative to dist/settings - -/** @type {HTMLInputElement} */ -const channelName = qs("#channelName"); -/** @type {HTMLInputElement} */ -const twitchReauthEl = qs("#twitchReauth"); -/** @type {HTMLInputElement} */ -const cgCmd = qs("#cgCmd"); -/** @type {HTMLInputElement} */ -const cgCmdCooldown = qs("#cgCmdCooldown"); -/** @type {HTMLInputElement} */ -const cgMsg = qs("#cgMsg"); -/** @type {HTMLInputElement} */ -const flagsCmd = qs("#flagsCmd"); -/** @type {HTMLInputElement} */ -const flagsCmdMsg = qs("#flagsCmdMsg"); -/** @type {HTMLInputElement} */ -const getUserStatsCmd = qs("#getUserStatsCmd"); -/** @type {HTMLInputElement} */ -const getBestStatsCmd = qs("#getBestStatsCmd"); -/** @type {HTMLInputElement} */ -const clearUserStatsCmd = qs("#clearUserStatsCmd"); -/** @type {HTMLInputElement} */ -const randomPlonkCmd = qs("#randomPlonkCmd"); -/** @type {HTMLInputElement} */ -const mapCmd = qs("#mapCmd"); -/** @type {HTMLInputElement} */ -const mapCmdCooldown = qs("#mapCmdCooldown"); -/** @type {HTMLInputElement} */ -const showHasGuessed = qs("#showHasGuessed"); -/** @type {HTMLInputElement} */ -const showHasAlreadyGuessed = qs("#showHasAlreadyGuessed"); -/** @type {HTMLInputElement} */ -const showGuessChanged = qs("#showGuessChanged"); -/** @type {HTMLInputElement} */ -const showSubmittedPreviousGuess = qs("#showSubmittedPreviousGuess"); -/** @type {HTMLInputElement} */ -const isMultiGuess = qs("#isMultiGuess"); -/** @type {HTMLInputElement} */ -const guessMarkersLimit = qs("#guessMarkersLimit"); -/** @type {HTMLInputElement} */ -const cgLink = qs("#cgLink"); -/** @type {HTMLElement} */ -const cgLinkContainer = qs("#cgLinkContainer"); -/** @type {HTMLButtonElement} */ -const copyLinkBtn = qs("#copyLinkBtn"); -/** @type {HTMLElement} */ -const twitchStatusElement = qs("#twitchStatus"); -/** @type {HTMLElement} */ -const socketStatusElement = qs("#socketStatus"); -/** @type {HTMLButtonElement} */ -const clearStatsBtn = qs("#clearStatsBtn"); -/** @type {HTMLInputElement} */ -const banUserInput = qs("#banUserInput"); -/** @type {HTMLDivElement} */ -const bannedUsersList = qs("#bannedUsersList"); -/** @type {HTMLElement} */ -const versionText = qs("#version"); - -let bannedUsersArr = []; - -ipcRenderer.on("render-settings", (_event, settings, bannedUsers, connectionState, socketStatus) => { - channelName.value = settings.channelName; - cgCmd.value = settings.cgCmd; - cgCmdCooldown.value = settings.cgCmdCooldown; - cgMsg.value = settings.cgMsg; - flagsCmd.value = settings.flagsCmd; - flagsCmdMsg.value = settings.flagsCmdMsg; - getUserStatsCmd.value = settings.getUserStatsCmd; - getBestStatsCmd.value = settings.getBestStatsCmd; - clearUserStatsCmd.value = settings.clearUserStatsCmd; - mapCmd.value = settings.mapCmd; - mapCmdCooldown.value = settings.mapCmdCooldown; - randomPlonkCmd.value = settings.randomPlonkCmd; - showHasGuessed.checked = settings.showHasGuessed; - showHasAlreadyGuessed.checked = settings.showHasAlreadyGuessed; - showGuessChanged.checked = settings.showGuessChanged; - showSubmittedPreviousGuess.checked = settings.showSubmittedPreviousGuess; - isMultiGuess.checked = settings.isMultiGuess; - guessMarkersLimit.value = settings.guessMarkersLimit; - - bannedUsersArr = [...bannedUsers]; - let newChilds = []; - bannedUsersArr.map((user) => { - const userBadge = createBadge(user.username); - newChilds.push(userBadge); - }); - bannedUsersList.replaceChildren(...newChilds); - - handleConnectionState(connectionState); - - if (socketStatus) { - socketConnected(); - } else { - socketDisconnected(); - } -}); - -ipcRenderer.on("connection-state", (_event, connectionState) => { - handleConnectionState(connectionState); -}); - -ipcRenderer.on("twitch-error", (_event, error) => { - twitchStatusElement.textContent = error; - twitchStatusElement.style.color = "#ed2453"; -}); - -ipcRenderer.on("socket-connected", () => { - socketConnected(); -}); - -ipcRenderer.on("socket-disconnected", () => { - socketDisconnected(); -}); - -const handleConnectionState = (connectionState) => { - if (connectionState.state == "connected") { - twitchConnected(connectionState.botUsername); - } else { - twitchDisconnected(); - } -}; - -/** - * @param {string} botUsername - */ -const twitchConnected = (botUsername) => { - const linkStr = `chatguessr.com/map/${botUsername}`; - cgLink.value = linkStr; - - copyLinkBtn.addEventListener("click", (e) => { - e.preventDefault(); - navigator.clipboard.writeText(linkStr); - copyLinkBtn.textContent = "Copied"; - setTimeout(() => { - copyLinkBtn.textContent = "Copy"; - }, 1000); - }); - - cgLinkContainer.style.display = "block"; - - const connected = document.createElement("span"); - connected.textContent = "Connected"; - connected.style.color = "#3fe077"; - - twitchReauthEl.textContent = "Change account"; - twitchReauthEl.classList.remove("success"); - twitchReauthEl.classList.add("danger"); - - twitchStatusElement.replaceChildren(connected, document.createTextNode(` as ${botUsername}`)); -}; - -const twitchDisconnected = () => { - cgLinkContainer.style.display = "none"; - - const disconnected = document.createElement("span"); - disconnected.textContent = "Disconnected"; - disconnected.style.color = "#ed2453"; - - twitchReauthEl.textContent = "Log in"; - twitchReauthEl.classList.add("success"); - twitchReauthEl.classList.remove("danger"); - - twitchStatusElement.replaceChildren(disconnected); -}; - -function handleGuessMarkersLimit(e) { - let newValue = parseInt(e.value); - if (!isNaN(newValue)) { - if (newValue < 10) newValue = 10; - if (newValue > 1000) newValue = 1000; - guessMarkersLimit.value = newValue.toString(); - } else { - guessMarkersLimit.value = "100"; - } -} - -function saveGlobalSettings() { - ipcRenderer.send("save-global-settings", { - isMultiGuess: isMultiGuess.checked, - guessMarkersLimit: guessMarkersLimit.valueAsNumber, - cgCmd: cgCmd.value, - cgCmdCooldown: cgCmdCooldown.value, - cgMsg: cgMsg.value, - flagsCmd: flagsCmd.value, - flagsCmdMsg: flagsCmdMsg.value, - getUserStatsCmd: getUserStatsCmd.value, - getBestStatsCmd: getBestStatsCmd.value, - clearUserStatsCmd: clearUserStatsCmd.value, - mapCmd: mapCmd.value, - mapCmdCooldown: mapCmdCooldown.value, - randomPlonkCmd: randomPlonkCmd.value, - showHasGuessed: showHasGuessed.checked, - showHasAlreadyGuessed: showHasAlreadyGuessed.checked, - showGuessChanged: showGuessChanged.checked, - showSubmittedPreviousGuess: showSubmittedPreviousGuess.checked, - }); -} - -function saveTwitchSettings(e) { - e.preventDefault(); - ipcRenderer.send("save-twitch-settings", channelName.value); -} - -const socketConnected = () => { - socketStatusElement.textContent = "Connected"; - socketStatusElement.style.color = "#3fe077"; -}; - -const socketDisconnected = () => { - socketStatusElement.textContent = "Disconnected"; - socketStatusElement.style.color = "#ed2453"; -}; - -function clearStats() { - clearStatsBtn.value = "Are you sure ?"; - clearStatsBtn.setAttribute("onclick", "clearStatsConfirm()"); -} - -function clearStatsConfirm() { - clearStatsBtn.value = "Clear all stats"; - clearStatsBtn.setAttribute("onclick", "clearStats()"); - ipcRenderer.send("clearStats"); -} - -function closeWindow() { - ipcRenderer.send("closeSettings"); -} - -function addUser(e) { - e.preventDefault(); - const input = banUserInput.value.toLowerCase(); - if (input.trim() != "") { - bannedUsersArr.push({ username: input }); - const userBadge = createBadge(input); - bannedUsersList.appendChild(userBadge); - banUserInput.value = ""; - ipcRenderer.send("add-banned-user", input); - } -} - -function removeUser(e) { - const clickedUser = e.target; - const itemId = clickedUser.id; - const index = bannedUsersArr.findIndex((o) => o.username === itemId); - if (index !== -1) { - bannedUsersArr.splice(index, 1); - clickedUser.parentNode.removeChild(clickedUser); - ipcRenderer.send("delete-banned-user", itemId); - } -} - -function createBadge(username) { - const userBadge = document.createElement("div"); - userBadge.className = "badge danger"; - userBadge.textContent = username; - userBadge.id = username; - userBadge.title = "Unban"; - userBadge.addEventListener("click", removeUser); - return userBadge; -} - -function openTab(event, tab) { - for (const el of document.querySelectorAll(".tabcontent")) { - // @ts-ignore TS2339 - el.style.display = "none"; - } - for (const el of document.querySelectorAll(".tablinks")) { - el.classList.remove("active"); - } - document.getElementById(tab).style.display = "block"; - event.currentTarget.classList.add("active"); -} - -// @ts-ignore TS2339 -qs("#defaultOpen").click(); -versionText.append(document.createTextNode(`ChatGuessr version ${version}`)); - -twitchReauthEl.addEventListener("click", () => { - ipcRenderer.invoke("replace-session"); -}); - -function qs(selector, parent = document) { - return parent.querySelector(selector); -} diff --git a/src/auth/AuthWindow.ts b/src/auth/AuthWindow.ts new file mode 100644 index 0000000..c268a33 --- /dev/null +++ b/src/auth/AuthWindow.ts @@ -0,0 +1,51 @@ +import path from 'path' +import { BrowserWindow, shell } from 'electron' + +const isDev = process.env.npm_lifecycle_event === 'dev' + +// Create the Auth window. +export default async function createAuthWindow( + parentWindow: BrowserWindow, + options: { authUrl?: string | null | undefined; clearStorageData: boolean } +) { + const win = new BrowserWindow({ + height: 800, + parent: parentWindow, + show: false, + modal: true, + webPreferences: { + preload: path.join(__dirname, './auth_preload.js'), + devTools: isDev ? true : false, + // Use a separate browser session so we can force log people out of + // Twitch without logging them out of GeoGuessr. + partition: 'persist:backendAuth', + sandbox: false + } + }) + win.setMenuBarVisibility(false) + + win.webContents.setWindowOpenHandler(({ url }) => { + shell.openExternal(url) + return { action: 'deny' } + }) + + win.webContents.on('did-navigate', (_event, url) => { + // If we can go through the auth process without user interaction, we would end up at /streamer/redirect. + // We don't need to show the window at all then. + const isTwitchHeadlessUrl = url.startsWith('https://id.twitch.tv/oauth2/authorize?client_id') + const isSuccessfulRedirectUrl = url.includes('streamer/redirect#access_token') + if (!isTwitchHeadlessUrl && !isSuccessfulRedirectUrl) { + win.show() + } + }) + + if (options.clearStorageData) { + await win.webContents.session.clearStorageData() + } + + win.loadURL(options.authUrl ?? `file://${path.join(__dirname, `../../src/auth/index.html`)}`) + + if (isDev) win.webContents.openDevTools() + + return win +} diff --git a/src/auth/auth_impl.ts b/src/auth/auth_impl.ts new file mode 100644 index 0000000..b00adc3 --- /dev/null +++ b/src/auth/auth_impl.ts @@ -0,0 +1,8 @@ +const startAuth: HTMLButtonElement | null = document.querySelector('#start-auth') +if (startAuth) { + startAuth.addEventListener('click', () => { + startAuth.disabled = true + // @ts-expect-error TS2304: defined by preload script + chatguessrApi.startAuth() + }) +} diff --git a/src/auth/auth_preload.ts b/src/auth/auth_preload.ts new file mode 100644 index 0000000..1a7fa9d --- /dev/null +++ b/src/auth/auth_preload.ts @@ -0,0 +1,22 @@ +import fs from 'fs' +import { join } from 'path' +import { contextBridge, ipcRenderer } from 'electron' +import whenDomReady from 'when-dom-ready' + +const impl = fs.readFileSync(join(__dirname, 'auth_impl.js'), 'utf8') + +whenDomReady().then(() => { + const script = document.createElement('script') + script.type = 'module' + script.innerHTML = impl + document.body.appendChild(script) +}) + +contextBridge.exposeInMainWorld('chatguessrApi', { + startAuth() { + ipcRenderer.invoke('start-auth') + }, + setSession(session: import('@supabase/supabase-js').Session) { + ipcRenderer.send('set-session', session) + } +}) diff --git a/src/auth/index.html b/src/auth/index.html new file mode 100644 index 0000000..6981b80 --- /dev/null +++ b/src/auth/index.html @@ -0,0 +1,21 @@ + + + + + + Twitch Setup + + + +
+
+

+ To use ChatGuessr, you have to log in with Twitch. We recommend logging in using a bot + account or second account, not your main streamer account. +

+ + +
+
+ + diff --git a/src/auth/styles.css b/src/auth/styles.css new file mode 100644 index 0000000..b2f052d --- /dev/null +++ b/src/auth/styles.css @@ -0,0 +1,56 @@ +:root { + --clr-primary: #59ffd8; + --clr-secondary: #a159ff; + --bg-color: #252525; +} + +html { + background: var(--bg-color); + font-family: 'Montserrat', sans-serif; + font-size: 14px; + color: #fff; + letter-spacing: 0.03rem; + -webkit-font-smoothing: antialiased; + font-weight: 300; +} + +.container { + padding: 0.5rem; +} + +.card { + background: rgba(180, 180, 180, 0.1); + border-radius: 5px; + box-shadow: 1px 0px 5px rgb(0, 0, 0, 0.15); + padding: 0.5rem; +} + +.center { + text-align: center; +} +.btn { + font-family: inherit; + border: 0; + border-radius: 5px; + outline: 0; + position: relative; + padding: 10px; + font-weight: 700; + margin: 2px; + color: white; + cursor: pointer; + transition: transform 100ms ease-in-out; + box-shadow: + 0 1px 3px rgb(0 0 0 / 12%), + 0 1px 2px rgb(0 0 0 / 24%); +} +.btn:hover { + transform: translateY(1px); +} +.btn:active { + transform: translateY(2px); +} + +.btn.twitch { + background: var(--clr-secondary); +} diff --git a/src/backend/twitch.js b/src/backend/twitch.js deleted file mode 100644 index aa75dbf..0000000 --- a/src/backend/twitch.js +++ /dev/null @@ -1,85 +0,0 @@ -const { EventEmitter } = require("events"); -const TwitchClient = require("tmi.js").Client; - -class TwitchBackend extends EventEmitter { - /** @type {TwitchClient} */ - #tmi; - - #closing = false; - - /** @type {string} */ - botUsername; - /** @type {string} */ - channelName; - - /** - * @param {object} options - * @param {string} options.botUsername - * @param {string} options.channelName - * @param {string} options.whisperToken - */ - constructor(options) { - super(); - - this.botUsername = options.botUsername; - this.channelName = options.channelName; - - this.#tmi = new TwitchClient({ - options: { debug: true, messagesLogLevel: "info" }, - connection: { - secure: true, - reconnect: false, - }, - identity: { - username: this.botUsername, - password: `oauth:${options.whisperToken}`, - }, - channels: [this.channelName], - }); - - this.#tmi.on("connected", () => { - this.emit("connected"); - }); - - this.#tmi.on("disconnected", () => { - this.emit("disconnected", this.#closing); - }); - - this.#tmi.on("whisper", (_from, userstate, message, self) => { - if (self) return; - this.emit("guess", userstate, message); - }); - - this.#tmi.on("message", (_channel, userstate, message, self) => { - if (self) return; - this.emit("message", userstate, message); - }); - } - - async connect() { - await this.#tmi.connect(); - } - - async close() { - this.#closing = true; - await this.#tmi.disconnect(); - } - - isConnected() { - return this.#tmi.readyState() === "OPEN"; - } - - /** - * @param {string} message - * @param {{ system?: boolean }} [options] - */ - async sendMessage(message, options = {}) { - if (options.system) { - await this.#tmi.action(this.channelName, message); - } else { - await this.#tmi.say(this.channelName, message); - } - } -} - -module.exports = TwitchBackend; diff --git a/src/components/Frame.vue b/src/components/Frame.vue deleted file mode 100644 index 0df1533..0000000 --- a/src/components/Frame.vue +++ /dev/null @@ -1,351 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/components/Timer.vue b/src/components/Timer.vue deleted file mode 100644 index f9987d2..0000000 --- a/src/components/Timer.vue +++ /dev/null @@ -1,693 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/errorReporting.js b/src/errorReporting.js deleted file mode 100644 index b338939..0000000 --- a/src/errorReporting.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -const path = require("path"); -const findUp = require('find-up'); -const Sentry = require('@sentry/electron'); -const dotenv = require('dotenv'); -const { version } = require('../package.json'); -const { accessSync } = require("fs"); - -const envPath = findUp.sync(".env") ?? path.join(__dirname, "../.env"); -try { - accessSync(envPath); - dotenv.config({ path: envPath }); -} catch (error) { - console.error(error); -} - -if (process.env.SENTRY_DSN) { - Sentry.init({ - dsn: process.env.SENTRY_DSN, - release: version, - }); -} \ No newline at end of file diff --git a/src/main.js b/src/main.js deleted file mode 100644 index 9900f14..0000000 --- a/src/main.js +++ /dev/null @@ -1,227 +0,0 @@ -"use strict"; - -require("./errorReporting"); - -if (process.platform == "win32") require("update-electron-app")(); - -const path = require("path"); -const fs = require("fs"); -const { app, BrowserWindow, ipcMain, protocol, dialog } = require("electron"); -const { initRenderer } = require("electron-store"); -const GameHandler = require("./GameHandler").default; -const flags = require("./utils/flags"); -const Database = require("./utils/Database"); -const sharedStore = require("./utils/sharedStore"); -const Settings = require("./utils/Settings"); -const { supabase } = require("./utils/supabase"); -const createAuthWindow = require("./Windows/auth/AuthWindow"); -const axios = require("axios").default; - -if (require("electron-squirrel-startup")) { - app.quit(); -} - -const appDataPath = app.getPath("userData"); -const dbPath = path.join(appDataPath, "scores.db"); -const db = new Database(dbPath); - -function serveAssets() { - const assetDir = path.join(__dirname, "../assets"); - protocol.interceptFileProtocol("asset", (request, callback) => { - const assetFile = path.join(assetDir, new URL(request.url).pathname); - if (!assetFile.startsWith(assetDir)) { - callback({ statusCode: 404, data: "Not Found" }); - } else { - callback({ path: assetFile }); - } - }); -} - -async function serveFlags() { - await flags.load(); - - protocol.interceptFileProtocol("flag", async (request, callback) => { - const name = request.url.replace(/^flag:/, ""); - try { - callback(await flags.findFlagFile(name)); - } catch (err) { - callback({ statusCode: 500, data: err.message }); - } - }); -} - -function createWindow() { - const mainWindow = require("./Windows/MainWindow"); - - mainWindow.once("ready-to-show", () => { - mainWindow.show(); - mainWindow.maximize(); - }); - - return mainWindow; -} - -/** - * Previous versions used a user-generated oauth token that had too many permissions. If we still have one of those, revoke it. - */ -async function revokeLegacyOauthToken() { - const { token } = Settings.read(); - if (!token || !process.env.TWITCH_CLIENT_ID) { - return; - } - - try { - await axios.post( - "https://id.twitch.tv/oauth2/revoke", - new URLSearchParams({ - client_id: process.env.TWITCH_CLIENT_ID, - token: token.replace(/^oauth:/, ""), - }) - ); - } catch { - // We tried (this probably means it was not valid anymore to begin with) - } - - // @ts-expect-error TS2345 Sub-properties are not supported by the types, but do work - sharedStore.delete("settings.token"); -} - -/** - * @param {GameHandler} gameHandler - * @param {BrowserWindow} parentWindow - */ -async function authenticateWithTwitch(gameHandler, parentWindow) { - const hasSession = !!sharedStore.get("session")?.access_token; - - const authConfig = await supabase.auth.signInWithOAuth({ - provider: "twitch", - options: { - redirectTo: new URL("/streamer/redirect", `https://${process.env.CG_PUBLIC_URL}`).href, - scopes: ["chat:read", "chat:edit", "whispers:read"].join(" "), - }, - }); - - // If we have an existing session, we try to go through the login flow without user interaction. - // This way users don't have to sign in manually every time they open ChatGuessr. - const authUrl = hasSession ? authConfig.data?.url : undefined; - - const authWindow = await createAuthWindow(parentWindow, { - authUrl, - clearStorageData: !hasSession, - }); - - const startAuth = () => { - authWindow.loadURL(authConfig.data.url); - }; - - /** - * @param {import("electron").IpcMainEvent} _event - * @param {import("@supabase/supabase-js").Session} session - */ - const setSession = (_event, session) => { - supabase.auth.setSession(session); - gameHandler.authenticate(session).then(revokeLegacyOauthToken); - - authWindow.close(); - }; - - ipcMain.once("set-session", setSession); - ipcMain.handle("start-auth", startAuth); - authWindow.on("closed", () => { - ipcMain.off("set-session", setSession); - ipcMain.removeHandler("start-auth"); - }); -} - -async function init() { - initRenderer(); - - await app.whenReady(); - serveAssets(); - await serveFlags(); - - const mainWindow = createWindow(); - - app.on("activate", () => { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } - }); - - // Quit when all windows are closed, except on macOS. There, it's common - // for applications and their menu bar to stay active until the user quits - // explicitly with Cmd + Q. - app.on("window-all-closed", () => { - // temporary fix for macOS on closed app issue - // if (process.platform !== "darwin") { - app.quit(); - // } - }); - - const gameHandler = new GameHandler(db, mainWindow, { - async requestAuthentication() { - await authenticateWithTwitch(gameHandler, mainWindow); - }, - }); - ipcMain.handle("get-connection-state", () => gameHandler.getConnectionState()); - ipcMain.handle("replace-session", async () => { - await supabase.auth.signOut(); - await authenticateWithTwitch(gameHandler, mainWindow); - }); - - ipcMain.handle("app-data-path-exists", (_event, subdir) => { - let _path = appDataPath; - if (subdir) _path = path.join(appDataPath, subdir); - if (!fs.existsSync(_path)) return false; - return _path; - }); - - ipcMain.handle("import-audio-file", async () => { - return new Promise((resolve, reject) => { - dialog - .showOpenDialog(mainWindow, { - title: "Import audio file", - buttonLabel: "Import audio File", - filters: [{ name: "Audio Files", extensions: ["mp3", "wav", "ogg"] }], - }) - .then((result) => { - if (result.canceled) return resolve(null); - - const filePath = result.filePaths[0]; - if (!filePath) return reject("Error locating path"); - - const targetDirectory = path.join(appDataPath, "timer"); - if (!fs.existsSync(targetDirectory)) { - fs.mkdir(targetDirectory, (err) => { - if (err) return reject(err); - }); - } - - const data = fs.readFileSync(filePath); - // not saving the extension here so we can overwrite audio files having different extensions without extra logic - fs.writeFile(path.join(targetDirectory, "timer_alert"), data, (err) => { - if (err) return reject(err); - - resolve(path.join(targetDirectory, "timer_alert")); - }); - }) - .catch((err) => { - reject(err); - }); - }); - }); - - supabase.auth.onAuthStateChange((event, session) => { - if (event === "SIGNED_IN") { - sharedStore.set("session", session); - } else if (event === "SIGNED_OUT") { - sharedStore.delete("session"); - } - }); - - await authenticateWithTwitch(gameHandler, mainWindow); -} - -init(); diff --git a/src/main/Game.ts b/src/main/Game.ts new file mode 100644 index 0000000..8907189 --- /dev/null +++ b/src/main/Game.ts @@ -0,0 +1,362 @@ +import pMap from 'p-map' + +import { + latLngEqual, + calculateScale, + fetchSeed, + getCountryCode, + haversineDistance, + calculateScore +} from './utils/gameHelper' + +export default class Game { + #db: Database + + /** + * Play link for the current game. + */ + #url: string | undefined + + #settings: Settings + + /** + * The database UUID of the current round. + */ + #roundId: string | undefined + + /** + * Country code for the current round's location. + */ + #country: string | undefined + + seed: Seed | undefined + + mapScale: number | undefined + + location: Location_ | undefined + + lastLocation: LatLng | undefined + + isInGame = false + + guessesOpen = false + + isMultiGuess = false + + constructor(db: Database, settings: Settings) { + this.#db = db + this.#settings = settings + this.lastLocation = this.#db.getLastRoundLocation() + } + + async start(url: string, isMultiGuess: boolean) { + this.isInGame = true + this.isMultiGuess = isMultiGuess + if (this.#url === url) { + await this.refreshSeed() + } else { + this.#url = url + this.seed = await this.#getSeed() + if (!this.seed) { + throw new Error('Could not load seed for this game') + } + + try { + this.#db.createGame(this.seed) + this.#roundId = this.#db.createRound(this.seed.token, this.seed.rounds[0]) + } catch (err) { + // In this case we are restoring an existing game. + if (err instanceof Error && err.message.includes('UNIQUE constraint failed: games.id')) { + this.#roundId = this.#db.getCurrentRound(this.seed.token) + } else { + throw err + } + } + + this.mapScale = calculateScale(this.seed.bounds) + this.#getCountry() + } + } + + outGame() { + this.isInGame = false + this.closeGuesses() + } + + #streamerHasGuessed(seed: Seed) { + return seed.player.guesses.length != this.seed!.player.guesses.length + } + + #locHasChanged(seed: Seed) { + return !latLngEqual(seed.rounds.at(-1)!, this.getLocation()) + } + + // @ts-ignore + async refreshSeed() { + const newSeed = await this.#getSeed() + // If a guess has been committed, process streamer guess then return scores + if (newSeed && this.#streamerHasGuessed(newSeed)) { + this.closeGuesses() + + this.seed = newSeed + const location = this.location + await this.#makeGuess() + + const roundResults = this.getRoundResults() + + if (this.seed!.state !== 'finished') { + this.#roundId = this.#db.createRound(this.seed!.token, this.seed.rounds.at(-1)!) + this.#getCountry() + } else { + this.#roundId = undefined + } + + return { location, roundResults } + // Else, if only the loc has changed, the location was skipped, replace current loc + } else if (newSeed && this.#locHasChanged(newSeed)) { + this.seed = newSeed + this.#roundId = this.#db.createRound(this.seed!.token, this.seed.rounds.at(-1)!) + + this.#getCountry() + + return false + } + } + + async #getSeed() { + return this.#url ? await fetchSeed(this.#url) : undefined + } + + async #getCountry() { + this.location = this.getLocation() + this.#country = await getCountryCode(this.location) + + this.#db.setRoundCountry(this.#roundId!, this.#country ?? null) + } + + async #makeGuess() { + this.seed = await this.#getSeed() + + if (this.isMultiGuess) { + await this.#processMultiGuesses() + } + await this.#processStreamerGuess() + + this.lastLocation = { lat: this.location!.lat, lng: this.location!.lng } + } + + /** + * Update streaks for multi-guesses. + */ + async #processMultiGuesses() { + const guesses = this.#db.getRoundResultsSimplified(this.#roundId!) + await pMap( + guesses, + async (guess) => { + if (guess.country === this.#country) { + this.#db.addUserStreak(guess.player.userId, this.#roundId!) + } else { + this.#db.resetUserStreak(guess.player.userId) + } + }, + { concurrency: 10 } + ) + } + + async #processStreamerGuess() { + const index = this.seed!.state === 'finished' ? 1 : 2 + const streamerGuess = this.seed!.player.guesses[this.seed!.round - index] + const location = { lat: streamerGuess.lat, lng: streamerGuess.lng } + + const dbUser = this.#db.getOrCreateUser( + 'BROADCASTER', + this.#settings.channelName, + this.#settings.avatar, + '#FFF' + ) + if (!dbUser) return + + const guessedCountry = await getCountryCode(location) + const lastStreak = this.#db.getUserStreak(dbUser.id) + const correct = guessedCountry === this.#country + if (correct) { + this.#db.addUserStreak(dbUser.id, this.#roundId!) + } else { + this.#db.resetUserStreak(dbUser.id) + } + + const distance = haversineDistance(location, this.location!) + const score = streamerGuess.timedOut ? 0 : calculateScore(distance, this.mapScale!) + + const streak = this.#db.getUserStreak(dbUser.id) + + this.#db.createGuess(this.#roundId!, dbUser.id, { + location, + country: guessedCountry ?? null, + streak: streak?.count ?? 0, + lastStreak: lastStreak?.count && !correct ? lastStreak.count : null, + distance, + score + }) + } + + async handleUserGuess(userstate: UserData, location: LatLng): Promise { + const dbUser = this.#db.getOrCreateUser( + userstate['user-id'], + userstate['display-name'], + userstate.avatar, + userstate.color + ) + + if (!dbUser) throw Object.assign(new Error('Something went wrong creating dbUser')) + + const existingGuess = this.#db.getUserGuess(this.#roundId!, dbUser.id) + if (existingGuess && !this.isMultiGuess) { + throw Object.assign(new Error('User already guessed'), { code: 'alreadyGuessed' }) + } + + if (dbUser.previousGuess && latLngEqual(dbUser.previousGuess, location)) { + throw Object.assign(new Error('Same guess'), { code: 'submittedPreviousGuess' }) + } + + const distance = haversineDistance(location, this.location!) + const score = calculateScore(distance, this.mapScale!) + + const guessedCountry = await getCountryCode(location) + const correct = guessedCountry === this.#country + const lastStreak = this.#db.getUserStreak(dbUser.id) + + // Reset streak if the player skipped a round + if ( + lastStreak && + this.lastLocation && + !latLngEqual(lastStreak.lastLocation, this.lastLocation) + ) { + this.#db.resetUserStreak(dbUser.id) + } + + if (!this.isMultiGuess) { + if (correct) { + this.#db.addUserStreak(dbUser.id, this.#roundId!) + } else { + this.#db.resetUserStreak(dbUser.id) + } + } + + let streak: { count: number } | undefined = this.#db.getUserStreak(dbUser.id) + + // Here we mimic addUserStreak() without committing for multiGuesses() mode + // This might look weird but with this we no longer need to update guess streak in processMultiGuesses() which was slow + if (this.isMultiGuess) { + if (correct) { + streak ? streak.count++ : (streak = { count: 1 }) + } else { + streak = undefined + } + } + + const guess = { + location, + country: guessedCountry ?? null, + streak: streak?.count ?? 0, + lastStreak: lastStreak?.count && !correct ? lastStreak.count : null, + distance, + score + } + + // Modify guess or push it + let modified = false + if (this.isMultiGuess && existingGuess) { + this.#db.updateGuess(existingGuess.id, guess) + modified = true + } else { + this.#db.createGuess(this.#roundId!, dbUser.id, guess) + } + + // TODO save previous guess? No, fetch previous guess from the DB + this.#db.setUserPreviousGuess(dbUser.id, location) + + return { + player: { + username: dbUser.username, + color: dbUser.color, + avatar: dbUser.avatar, + flag: dbUser.flag + }, + position: location, + streak: streak?.count ?? 0, + lastStreak: lastStreak?.count && !correct ? lastStreak.count : null, + distance, + score, + modified + } + } + + getLocation(): Location_ { + return this.seed!.rounds.at(-1)! + } + + getLocations(): Location_[] { + return this.seed!.rounds.map((round) => ({ + lat: round.lat, + lng: round.lng, + panoId: round.panoId, + heading: Math.round(round.heading), + pitch: Math.round(round.pitch), + zoom: round.zoom + })) + } + + openGuesses() { + this.guessesOpen = true + } + + closeGuesses() { + this.guessesOpen = false + } + + /** + * Get the participants for the current round, sorted by who guessed first. + */ + getRoundParticipants() { + return this.#db.getRoundParticipants(this.#roundId!) + } + + /** + * Get the scores for the current round, sorted by distance from closest to farthest away. + */ + getRoundResults() { + return this.#db.getRoundResults(this.#roundId!) + } + + finishGame() { + return this.#db.finishGame(this.seed!.token) + } + + /** + * Get the combined scores for the current game, sorted from highest to lowest score. + */ + getGameResults() { + return this.#db.getGameResults(this.seed!.token) + } + + get isFinished() { + return this.seed!.state === 'finished' + } + + get mapName() { + return this.seed!.mapName + } + + get mode() { + return { + noMove: this.seed!.forbidMoving, + noPan: this.seed!.forbidRotating, + noZoom: this.seed!.forbidZooming + } + } + + get round() { + return this.seed!.round + } +} diff --git a/src/main/GameHandler.ts b/src/main/GameHandler.ts new file mode 100644 index 0000000..ab4093b --- /dev/null +++ b/src/main/GameHandler.ts @@ -0,0 +1,607 @@ +import { ipcMain } from 'electron' +import { once } from 'events' +import { io } from 'socket.io-client' +import Game from './Game' +import TwitchBackend from './utils/useTwitchJS' +import { settings, saveSettings } from './utils/useSettings' +import { + isGameURL, + makeLink, + fetchMap, + parseCoordinates, + getRandomCoordsInLand, + getStreamerAvatar +} from './utils/gameHelper' +import { getEmoji, randomCountryFlag, selectFlag } from './lib/flags/flags' + +const SOCKET_SERVER_URL = + import.meta.env.VITE_SOCKET_SERVER_URL ?? 'https://chatguessr-server.herokuapp.com' + +export default class GameHandler { + #db: Database + + #win: Electron.BrowserWindow + + #session: Session | undefined + + #backend: TwitchBackend | undefined + + #socket: Socket | undefined + + #game: Game + + #requestAuthentication: () => Promise + + constructor( + db: Database, + win: Electron.BrowserWindow, + options: { requestAuthentication: () => Promise } + ) { + this.#db = db + this.#win = win + this.#backend = undefined + this.#socket = undefined + this.#game = new Game(db, settings) + this.#requestAuthentication = options.requestAuthentication + this.init() + } + + openGuesses() { + this.#game.openGuesses() + this.#win.webContents.send('switch-on') + this.#backend?.sendMessage('Guesses are open...', { system: true }) + } + + closeGuesses() { + this.#game.closeGuesses() + this.#win.webContents.send('switch-off') + this.#backend?.sendMessage('Guesses are closed.', { system: true }) + } + + nextRound() { + if (this.#game.isFinished) { + this.#game.finishGame() + this.#showGameResults() + } else { + this.#win.webContents.send('next-round', this.#game.isMultiGuess, this.#game.getLocation()) + this.#backend?.sendMessage(`🌎 Round ${this.#game.round} has started`, { system: true }) + this.openGuesses() + } + } + + returnToMapPage() { + const mapUrl = this.#game.seed?.map + this.#win.loadURL(`https://www.geoguessr.com/maps/${mapUrl}/play`) + } + + #showRoundResults(location: Location_, roundResults: RoundResult[]) { + const round = this.#game.isFinished ? this.#game.round : this.#game.round - 1 + + this.#win.webContents.send( + 'show-round-results', + round, + location, + roundResults, + settings.guessMarkersLimit + ) + this.#backend?.sendMessage( + `🌎 Round ${round} has finished. Congrats ${getEmoji(roundResults[0].player.flag)} ${ + roundResults[0].player.username + } !`, + { system: true } + ) + } + + async #showGameResults() { + const gameResults = this.#game.getGameResults() + const locations = this.#game.getLocations() + + this.#win.webContents.send('show-game-results', locations, gameResults) + + let link: string | undefined + + try { + link = await makeLink({ + accessToken: this.#session!.access_token, + bot: this.#session!.user.user_metadata.name, + streamer: settings.channelName, + map: this.#game.mapName, + mode: this.#game.mode, + locations, + gameResults + }) + } catch (err) { + console.error('could not upload summary', err) + } + await this.#backend?.sendMessage( + `🌎 Game finished. Congrats ${getEmoji(gameResults[0].player.flag)} ${gameResults[0].player.username} 🏆! ${ + link != undefined ? `Game summary: ${link}` : '' + }`, + { system: true } + ) + } + + init() { + // Browser Listening + this.#win.webContents.on('did-navigate-in-page', (_event, url) => { + if (isGameURL(url)) { + // TODO(reanna) warn about the thing not being connected + if (!this.#backend) return + + this.#game + .start(url, settings.isMultiGuess) + .then(() => { + const restoredGuesses = this.#game.isMultiGuess + ? this.#game.getRoundParticipants() + : this.#game.getRoundResults() + this.#win.webContents.send( + 'game-started', + this.#game.isMultiGuess, + restoredGuesses, + this.#game.getLocation() + ) + + if (restoredGuesses.length > 0) { + this.#backend?.sendMessage(`🌎 Round ${this.#game.round} has resumed`, { + system: true + }) + } else if (this.#game.round === 1) { + this.#backend?.sendMessage(`🌎 A new seed of ${this.#game.mapName} has started`, { + system: true + }) + } else { + this.#backend?.sendMessage(`🌎 Round ${this.#game.round} has started`, { + system: true + }) + } + + this.openGuesses() + }) + .catch((err) => { + console.error(err) + }) + } else { + this.#game.outGame() + this.#win.webContents.send('game-quitted') + } + }) + + this.#win.webContents.on('did-frame-finish-load', () => { + if (!this.#game.isInGame) return + + this.#win.webContents.executeJavaScript(` + window.nextRoundBtn = document.querySelector('[data-qa="close-round-result"]'); + window.playAgainBtn = document.querySelector('[data-qa="play-again-button"]'); + + if (window.nextRoundBtn) { + nextRoundBtn.addEventListener("click", () => { + nextRoundBtn.setAttribute('disabled', 'disabled'); + chatguessrApi.startNextRound(); + }); + } + + if (window.playAgainBtn) { + playAgainBtn.addEventListener("click", () => { + playAgainBtn.setAttribute('disabled', 'disabled'); + chatguessrApi.returnToMapPage(); + }); + } + `) + + if (this.#game.isFinished) return + + this.#win.webContents.send('refreshed-in-game', this.#game.getLocation()) + // Checks and update seed when the this.game has refreshed + // update the current location if it was skipped + // if the streamer has guessed returns scores + this.#game.refreshSeed().then((roundResults) => { + if (roundResults && roundResults.location) { + this.#showRoundResults(roundResults.location, roundResults.roundResults) + } + }) + }) + + ipcMain.on('next-round-click', () => { + this.nextRound() + }) + + ipcMain.on('return-to-map-page', () => { + this.returnToMapPage() + }) + + ipcMain.on('open-guesses', () => { + this.openGuesses() + }) + + ipcMain.on('close-guesses', () => { + if (this.#game.guessesOpen) this.closeGuesses() + }) + + ipcMain.handle('get-settings', () => { + return settings + }) + + ipcMain.on('save-settings', (_event, settings_: Settings) => { + if (settings_.channelName != settings.channelName) { + this.#requestAuthentication() + } + saveSettings(settings_) + }) + + ipcMain.on('reconnect', () => { + this.#requestAuthentication() + }) + + ipcMain.handle('get-banned-users', () => { + return this.#db.getBannedUsers() + }) + + ipcMain.on('add-banned-user', (_event, username: string) => { + this.#db.addBannedUser(username) + }) + + ipcMain.on('delete-banned-user', (_event, username: string) => { + this.#db.deleteBannedUser(username) + }) + + ipcMain.on('clear-stats', async () => { + await this.#db.clear() + await this.#backend?.sendMessage('All stats cleared 🗑️', { system: true }) + }) + } + + getTwitchConnectionState(): TwitchConnectionState { + if (!this.#backend) { + return { state: 'disconnected' } + } else if (this.#backend.isConnected()) { + return { + state: 'connected', + botUsername: this.#backend.botUsername, + channelName: this.#backend.channelName + } + } + return { state: 'connecting' } + } + + getSocketConnectionState(): SocketConnectionState { + if (!this.#socket) { + return { state: 'disconnected' } + } else if (this.#socket.connected) { + return { state: 'connected' } + } + return { state: 'connecting' } + } + + async authenticate(session: Session) { + this.#session = session + await this.#initBackend(session) + await this.#initSocket(session) + } + + async #initBackend(session: Session) { + this.#backend?.close() + this.#backend = undefined + if (!settings.channelName) { + return + } + if (session.user.app_metadata.provider === 'twitch' && session.provider_token) { + this.#backend = new TwitchBackend({ + botUsername: session.user.user_metadata.name, + channelName: settings.channelName, + whisperToken: session.provider_token + }) + } else { + throw new Error('unsupported provider') + } + + const { avatar } = await getStreamerAvatar(settings.channelName) + if (avatar) { + settings.avatar = avatar + } + + const emitConnectionState = () => { + const state = this.getTwitchConnectionState() + this.#win.webContents.send('twitch-connection-state', state) + } + + this.#backend.on('connected', () => { + emitConnectionState() + this.#backend?.sendMessage('is now connected', { system: true }) + }) + this.#backend.on('disconnected', (requestedClose) => { + emitConnectionState() + if (!requestedClose) { + // Try to reconnect. + this.#requestAuthentication() + } + }) + + this.#backend.on('guess', (userstate: UserData, message: string) => { + this.#handleGuess(userstate, message).catch((err) => { + console.error(err) + }) + }) + + this.#backend.on('message', (userstate: UserData, message: string) => { + this.#handleMessage(userstate, message).catch((err) => { + console.error(err) + }) + }) + + emitConnectionState() + try { + await this.#backend.connect() + } catch (err) { + this.#win.webContents.send('twitch-error', err) + console.error('Backend connection error:', err) + } + } + + async #initSocket(session: Session) { + if (this.#socket?.connected) { + this.#socket.disconnect() + } + + const botUsername: string = session.user.user_metadata.name + + this.#socket = io(SOCKET_SERVER_URL, { + transportOptions: { + polling: { + extraHeaders: { + access_token: session.access_token, + channelname: settings.channelName, + bot: botUsername + } + } + } + }) + + this.#socket.on('connect', () => { + this.#socket?.emit('join', botUsername) + this.#win.webContents.send('socket-connected') + }) + + this.#socket.on('disconnect', () => { + this.#win.webContents.send('socket-disconnected') + }) + + this.#socket.on('guess', (userData: UserData, guess: string) => { + this.#handleGuess(userData, guess).catch((err) => { + console.error(err) + }) + }) + + await once(this.#socket, 'connect') + } + + async #handleGuess(userstate: UserData, message: string) { + if (!message.startsWith('!g') || !this.#game.guessesOpen) return + // Ignore guesses made by the broadcaster with the CG map: prevents seemingly duplicate guesses + if (userstate.username?.toLowerCase() === settings.channelName.toLowerCase()) return + // Check if user is banned + if (this.isUserBanned(userstate.username!)) return + + const location = parseCoordinates(message.replace(/^!g\s+/, '')) + if (!location) return + + try { + const guess = await this.#game.handleUserGuess(userstate, location) + + if (!this.#game.isMultiGuess) { + this.#win.webContents.send('render-guess', guess) + if (settings.showHasGuessed) { + await this.#backend?.sendMessage( + `${getEmoji(guess.player.flag)} ${guess.player.username} has guessed` + ) + } + } else { + this.#win.webContents.send('render-multiguess', guess) + + if (!guess.modified) { + if (settings.showHasGuessed) { + await this.#backend?.sendMessage( + `${getEmoji(guess.player.flag)} ${guess.player.username} has guessed` + ) + } + } else { + if (settings.showGuessChanged) { + await this.#backend?.sendMessage( + `${getEmoji(guess.player.flag)} ${guess.player.username} guess changed` + ) + } + } + } + } catch (err: any) { + if (err.code === 'alreadyGuessed') { + if (settings.showHasAlreadyGuessed) { + await this.#backend?.sendMessage(`${userstate['display-name']} you already guessed`) + } + } else if (err.code === 'submittedPreviousGuess') { + if (settings.showSubmittedPreviousGuess) { + await this.#backend?.sendMessage( + `${userstate['display-name']} you submitted your previous guess` + ) + } + } else { + console.error(err) + } + } + } + + #cgCooldown: boolean = false + #mapCooldown: boolean = false + async #handleMessage(userstate: UserData, message: string) { + if (!message.startsWith('!')) return + if (!userstate['user-id'] || !userstate['display-name']) return + + const userId = userstate.badges?.broadcaster === '1' ? 'BROADCASTER' : userstate['user-id'] + message = message.trim().toLowerCase() + + if (message === settings.cgCmd) { + if (this.#cgCooldown && userId !== 'BROADCASTER') return + + await this.#backend?.sendMessage( + settings.cgMsg.replace('', `chatguessr.com/map/${this.#backend?.botUsername}`) + ) + + this.#cgCooldown = true + setTimeout(() => { + this.#cgCooldown = false + }, settings.cgCmdCooldown * 1000) + return + } + + if (message.startsWith('!flag ')) { + const countryReq = message.slice(message.indexOf(' ') + 1).trim() + const dbUser = this.#db.getOrCreateUser( + userId, + userstate['display-name'], + userstate.color, + userstate.avatar + ) + if (!dbUser) return + + let newFlag: string | null | undefined + if (countryReq === 'none') { + newFlag = null + await this.#backend?.sendMessage(`${dbUser.username} flag removed`) + } else if (countryReq === 'random') { + newFlag = randomCountryFlag() + await this.#backend?.sendMessage(`${dbUser.username} got ${getEmoji(newFlag)}`) + } else { + newFlag = selectFlag(countryReq) + if (!newFlag) { + await this.#backend?.sendMessage(`${dbUser.username} no flag found`) + return + } + } + this.#db.setUserFlag(dbUser.id, newFlag) + return + } + + if (message === settings.flagsCmd) { + await this.#backend?.sendMessage('Available flags: chatguessr.com/flags') + return + } + + if (message === settings.mapCmd) { + // We'll only have a map ID if we're + if (!this.#game.isInGame || !this.#game.seed || !this.#game.seed.map) { + return + } + // Allow the broadcaster to circumvent the cooldown + if (this.#mapCooldown && userId !== 'BROADCASTER') return + this.#mapCooldown = true + + const map = await fetchMap(this.#game.seed.map) + if (map) { + await this.#backend?.sendMessage( + `🌎 Now playing '${map.name}' by ${map.creator.nick}, played ${map.numFinishedGames} times with ${map.likes} likes: ${map.description}` + ) + } + + setTimeout(() => { + this.#mapCooldown = false + }, settings.mapCmdCooldown * 1000) + } + + if (message === settings.getUserStatsCmd) { + const userInfo = this.#db.getUserStats(userId) + if (!userInfo) { + await this.#backend?.sendMessage(`${userstate['display-name']} you've never guessed yet.`) + } else { + await this.#backend?.sendMessage(` + ${getEmoji(userInfo.flag)} ${userInfo.username} : Current streak: ${userInfo.streak}. + Best streak: ${userInfo.bestStreak}. + Correct countries: ${userInfo.correctGuesses}/${userInfo.nbGuesses}${ + userInfo.nbGuesses > 0 + ? ` (${((userInfo.correctGuesses / userInfo.nbGuesses) * 100).toFixed(2)}%).` + : '.' + } + Avg. score: ${Math.round(userInfo.meanScore)}. + Victories: ${userInfo.victories}. + 5ks: ${userInfo.perfects}. + `) + } + return + } + + if (message === settings.getBestStatsCmd) { + const { streak, victories, perfects } = this.#db.getGlobalStats() + if (!streak && !victories && !perfects) { + await this.#backend?.sendMessage('No stats available.') + } else { + let msg = '' + if (streak) { + msg += `Streak: ${streak.streak} (${streak.username}). ` + } + if (victories) { + msg += `Victories: ${victories.victories} (${victories.username}). ` + } + if (perfects) { + msg += `5ks: ${perfects.perfects} (${perfects.username}). ` + } + await this.#backend?.sendMessage(`Channels best: ${msg}`) + } + return + } + + if (message === settings.clearUserStatsCmd) { + const dbUser = this.#db.getUser(userId) + if (dbUser) { + this.#db.resetUserStats(dbUser.id) + await this.#backend?.sendMessage( + `${getEmoji(dbUser.flag)} ${dbUser.username} 🗑️ stats cleared !` + ) + } else { + await this.#backend?.sendMessage(`${userstate['display-name']} you've never guessed yet.`) + } + return + } + + if (message === settings.randomPlonkCmd) { + if (!this.#game.isInGame) return + + const { lat, lng } = await getRandomCoordsInLand(this.#game.seed!.bounds) + const randomGuess = `!g ${lat}, ${lng}` + this.#handleGuess(userstate, randomGuess).catch((err) => { + console.error(err) + }) + return + } + + // streamer commands + if (process.env.NODE_ENV !== 'development' || userstate.badges?.broadcaster !== '1') return + + if (message.startsWith('!spamguess')) { + const max = parseInt(message.split(' ')[1] ?? '50', 10) + + let i = 0 + const interval = setInterval(async () => { + const userId = `123450${i}` + // const flag = randomCountryFlag() + // this.#db.setUserFlag(userId, flag) + const { lat, lng } = await getRandomCoordsInLand(this.#game.seed!.bounds) + await this.#handleGuess( + { + 'user-id': userId, + username: `fake_${i}`, + 'display-name': `fake_${i}`, + color: `#${Math.random().toString(16).slice(2, 8).padStart(6, '0')}` + }, + `!g ${lat},${lng}` + ) + i++ + if (i === max) { + clearInterval(interval) + } + }, 200) + } + } + + isUserBanned(username: string) { + const bannedUsers = this.#db.getBannedUsers() + const isBanned = bannedUsers.some((user) => user.username === username) + return isBanned + } +} diff --git a/src/main/MainWindow.ts b/src/main/MainWindow.ts new file mode 100644 index 0000000..71dcbf3 --- /dev/null +++ b/src/main/MainWindow.ts @@ -0,0 +1,48 @@ +import { join } from 'path' +import { BrowserWindow, shell } from 'electron' + +const isDev = process.env.npm_lifecycle_event === 'dev' + +// Create the Main window. +export default function createWindow() { + const win = new BrowserWindow({ + show: false, + ...(process.platform === 'linux' ? { icon: join(__dirname, '../../build/icon.png') } : {}), + webPreferences: { + preload: join(__dirname, './preload.js'), + devTools: isDev ? true : false, + contextIsolation: true, + nodeIntegration: false, + sandbox: false, + // only needed for timer sound alert + webSecurity: false + } + }) + + win.setMenuBarVisibility(false) + win.loadURL('https://www.geoguessr.com/community/maps') + + // Open links in default OS browser + // Allow GeoGuessr socials login to open a new window + win.webContents.setWindowOpenHandler(({ url }) => { + const socialUrls = [ + 'https://www.facebook.com', + 'https://accounts.google.com', + 'https://appleid.apple.com' + ] + if (socialUrls.some((_url) => url.startsWith(_url))) return { action: 'allow' } + + shell.openExternal(url) + return { action: 'deny' } + }) + + win.once('ready-to-show', () => { + win.show() + win.maximize() + if (isDev) win.webContents.openDevTools() + }) + + win.on('close', () => BrowserWindow.getAllWindows().forEach((window) => window.destroy())) + + return win +} diff --git a/src/utils/countryCodes.json b/src/main/lib/countryCodes.json similarity index 99% rename from src/utils/countryCodes.json rename to src/main/lib/countryCodes.json index 8c5ea8f..cbd004d 100644 --- a/src/utils/countryCodes.json +++ b/src/main/lib/countryCodes.json @@ -247,4 +247,4 @@ "ZW": "ZW", "SX": "NL", "CW": "NL" -} \ No newline at end of file +} diff --git a/src/main/lib/countryCodesNames.json b/src/main/lib/countryCodesNames.json new file mode 100644 index 0000000..75d6f23 --- /dev/null +++ b/src/main/lib/countryCodesNames.json @@ -0,0 +1,255 @@ +[ + { "code": "ad", "names": "Andorra" }, + { "code": "ae", "names": "UAE, United Arab Emirates" }, + { "code": "af", "names": "Afghanistan" }, + { "code": "ag", "names": "Antigua and Barbuda" }, + { "code": "ai", "names": "Anguilla" }, + { "code": "aq", "names": "Antarctica" }, + { "code": "al", "names": "Albania" }, + { "code": "am", "names": "Armenia" }, + { "code": "ao", "names": "Angola" }, + { "code": "ar", "names": "Argentina" }, + { "code": "as", "names": "American Samoa" }, + { "code": "at", "names": "Austria" }, + { "code": "au", "names": "Australia" }, + { "code": "aw", "names": "Aruba" }, + { "code": "ax", "names": "Aland Islands" }, + { "code": "az", "names": "Azerbaijan" }, + { "code": "ba", "names": "Bosnia and Herzegovina" }, + { "code": "bb", "names": "Barbados" }, + { "code": "bd", "names": "Bangladesh" }, + { "code": "be", "names": "Belgium" }, + { "code": "bf", "names": "Burkina Faso" }, + { "code": "bg", "names": "Bulgaria" }, + { "code": "bh", "names": "Bahrain" }, + { "code": "bi", "names": "Burundi" }, + { "code": "bj", "names": "Benin" }, + { "code": "bl", "names": "Saint Barthelemy" }, + { "code": "bm", "names": "Bermuda" }, + { "code": "bn", "names": "Brunei" }, + { "code": "bo", "names": "Bolivia" }, + { "code": "br", "names": "Brazil" }, + { "code": "bs", "names": "Bahamas" }, + { "code": "bt", "names": "Bhutan" }, + { "code": "bv", "names": "Bouvet Island" }, + { "code": "bw", "names": "Botswana" }, + { "code": "by", "names": "Belarus" }, + { "code": "bz", "names": "Belize" }, + { "code": "ca", "names": "Canada" }, + { "code": "cc", "names": "Cocos (Keeling) Islands" }, + { "code": "cg", "names": "Congo" }, + { "code": "cd", "names": "Democratic Republic of the Congo" }, + { "code": "cf", "names": "Central African Republic" }, + { "code": "ch", "names": "Switzerland" }, + { "code": "ci", "names": "Cote d'Ivoire, Ivory Coast" }, + { "code": "ck", "names": "Cook Islands" }, + { "code": "cl", "names": "Chile" }, + { "code": "cm", "names": "Cameroon" }, + { "code": "cn", "names": "China" }, + { "code": "co", "names": "Colombia" }, + { "code": "cr", "names": "Costa Rica" }, + { "code": "cu", "names": "Cuba" }, + { "code": "cv", "names": "Cape Verde" }, + { "code": "cw", "names": "Curaçao" }, + { "code": "cx", "names": "Christmas Island" }, + { "code": "cy", "names": "Cyprus" }, + { "code": "cz", "names": "Czech Republic, Czechia" }, + { "code": "de", "names": "Germany" }, + { "code": "dj", "names": "Djibouti" }, + { "code": "dk", "names": "Denmark" }, + { "code": "dm", "names": "Dominica" }, + { "code": "do", "names": "Dominican Republic" }, + { "code": "dz", "names": "Algeria" }, + { "code": "ec", "names": "Ecuador" }, + { "code": "ee", "names": "Estonia" }, + { "code": "eg", "names": "Egypt" }, + { "code": "eh", "names": "Western Sahara" }, + { "code": "er", "names": "Eritrea" }, + { "code": "es", "names": "Spain" }, + { "code": "et", "names": "Ethiopia" }, + { "code": "eu", "names": "Europe" }, + { "code": "fi", "names": "Finland" }, + { "code": "fj", "names": "Fiji" }, + { "code": "fk", "names": "Falkland Islands (Malvinas)" }, + { "code": "fm", "names": "Micronesia" }, + { "code": "fo", "names": "Faroe Islands" }, + { "code": "fr", "names": "France" }, + { "code": "ga", "names": "Gabon" }, + { "code": "gb", "names": "UK, Great Britain, United Kingdom" }, + { "code": "gbeng", "names": "England" }, + { "code": "gbsct", "names": "Scotland" }, + { "code": "gbwls", "names": "Wales" }, + { "code": "gd", "names": "Grenada" }, + { "code": "ge", "names": "Georgia" }, + { "code": "gf", "names": "French Guiana" }, + { "code": "gg", "names": "Guernsey" }, + { "code": "gh", "names": "Ghana" }, + { "code": "gi", "names": "Gibraltar" }, + { "code": "gl", "names": "Greenland" }, + { "code": "gm", "names": "Gambia" }, + { "code": "gn", "names": "Guinea" }, + { "code": "gp", "names": "Guadeloupe" }, + { "code": "gq", "names": "Equatorial Guinea" }, + { "code": "gr", "names": "Greece" }, + { "code": "gs", "names": "South Georgia and the South Sandwich Islands" }, + { "code": "gt", "names": "Guatemala" }, + { "code": "gu", "names": "Guam" }, + { "code": "gw", "names": "Guinea-Bissau" }, + { "code": "gy", "names": "Guyana" }, + { "code": "hk", "names": "Hong Kong" }, + { "code": "hm", "names": "Heard Island and McDonald Islands" }, + { "code": "hn", "names": "Honduras" }, + { "code": "hr", "names": "Croatia" }, + { "code": "ht", "names": "Haiti" }, + { "code": "hu", "names": "Hungary" }, + { "code": "id", "names": "Indonesia" }, + { "code": "ie", "names": "Ireland" }, + { "code": "il", "names": "Israel" }, + { "code": "im", "names": "Isle of Man" }, + { "code": "in", "names": "India" }, + { "code": "io", "names": "British Indian Ocean Territory" }, + { "code": "iq", "names": "Iraq" }, + { "code": "ir", "names": "Iran" }, + { "code": "is", "names": "Iceland" }, + { "code": "it", "names": "Italy" }, + { "code": "je", "names": "Jersey" }, + { "code": "jm", "names": "Jamaica" }, + { "code": "jo", "names": "Jordan" }, + { "code": "jp", "names": "Japan" }, + { "code": "ke", "names": "Kenya" }, + { "code": "kg", "names": "Kyrgyzstan" }, + { "code": "kh", "names": "Cambodia" }, + { "code": "ki", "names": "Kiribati" }, + { "code": "km", "names": "Comoros" }, + { "code": "kn", "names": "Saint Kitts and Nevis" }, + { "code": "kp", "names": "North Korea, DPRK" }, + { "code": "kr", "names": "Korea, South Korea, ROK" }, + { "code": "kw", "names": "Kuwait" }, + { "code": "ky", "names": "Cayman Islands" }, + { "code": "kz", "names": "Kazakhstan" }, + { "code": "la", "names": "Laos" }, + { "code": "lb", "names": "Lebanon" }, + { "code": "lc", "names": "Saint Lucia, St Lucia" }, + { "code": "li", "names": "Liechtenstein" }, + { "code": "lk", "names": "Sri Lanka" }, + { "code": "lr", "names": "Liberia" }, + { "code": "ls", "names": "Lesotho" }, + { "code": "lt", "names": "Lithuania" }, + { "code": "lu", "names": "Luxembourg" }, + { "code": "lv", "names": "Latvia" }, + { "code": "ly", "names": "Libya" }, + { "code": "ma", "names": "Morocco" }, + { "code": "mc", "names": "Monaco" }, + { "code": "md", "names": "Moldova, Moldavia" }, + { "code": "me", "names": "Montenegro" }, + { "code": "mf", "names": "Saint Martin, St Martin" }, + { "code": "mg", "names": "Madagascar" }, + { "code": "mh", "names": "Marshall Islands" }, + { "code": "mk", "names": "North Macedonia" }, + { "code": "ml", "names": "Mali" }, + { "code": "mm", "names": "Myanmar" }, + { "code": "mn", "names": "Mongolia" }, + { "code": "mo", "names": "Macao, Macau" }, + { "code": "mp", "names": "Northern Mariana Islands" }, + { "code": "mq", "names": "Martinique" }, + { "code": "mr", "names": "Mauritania" }, + { "code": "ms", "names": "Montserrat" }, + { "code": "mt", "names": "Malta" }, + { "code": "mu", "names": "Mauritius" }, + { "code": "mv", "names": "Maldives" }, + { "code": "mw", "names": "Malawi" }, + { "code": "mx", "names": "Mexico" }, + { "code": "my", "names": "Malaysia" }, + { "code": "mz", "names": "Mozambique" }, + { "code": "na", "names": "Namibia" }, + { "code": "nc", "names": "New Caledonia" }, + { "code": "ne", "names": "Niger" }, + { "code": "nf", "names": "Norfolk Island" }, + { "code": "ng", "names": "Nigeria" }, + { "code": "ni", "names": "Nicaragua" }, + { "code": "nl", "names": "Netherlands" }, + { "code": "no", "names": "Norway" }, + { "code": "np", "names": "Nepal" }, + { "code": "nr", "names": "Nauru" }, + { "code": "nu", "names": "Niue" }, + { "code": "nz", "names": "New Zealand" }, + { "code": "om", "names": "Oman" }, + { "code": "pa", "names": "Panama" }, + { "code": "pe", "names": "Peru" }, + { "code": "pf", "names": "French Polynesia" }, + { "code": "pg", "names": "Papua New Guinea" }, + { "code": "ph", "names": "Philippines" }, + { "code": "pk", "names": "Pakistan" }, + { "code": "pl", "names": "Poland" }, + { "code": "pm", "names": "Saint Pierre and Miquelon, St Pierre and Miquelon" }, + { "code": "pn", "names": "Pitcairn" }, + { "code": "pr", "names": "Puerto Rico" }, + { "code": "ps", "names": "Palestine" }, + { "code": "pt", "names": "Portugal" }, + { "code": "pw", "names": "Palau" }, + { "code": "py", "names": "Paraguay" }, + { "code": "qa", "names": "Qatar" }, + { "code": "re", "names": "Reunion" }, + { "code": "ro", "names": "Romania" }, + { "code": "rs", "names": "Serbia" }, + { "code": "ru", "names": "Russia" }, + { "code": "rw", "names": "Rwanda" }, + { "code": "sa", "names": "Saudi Arabia" }, + { "code": "sb", "names": "Solomon Islands" }, + { "code": "sc", "names": "Seychelles" }, + { "code": "sd", "names": "Sudan" }, + { "code": "se", "names": "Sweden" }, + { "code": "sg", "names": "Singapore" }, + { "code": "sh", "names": "Saint Helena, Ascension and Tristan da Cunha" }, + { "code": "si", "names": "Slovenia" }, + { "code": "sj", "names": "Svalbard" }, + { "code": "sk", "names": "Slovakia" }, + { "code": "sl", "names": "Sierra Leone" }, + { "code": "sm", "names": "San Marino" }, + { "code": "sn", "names": "Senegal" }, + { "code": "so", "names": "Somalia" }, + { "code": "sr", "names": "Suriname" }, + { "code": "ss", "names": "South Sudan" }, + { "code": "st", "names": "Sao Tome and Principe" }, + { "code": "sv", "names": "El Salvador" }, + { "code": "sx", "names": "Sint Maarten" }, + { "code": "sy", "names": "Syria" }, + { "code": "sz", "names": "Swaziland, eSwatini" }, + { "code": "tb", "names": "Tibet" }, + { "code": "tc", "names": "Turks and Caicos Islands" }, + { "code": "td", "names": "Chad" }, + { "code": "tf", "names": "French Southern Territories" }, + { "code": "tg", "names": "Togo" }, + { "code": "th", "names": "Thailand" }, + { "code": "tj", "names": "Tajikistan" }, + { "code": "tk", "names": "Tokelau" }, + { "code": "tl", "names": "Timor-Leste" }, + { "code": "tm", "names": "Turkmenistan" }, + { "code": "tn", "names": "Tunisia" }, + { "code": "to", "names": "Tonga" }, + { "code": "tr", "names": "Turkey" }, + { "code": "tt", "names": "Trinidad and Tobago" }, + { "code": "tv", "names": "Tuvalu" }, + { "code": "tw", "names": "Taiwan" }, + { "code": "tz", "names": "Tanzania" }, + { "code": "ua", "names": "Ukraine" }, + { "code": "ug", "names": "Uganda" }, + { "code": "us", "names": "US, USA, United States" }, + { "code": "uy", "names": "Uruguay" }, + { "code": "uz", "names": "Uzbekistan" }, + { "code": "va", "names": "Vatican, Vatican City, Holy See" }, + { "code": "vc", "names": "Saint Vincent and the Grenadines" }, + { "code": "ve", "names": "Venezuela" }, + { "code": "vg", "names": "British Virgin Islands" }, + { "code": "vi", "names": "US Virgin Islands" }, + { "code": "vn", "names": "Viet Nam, Vietnam" }, + { "code": "vu", "names": "Vanuatu" }, + { "code": "wf", "names": "Wallis and Futuna" }, + { "code": "ws", "names": "Samoa" }, + { "code": "ye", "names": "Yemen" }, + { "code": "yt", "names": "Mayotte" }, + { "code": "za", "names": "South Africa" }, + { "code": "zm", "names": "Zambia" }, + { "code": "zw", "names": "Zimbabwe" }, + { "code": "xk", "names": "Kosovo" } +] diff --git a/src/main/lib/flags/builtinFlags.json b/src/main/lib/flags/builtinFlags.json new file mode 100644 index 0000000..38097ad --- /dev/null +++ b/src/main/lib/flags/builtinFlags.json @@ -0,0 +1,76 @@ +[ + { "code": "auaboriginal", "names": "Aboriginal", "emoji": "🇦🇺 (Aboriginal)" }, + { "code": "black", "names": "Black", "emoji": "\uD83C\uDFF4" }, + { "code": "caqc", "names": "Quebec", "emoji": "🇨🇦 (QC)" }, + { + "code": "checkered", + "names": "Checkered flag, Chequered flag, Racing flag", + "emoji": "\uD83C\uDFC1" + }, + { "code": "esct", "names": "Catalonia, Catalunya, catalunia", "emoji": "🇪🇸 (CT)" }, + { "code": "esga", "names": "Galicia", "emoji": "🇪🇸 (GA)" }, + { "code": "espv", "names": "Basque Country, euskadi, Pais Vasco", "emoji": "🇪🇸 (PV)" }, + { "code": "frbre", "names": "Brittany, BZH, Bretagne", "emoji": "🇫🇷 (BRE)" }, + { "code": "frcor", "names": "Corsica, Corse", "emoji": "🇫🇷 (COR)" }, + { "code": "itsrd", "names": "Sardinia, Sardegna", "emoji": "🇮🇹 (Sardegna)" }, + { "code": "lgbt", "names": "Rainbow, Pride", "emoji": "\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08" }, + { "code": "nzmaori", "names": "Maori", "emoji": "🇳🇿 (Māori)" }, + { "code": "mypg", "names": "Penang", "emoji": "🇲🇾 (Penang)" }, + { "code": "mysb", "names": "Sabah", "emoji": "🇲🇾 (Sabah)" }, + { "code": "myswk", "names": "Sarawak", "emoji": "🇲🇾 (Sarawak)" }, + { "code": "pirate", "names": "Pirate, Jolly Roger", "emoji": "\uD83C\uDFF4\u200D\u2620\uFE0F" }, + { "code": "ussr", "names": "USSR, Soviet union", "emoji": "☭" }, + { "code": "trans", "names": "Transgender", "emoji": "\uD83C\uDFF3\uFE0F\u200D\u26A7\uFE0F" }, + { "code": "usak", "names": "Alaska", "emoji": "🇺🇸 (AK)" }, + { "code": "usal", "names": "Alabama", "emoji": "🇺🇸 (AL)" }, + { "code": "usar", "names": "Arkansas", "emoji": "🇺🇸 (AR)" }, + { "code": "usaz", "names": "Arizona", "emoji": "🇺🇸 (AZ)" }, + { "code": "usca", "names": "California", "emoji": "🇺🇸 (CA)" }, + { "code": "usco", "names": "Colorado", "emoji": "🇺🇸 (CO)" }, + { "code": "usct", "names": "Connecticut", "emoji": "🇺🇸 (CT)" }, + { "code": "usde", "names": "Delaware", "emoji": "🇺🇸 (DE)" }, + { "code": "usfl", "names": "Florida", "emoji": "🇺🇸 (FL)" }, + { "code": "usga", "names": "Georgia state", "emoji": "🇺🇸 (GA)" }, + { "code": "ushi", "names": "Hawaii", "emoji": "🇺🇸 (HI)" }, + { "code": "usia", "names": "Iowa", "emoji": "🇺🇸 (IA)" }, + { "code": "usid", "names": "Idaho", "emoji": "🇺🇸 (ID)" }, + { "code": "usil", "names": "Illinois", "emoji": "🇺🇸 (IL)" }, + { "code": "usin", "names": "Indiana", "emoji": "🇺🇸 (IN)" }, + { "code": "usks", "names": "Kansas", "emoji": "🇺🇸 (KS)" }, + { "code": "usky", "names": "Kentucky", "emoji": "🇺🇸 (KY)" }, + { "code": "usla", "names": "Louisiana", "emoji": "🇺🇸 (LA)" }, + { "code": "usma", "names": "Massachusetts", "emoji": "🇺🇸 (MA)" }, + { "code": "usmd", "names": "Maryland", "emoji": "🇺🇸 (MD)" }, + { "code": "usme", "names": "Maine", "emoji": "🇺🇸 (ME)" }, + { "code": "usmi", "names": "Michigan", "emoji": "🇺🇸 (MI)" }, + { "code": "usmn", "names": "Minnesota", "emoji": "🇺🇸 (MN)" }, + { "code": "usmo", "names": "Missouri", "emoji": "🇺🇸 (MO)" }, + { "code": "usms", "names": "Mississippi", "emoji": "🇺🇸 (MS)" }, + { "code": "usmt", "names": "Montana", "emoji": "🇺🇸 (MT)" }, + { "code": "usnc", "names": "North Carolina", "emoji": "🇺🇸 (NC)" }, + { "code": "usnd", "names": "North Dakota", "emoji": "🇺🇸 (ND)" }, + { "code": "usne", "names": "Nebraska", "emoji": "🇺🇸 (NE)" }, + { "code": "usnh", "names": "New Hampshire", "emoji": "🇺🇸 (NH)" }, + { "code": "usnj", "names": "New Jersey", "emoji": "🇺🇸 (NJ)" }, + { "code": "usnm", "names": "New Mexico", "emoji": "🇺🇸 (NM)" }, + { "code": "usnv", "names": "Nevada", "emoji": "🇺🇸 (NV)" }, + { "code": "usny", "names": "New York", "emoji": "🇺🇸(NY)" }, + { "code": "usoh", "names": "Ohio", "emoji": "🇺🇸 (OH)" }, + { "code": "usok", "names": "Oklahoma", "emoji": "🇺🇸 (OK)" }, + { "code": "usor", "names": "Oregon", "emoji": "🇺🇸 (OR)" }, + { "code": "uspa", "names": "Pennsylvania", "emoji": "🇺🇸 (PA)" }, + { "code": "usri", "names": "Rhode Island", "emoji": "🇺🇸 (RI)" }, + { "code": "ussc", "names": "South Carolina", "emoji": "🇺🇸 (SC)" }, + { "code": "ussd", "names": "South Dakota", "emoji": "🇺🇸 (SD)" }, + { "code": "ustn", "names": "Tennessee", "emoji": "🇺🇸 (TN)" }, + { "code": "ustx", "names": "Texas", "emoji": "🇺🇸 (TX)" }, + { "code": "usut", "names": "Utah", "emoji": "🇺🇸 (UT)" }, + { "code": "usva", "names": "Virginia", "emoji": "🇺🇸 (VA)" }, + { "code": "usvt", "names": "Vermont", "emoji": "🇺🇸 (VT)" }, + { "code": "uswa", "names": "Washington", "emoji": "🇺🇸 (WA)" }, + { "code": "uswi", "names": "Wisconsin", "emoji": "🇺🇸 (WI)" }, + { "code": "uswv", "names": "West Virginia", "emoji": "🇺🇸 (WV)" }, + { "code": "uswy", "names": "Wyoming", "emoji": "🇺🇸 (WY)" }, + { "code": "white", "names": "Surrender, White", "emoji": "\uD83C\uDFF3\uFE0F" }, + { "code": "yu", "names": "Yugoslavia", "emoji": "🇾🇺" } +] diff --git a/src/main/lib/flags/flags.ts b/src/main/lib/flags/flags.ts new file mode 100644 index 0000000..47bbc41 --- /dev/null +++ b/src/main/lib/flags/flags.ts @@ -0,0 +1,114 @@ +import path from 'path' +import fs from 'fs/promises' +import { app } from 'electron' +import { matchSorter } from 'match-sorter' + +import builtinFlags from './builtinFlags.json' +import countryCodesNames from '../countryCodesNames.json' + +// The fallback to `/tmp/` is so this module can be used in tests outside electron. +const appDataDir = app?.getPath('userData') ?? '/tmp/' +const customFlagsDir = path.join(appDataDir, 'flags') + +/** + * Country flags included in Chatguessr by default. + */ +const countryFlags: Flag[] = countryCodesNames.map(({ code, names }) => ({ + code, + names, + emoji: getCountryEmoji(code) +})) + +/** + * Custom flags configured by the streamer. + */ +let customFlags: Flag[] = [] + +/** Get all available flags: custom flags, country flags, builtin flags. */ +export function getAvailableFlags() { + return [...customFlags, ...countryFlags, ...builtinFlags] +} + +export async function loadCustomFlags() { + try { + customFlags = JSON.parse( + await fs.readFile(path.join(customFlagsDir, 'customFlags.json'), 'utf8') + ) + } catch { + // it's OK if it doesn't exist + } +} + +export function setCustomFlags(flags: Flag[]) { + customFlags = flags +} + +export async function findFlagFile(id: string): Promise { + const customFlagPaths = [path.join(customFlagsDir, `${id}.svg`)] + + for (const customFlagPath of customFlagPaths) { + try { + await fs.access(customFlagPath) + return { path: customFlagPath } + } catch { + // Flag file doesn't exist. Try the next, or fall back to builtin flags. + } + } + + // We always return a path to the builtin SVGs because it's easy. + // electron will return a 404 for us if the file doesn't exist. + return { path: path.join(__dirname, `./assets/flags/${id.toUpperCase()}.svg`) } +} + +/** + * Find a flag code based on user input. + */ +export function selectFlag(input: string): string | undefined { + const availableFlags = getAvailableFlags() + + const matches = matchSorter(availableFlags, input, { + keys: ['names', { threshold: matchSorter.rankings.EQUAL, key: 'code' }] + }) + + return matches[0]?.code +} + +/** + * Select a random country code. + */ +export function randomCountryFlag(): string { + return countryCodesNames[Math.floor(Math.random() * countryCodesNames.length)].code +} + +/** + * Convert a country code to a flag emoji. + */ +export function getCountryEmoji(value: string) { + if (value.length == 2) { + return value + .toUpperCase() + .replace(/./g, (char) => String.fromCodePoint(char.charCodeAt(0) + 127397)) + } else { + const flag = value + .toUpperCase() + .substring(0, 2) + .replace(/./g, (char) => String.fromCodePoint(char.charCodeAt(0) + 127397)) + const region = value + .toUpperCase() + .substring(2) + .replace(/./g, (char) => String.fromCodePoint(char.charCodeAt(0) + 127397) + ' ') + return `${flag} ${region}`.trim() + } +} + +/** + * Convert a user flag to an emoji or text value. + * Country codes get a flag emoji, and custom flags either get their configured emoji, or the empty string. + */ +export function getEmoji(value: string | null) { + if (!value) return '' + + const flag = getAvailableFlags().find((flag) => flag.code === value.toLowerCase()) + + return flag?.emoji ?? '' +} diff --git a/src/main/main.ts b/src/main/main.ts new file mode 100644 index 0000000..50f9e2b --- /dev/null +++ b/src/main/main.ts @@ -0,0 +1,187 @@ +import fs from 'fs' +import { join } from 'path' +import { app, BrowserWindow, ipcMain, protocol, dialog } from 'electron' +import { updateElectronApp } from 'update-electron-app' + +import createMainWindow from './MainWindow' +import createAuthWindow from '../auth/AuthWindow' +import GameHandler from './GameHandler' +import { database } from './utils/Database' +import { supabase } from './utils/useSupabase' +import { store } from './utils/store' +import { loadCustomFlags, findFlagFile } from './lib/flags/flags' +import { version } from '../../package.json' + +if (process.platform == 'win32') updateElectronApp() + +const appDataPath = app.getPath('userData') +const dbPath = join(appDataPath, 'scores.db') +const db = database(dbPath) + +// This method will be called when Electron has finished initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.whenReady().then(async () => { + serveAssets() + await serveFlags() + + const mainWindow = createMainWindow() + + const gameHandler = new GameHandler(db, mainWindow, { + async requestAuthentication() { + await authenticateWithTwitch(gameHandler, mainWindow) + } + }) + + ipcMain.handle('get-twitch-connection-state', () => gameHandler.getTwitchConnectionState()) + ipcMain.handle('get-socket-connection-state', () => gameHandler.getSocketConnectionState()) + ipcMain.handle('replace-session', async () => { + await supabase.auth.signOut() + await authenticateWithTwitch(gameHandler, mainWindow) + }) + + ipcMain.handle('app-data-path-exists', (_event, subdir) => { + let _path = appDataPath + if (subdir) _path = join(appDataPath, subdir) + if (!fs.existsSync(_path)) return false + return _path + }) + + ipcMain.handle('import-audio-file', async () => { + return new Promise((resolve, reject) => { + dialog + .showOpenDialog(mainWindow, { + title: 'Import audio file', + buttonLabel: 'Import audio File', + filters: [{ name: 'Audio Files', extensions: ['mp3', 'wav', 'ogg'] }] + }) + .then((result) => { + if (result.canceled) return resolve(null) + + const filePath = result.filePaths[0] + if (!filePath) return reject('Error locating path') + + const targetDirectory = join(appDataPath, 'timer') + if (!fs.existsSync(targetDirectory)) { + fs.mkdir(targetDirectory, (err) => { + if (err) return reject(err) + }) + } + + const data = fs.readFileSync(filePath) + // not saving the extension here so we can overwrite audio files having different extensions without extra logic + fs.writeFile(join(targetDirectory, 'timer_alert'), data, (err) => { + if (err) return reject(err) + + resolve(join(targetDirectory, 'timer_alert')) + }) + }) + .catch((err) => { + reject(err) + }) + }) + }) + + ipcMain.handle('get-current-version', () => version) + + supabase.auth.onAuthStateChange((event, session) => { + if (event === 'SIGNED_IN') { + store.set('session', session) + } else if (event === 'SIGNED_OUT') { + store.delete('session') + } + }) + + await authenticateWithTwitch(gameHandler, mainWindow) +}) + +async function authenticateWithTwitch(gameHandler: GameHandler, parentWindow: BrowserWindow) { + const hasSession = !!store.get('session')?.access_token + + const authConfig = await supabase.auth.signInWithOAuth({ + provider: 'twitch', + options: { + redirectTo: new URL('/streamer/redirect', `https://${import.meta.env.VITE_CG_PUBLIC_URL}`) + .href, + scopes: ['chat:read', 'chat:edit', 'whispers:read'].join(' ') + } + }) + + // If we have an existing session, we try to go through the login flow without user interaction. + // This way users don't have to sign in manually every time they open ChatGuessr. + const authUrl = hasSession ? authConfig.data.url : undefined + + const authWindow = await createAuthWindow(parentWindow, { + authUrl, + clearStorageData: !hasSession + }) + + const startAuth = () => { + supabase.auth.signOut().finally(() => { + // @ts-expect-error + authWindow.loadURL(authConfig.data.url) + }) + } + + const setSession = (_event: Electron.IpcMainEvent, session: Session) => { + supabase.auth.setSession(session) + gameHandler.authenticate(session) + + authWindow.close() + } + + ipcMain.once('set-session', setSession) + ipcMain.handle('start-auth', startAuth) + authWindow.on('closed', () => { + ipcMain.off('set-session', setSession) + ipcMain.removeHandler('start-auth') + }) +} + +// Quit when all windows are closed, except on macOS. There, it's common +// for applications and their menu bar to stay active until the user quits +// explicitly with Cmd + Q. +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) + +app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows o + if (BrowserWindow.getAllWindows().length === 0) { + createMainWindow() + } +}) + +// Handle creating/removing shortcuts on Windows when installing/uninstalling. +if (require('electron-squirrel-startup')) { + app.quit() +} + +// Serve assets to 'asset:' file protocol +// Assets must be placed in the public folder +function serveAssets() { + const assetDir = join(__dirname, './assets') + protocol.interceptFileProtocol('asset', (request, callback) => { + const assetFile = join(assetDir, new URL(request.url).pathname) + if (!assetFile.startsWith(assetDir)) { + callback({ statusCode: 404, data: 'Not Found' }) + } else { + callback({ path: assetFile }) + } + }) +} + +async function serveFlags() { + await loadCustomFlags() + + protocol.interceptFileProtocol('flag', async (request, callback) => { + const name = request.url.replace(/^flag:/, '') + try { + callback(await findFlagFile(name)) + } catch (err: any) { + callback({ statusCode: 500, data: err.message }) + } + }) +} diff --git a/src/main/utils/Database.test.ts b/src/main/utils/Database.test.ts new file mode 100644 index 0000000..579cefc --- /dev/null +++ b/src/main/utils/Database.test.ts @@ -0,0 +1,213 @@ +import { beforeEach, describe, it, expect } from 'vitest' +import { randomUUID } from 'node:crypto' +import { database } from './Database' + +let db: Database + +beforeEach(() => { + db = database(':memory:') +}) + +function createGame() { + const token = randomUUID() + db.createGame({ + token, + map: 'test', + mapName: 'test', + bounds: { + min: { lat: 0, lng: 0 }, + max: { lat: 0, lng: 0 } + }, + forbidMoving: true, + forbidRotating: false, + forbidZooming: false, + timeLimit: 0 + } as Seed) + return token +} + +describe('getUserStats', () => { + it('counts victories', () => { + const user = db.getOrCreateUser('1234567', 'libreanna', undefined, undefined) + const token = createGame() + const createGuess = () => { + const roundId = db.createRound(token, { + lat: 0, + lng: 0, + panoId: null, + heading: 0, + pitch: 0, + zoom: 0 + }) + db.createGuess(roundId, user!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 0, + score: 5000 + }) + } + + for (let i = 0; i < 5; i += 1) { + createGuess() + } + + // Now on round 5: this should not yet be counted as a victory + expect(db.getUserStats(user!.id)!.victories).toEqual(0) + + db.finishGame(token) + + // Only once the game is finished, it counts. + expect(db.getUserStats(user!.id)!.victories).toEqual(1) + }) +}) + +describe('getRoundResults', () => { + it('sorts by score and distance', () => { + const user = db.getOrCreateUser('1234567', 'libreanna', undefined, undefined) + const user2 = db.getOrCreateUser('1234568', 'zehef_', undefined, undefined) + const user3 = db.getOrCreateUser('1234569', 'mramericanmike', undefined, undefined) + const token = createGame() + + const roundId = db.createRound(token, { + lat: 0, + lng: 0, + panoId: null, + heading: 0, + pitch: 0, + zoom: 0 + }) + + db.createGuess(roundId, user2!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 1234, + score: 3000 + }) + db.createGuess(roundId, user!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 1000, + score: 3600 + }) + db.createGuess(roundId, user3!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 998, + score: 3600 + }) + + const leaderboard = db.getRoundResults(roundId).map((score) => score.player.username) + expect(leaderboard).toEqual(['mramericanmike', 'libreanna', 'zehef_']) + }) + + it('sorts 5Ks by time', async () => { + const user = db.getOrCreateUser('1234567', 'libreanna', undefined, undefined) + const user2 = db.getOrCreateUser('1234568', 'zehef_', undefined, undefined) + const user3 = db.getOrCreateUser('1234569', 'mramericanmike', undefined, undefined) + const token = createGame() + + const roundId = db.createRound(token, { + lat: 0, + lng: 0, + panoId: null, + heading: 0, + pitch: 0, + zoom: 0 + }) + + db.createGuess(roundId, user!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 12, + score: 5000 + }) + db.createGuess(roundId, user3!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 998, + score: 4800 + }) + const second5k = db.createGuess(roundId, user2!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 8, + score: 5000 + }) + + // `second5k` was closer, but 20 seconds later, + // so it should show up *after* the first 5K. + // TODO maybe we can use jest simulated timers for this + db[Symbol.for('chatguessr-test-run-query')]( + 'UPDATE guesses SET created_at = created_at + 20 WHERE id = :id', + { id: second5k } + ) + + const leaderboard = db.getRoundResults(roundId).map((score) => score.player.username) + expect(leaderboard).toEqual(['libreanna', 'zehef_', 'mramericanmike']) + }) + + it('sorts by time in multi-guess', async () => { + const user = db.getOrCreateUser('1234567', 'libreanna', undefined, undefined) + const user2 = db.getOrCreateUser('1234568', 'zehef_', undefined, undefined) + const token = createGame() + + const roundId = db.createRound(token, { + lat: 0, + lng: 0, + panoId: null, + heading: 0, + pitch: 0, + zoom: 0 + }) + + const non5k = db.createGuess(roundId, user!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 988, + score: 4924 + }) + // adjust `non5k` to be significantly earlier than user2's 5K, + // so it is earlier but worse by not being a 5K. Then we can check that after + // updating the guess, the time is also updated. + db[Symbol.for('chatguessr-test-run-query')]( + 'UPDATE guesses SET created_at = created_at - 20 WHERE id = :id', + { id: non5k } + ) + + db.createGuess(roundId, user2!.id, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 8, + score: 5000 + }) + db.updateGuess(non5k, { + location: { lat: 0, lng: 0 }, + country: null, + streak: 0, + lastStreak: null, + distance: 12, + score: 5000 + }) + + const leaderboard = db.getRoundResults(roundId).map((score) => score.player.username) + expect(leaderboard).toEqual(['zehef_', 'libreanna']) + }) +}) diff --git a/src/main/utils/Database.ts b/src/main/utils/Database.ts new file mode 100644 index 0000000..52a624e --- /dev/null +++ b/src/main/utils/Database.ts @@ -0,0 +1,928 @@ +import SQLite from 'better-sqlite3' +import { randomUUID } from 'crypto' + +function timestamp() { + return Math.floor(Date.now() / 1000) +} + +// NEVER modify existing migrations, ONLY add new ones. +const migrations: ((db: SQLite.Database) => void)[] = [ + function initialSetup(db) { + const usersTable = db.prepare(`CREATE TABLE users ( + -- Twitch user ID + id TEXT PRIMARY KEY NOT NULL, + -- Twitch display name + username TEXT NOT NULL, + flag TEXT DEFAULT NULL, + previous_guess TEXT DEFAULT NULL, + last_location TEXT DEFAULT NULL, + reset_at INT DEFAULT 0 + )`) + + const gamesTable = db.prepare(`CREATE TABLE games ( + -- GeoGuessr game token + id TEXT PRIMARY KEY NOT NULL, + map TEXT NOT NULL, + map_name TEXT NOT NULL, + -- JSON bounds: {min: LatLng, max: LatLng} + -- for the scoring formula + map_bounds TEXT NOT NULL, + -- boolean 0 or 1 + forbid_moving INT NOT NULL, + -- boolean 0 or 1 + forbid_panning INT NOT NULL, + -- boolean 0 or 1 + forbid_zooming INT NOT NULL, + -- in seconds + time_limit INT DEFAULT NULL, + created_at INT NOT NULL + )`) + + const roundsTable = db.prepare(`CREATE TABLE rounds ( + -- UUID + id TEXT PRIMARY KEY NOT NULL, + game_id TEXT NOT NULL, + -- JSON coordinates {lat,lng,heading,pitch} + location TEXT NOT NULL, + -- Country code of the location + country TEXT DEFAULT NULL, + created_at INT NOT NULL, + + FOREIGN KEY(game_id) REFERENCES games(id) + )`) + + const guessesTable = db.prepare(`CREATE TABLE guesses ( + -- UUID + id TEXT PRIMARY KEY NOT NULL, + user_id TEXT NOT NULL, + round_id TEXT NOT NULL, + -- User color at the time the guess was made. + color TEXT DEFAULT NULL, + -- User flag at the time the guess was made. + flag TEXT DEFAULT NULL, + -- JSON coordinates {lat,lng} + location TEXT NOT NULL, + -- Country code where the guess was placed + country TEXT DEFAULT NULL, + streak INT DEFAULT 0, + -- Distance (in metres?), slightly inaccurate + distance INT NOT NULL, + score INT NOT NULL, + created_at INT NOT NULL, + + FOREIGN KEY(user_id) REFERENCES users(id), + FOREIGN KEY(round_id) REFERENCES rounds(id) + )`) + + usersTable.run() + gamesTable.run() + roundsTable.run() + guessesTable.run() + + // These are all deriveable … maybe add them later if it is useful + /* + ALTER TABLE users ADD COLUMN streak INT DEFAULT 0; + ALTER TABLE users ADD COLUMN best_streak INT DEFAULT 0; + ALTER TABLE users ADD COLUMN correct_guesses INT DEFAULT 0; + ALTER TABLE users ADD COLUMN nb_guesses INT DEFAULT 0; + ALTER TABLE users ADD COLUMN perfects INT DEFAULT 0; + ALTER TABLE users ADD COLUMN victories INT DEFAULT 0; + */ + }, + function createSearchIndices(db) { + db.prepare(`CREATE INDEX guess_user_id ON guesses(user_id)`).run() + db.prepare(`CREATE INDEX guess_round_id ON guesses(round_id)`).run() + db.prepare(`CREATE INDEX round_game_id ON rounds(game_id)`).run() + }, + function createStreaks(db) { + db.prepare( + `CREATE TABLE streaks ( + id TEXT PRIMARY KEY NOT NULL, + user_id TEXT NOT NULL, + last_round_id TEXT NOT NULL, + count INT NOT NULL DEFAULT 1, + created_at INT NOT NULL, + updated_at INT NOT NULL, + + FOREIGN KEY(user_id) REFERENCES users(id), + FOREIGN KEY(last_round_id) REFERENCES rounds(id) + )` + ).run() + + db.prepare(`ALTER TABLE users ADD COLUMN current_streak_id TEXT DEFAULT NULL`).run() + }, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function createGameWinnersObsolete(_db) { + // This used to create a game_winners view, but that was obsoleted by the next migration. + // For new users who didn't run this migration yet we can keep it a noop. + // This empty function needs to remain so the `user_version` value in SQLite stays correct. + }, + function addGameStateColumn(db) { + db.prepare(`ALTER TABLE games ADD COLUMN state TEXT DEFAULT 'started'`).run() + db.prepare(`CREATE INDEX games_state ON games(state)`).run() + + // Mark all existing games with at least 5 rounds as finished. + db.prepare( + ` + UPDATE games SET state = 'finished' WHERE id IN ( + SELECT games.id + FROM games, rounds + WHERE rounds.game_id = games.id + GROUP BY games.id + HAVING COUNT(rounds.id) >= 5 + ) + ` + ).run() + }, + function createGameWinners(db) { + db.prepare(`DROP VIEW IF EXISTS game_winners`).run() + // this query is based on https://stackoverflow.com/a/7745635/591962 + // It could be possible to use windowing functions on the game_scores query too, + // partitioning by game_id and then selecting only those where rank() = 1 to filter top scores. + db.prepare( + ` + CREATE VIEW game_winners (id, user_id, score, created_at) AS + -- Prepare all users' total scores in each game + WITH game_scores AS ( + SELECT guesses.user_id, games.id AS game_id, SUM(guesses.score) AS score, MAX(guesses.created_at) AS guessed_at + FROM games + LEFT JOIN rounds ON rounds.game_id = games.id + LEFT JOIN guesses ON guesses.round_id = rounds.id + WHERE games.state = 'finished' + GROUP BY guesses.user_id, games.id + ) + SELECT games.id, top_scores.user_id, top_scores.score, top_scores.guessed_at AS created_at + FROM games + -- Match the highest total score for each game + -- This can return multiple records if the top score was a tie: it means we count all of them as winners, which seems fair. + LEFT JOIN ( + SELECT user_id, game_id, MAX(score) AS score, guessed_at + FROM game_scores + GROUP BY game_id + ) top_scores ON games.id = top_scores.game_id + WHERE games.state = 'finished' + ` + ).run() + }, + function createBannedUsers(db) { + const bannedUsersTable = db.prepare(`CREATE TABLE banned_users (username TEXT NOT NULL)`) + + bannedUsersTable.run() + }, + function createLastStreakField(db) { + db.prepare(`ALTER TABLE guesses ADD COLUMN last_streak INTEGER DEFAULT NULL`).run() + }, + function moveFlagColorFieldsToUsersTable(db) { + db.prepare(`ALTER TABLE guesses DROP COLUMN color`).run() + db.prepare(`ALTER TABLE guesses DROP COLUMN flag`).run() + db.prepare(`ALTER TABLE users ADD COLUMN color STRING DEFAULT "#FFF"`).run() + }, + function createUsersAvatarField(db) { + db.prepare(`ALTER TABLE users ADD COLUMN avatar STRING DEFAULT NULL`).run() + }, + function removeUsersLastLocationField(db) { + db.prepare(`ALTER TABLE users DROP COLUMN last_location`).run() + } +] + +class db { + #db: SQLite.Database + + constructor(file: string) { + this.#db = new SQLite(file) + this.#migrate() + } + + #migrateUp() { + const version = this.#db.pragma('user_version', { simple: true }) + if (typeof version === 'number' && version < migrations.length) { + const up = this.#db.transaction(() => { + migrations[version](this.#db) + this.#db.pragma(`user_version=${version + 1}`) + }) + up() + + return true + } + return false + } + + #migrate() { + let moreMigrations = true + while (moreMigrations) { + moreMigrations = this.#migrateUp() + } + } + + createGame(seed: Seed) { + const insertGame = this.#db.prepare(` + INSERT INTO games(id, map, map_name, map_bounds, forbid_moving, forbid_panning, forbid_zooming, time_limit, created_at) + VALUES (:id, :map, :mapName, :bounds, :forbidMoving, :forbidPanning, :forbidZooming, :timeLimit, :createdAt) + `) + + insertGame.run({ + id: seed.token, + map: seed.map, + mapName: seed.mapName, + bounds: JSON.stringify(seed.bounds), + forbidMoving: seed.forbidMoving ? 1 : 0, + forbidPanning: seed.forbidRotating ? 1 : 0, + forbidZooming: seed.forbidZooming ? 1 : 0, + timeLimit: seed.timeLimit, + createdAt: timestamp() + }) + } + + getCurrentRound(gameId: string): string | undefined { + const findRoundId = this.#db + .prepare( + ` + SELECT id + FROM rounds + WHERE game_id = ? + ORDER BY created_at DESC + LIMIT 1 + ` + ) + .pluck(true) + + return findRoundId.get(gameId) as string | undefined + } + + createRound(gameId: string, round: Location_) { + const insertRound = this.#db.prepare(` + INSERT INTO rounds(id, game_id, location, created_at) + VALUES (:id, :gameId, :location, :createdAt) + `) + + const id = randomUUID() + + insertRound.run({ + id, + gameId, + location: JSON.stringify({ + lat: round.lat, + lng: round.lng, + panoId: round.panoId, + heading: round.heading, + pitch: round.pitch + }), + createdAt: timestamp() + }) + + return id + } + + setRoundCountry(roundId: string, country: string | null) { + const stmt = this.#db.prepare(`UPDATE rounds SET country = :country WHERE id = :id`) + stmt.run({ + id: roundId, + country + }) + } + + getLastRoundLocation() { + const stmt = this.#db + .prepare(`SELECT location from rounds ORDER BY created_at DESC LIMIT 1`) + .get() + return stmt as Location_ | undefined + } + + createGuess( + roundId: string, + userId: string, + guess: { + location: LatLng + country: string | null + streak: number + lastStreak: number | null + distance: number + score: number + } + ) { + const id = randomUUID() + const insertGuess = this.#db.prepare(` + INSERT INTO guesses(id, round_id, user_id, location, country, streak, last_streak, distance, score, created_at) + VALUES (:id, :roundId, :userId, :location, :country, :streak, :lastStreak, :distance, :score, :createdAt) + `) + + insertGuess.run({ + id, + roundId, + userId, + location: JSON.stringify(guess.location), + country: guess.country, + streak: guess.streak, + lastStreak: guess.lastStreak, + distance: guess.distance, + score: guess.score, + createdAt: timestamp() + }) + + return id + } + + getUserGuess(roundId: string, userId: string) { + const stmt = this.#db.prepare(` + SELECT + guesses.id, + users.avatar, + users.color, + users.flag, + guesses.location, + guesses.country, + guesses.streak, + guesses.last_streak AS lastStreak, + guesses.distance, + guesses.score + FROM guesses + JOIN users ON users.id = guesses.user_id + WHERE round_id = ? AND user_id = ? + `) + + const row = stmt.get(roundId, userId) as + | { + id: string + avatar: string | null + color: string + flag: string | null + location: string + country: string | null + streak: number + lastStreak: number | null + distance: number + score: number + } + | undefined + + if (!row) { + return + } + + return { + ...row, + location: JSON.parse(row.location) as LatLng + } + } + + updateGuess( + guessId: string, + guess: { + location: LatLng + country: string | null + streak: number + lastStreak: number | null + distance: number + score: number + } + ) { + const updateGuess = this.#db.prepare(` + UPDATE guesses + SET + location = :location, + country = :country, + streak = :streak, + last_streak = :lastStreak, + distance = :distance, + score = :score, + created_at = :updatedAt + WHERE id = :id + `) + + updateGuess.run({ + id: guessId, + location: JSON.stringify(guess.location), + country: guess.country, + streak: guess.streak, + lastStreak: guess.lastStreak, + distance: guess.distance, + score: guess.score, + updatedAt: timestamp() + }) + } + + // setGuessStreak(guessId: string, streak: number, lastStreak: number | null = null) { + // const updateGuess = this.#db.prepare(` + // UPDATE guesses + // SET streak = :streak, last_streak = :lastStreak + // WHERE id = :id + // `) + + // updateGuess.run({ + // id: guessId, + // streak, + // lastStreak + // }) + // } + + getUserStreak(userId: string): { id: string; count: number; lastLocation: LatLng } | undefined { + const stmt = this.#db.prepare(` + SELECT streaks.id, streaks.count, rounds.location + FROM users, streaks, rounds + WHERE users.id = ? + AND streaks.id = users.current_streak_id + AND rounds.id = streaks.last_round_id + `) + + const row = stmt.get(userId) as { id: string; count: number; location: string } | undefined + + return row + ? { + id: row.id, + count: row.count, + lastLocation: JSON.parse(row.location) + } + : undefined + } + + addUserStreak(userId: string, roundId: string) { + const streak = this.getUserStreak(userId) + + if (!streak) { + const id = randomUUID() + this.#db + .prepare( + ` + INSERT INTO streaks(id, user_id, last_round_id, created_at, updated_at) + VALUES (:id, :userId, :roundId, :createdAt, :createdAt) + ` + ) + .run({ + id, + userId, + roundId, + createdAt: timestamp() + }) + this.#db.prepare(`UPDATE users SET current_streak_id = :streakId WHERE id = :userId`).run({ + userId, + streakId: id + }) + } else { + this.#db + .prepare( + ` + UPDATE streaks + SET count = count + 1, + last_round_id = :roundId, + updated_at = :updatedAt + WHERE id = :id + ` + ) + .run({ + id: streak.id, + roundId, + updatedAt: timestamp() + }) + } + } + + resetUserStreak(userId: string) { + // In handleUserGuess() we need to get lastLocation from the previous streak in order to reset the streak if the player skipped a round + // so we don't need to return last streak from here anymore, it also saves a query in processMultiGuess() when streak is reseted + // const tx = this.#db.transaction(() => { + // const streak = this.getUserStreak(userId) + this.#db.prepare('UPDATE users SET current_streak_id = NULL WHERE id = ?').run(userId) + // return streak + // }) + // return tx()?.count ?? null + } + + /** + * Get all the participants for a round, sorted by time. No scores included. + */ + getRoundParticipants(roundId: string) { + const stmt = this.#db.prepare(` + SELECT + users.username, + users.avatar, + users.color, + users.flag + FROM guesses, users + WHERE round_id = ? AND users.id = guesses.user_id + ORDER BY created_at ASC + `) + + const records = stmt.all(roundId) as Player[] + + return records.map((record) => ({ + username: record.username, + avatar: record.avatar, + color: record.color, + flag: record.flag + })) as Player[] + } + + /** + * Get all the guesses for a round, sorted from closest distance to farthest away. + * For 5000 scores, the time to arrive at the guess is used instead of distance. + */ + getRoundResults(roundId: string) { + const stmt = this.#db.prepare(` + SELECT + guesses.id, + guesses.user_id, + users.username, + users.avatar, + users.color, + users.flag, + guesses.location, + guesses.streak, + guesses.country, + guesses.last_streak, + guesses.distance, + guesses.score, + guesses.created_at - rounds.created_at AS time, + IIF(guesses.score = 5000, guesses.created_at - rounds.created_at, NULL) AS time_to_5k + FROM rounds, guesses, users + WHERE rounds.id = ? + AND guesses.round_id = rounds.id + AND users.id = guesses.user_id + ORDER BY guesses.score DESC, + time_to_5k ASC, + guesses.distance ASC + `) + + const records = stmt.all(roundId) as { + id: string + user_id: string + username: string + avatar: string | null + color: string + flag: string | null + location: string + streak: number + country: string | null + last_streak: number | null + distance: number + score: number + time: number + }[] + + return records.map((record) => ({ + id: record.id, + player: { + userId: record.user_id, + username: record.username, + avatar: record.avatar, + color: record.color, + flag: record.flag + }, + streak: record.streak, + country: record.country, + lastStreak: record.last_streak, + distance: record.distance, + score: record.score, + time: record.time, + position: JSON.parse(record.location) as LatLng + })) as RoundResult[] + } + + /** + * Retrieve only needed values for processMultiGuesses() + */ + getRoundResultsSimplified(roundId: string) { + const stmt = this.#db.prepare(` + SELECT + guesses.id, + guesses.user_id, + guesses.streak, + guesses.country + FROM guesses, rounds + WHERE rounds.id = ? + AND guesses.round_id = rounds.id + `) + + const records = stmt.all(roundId) as { + id: string + user_id: string + streak: number + country: string | null + }[] + + return records.map((record) => ({ + id: record.id, + player: { + userId: record.user_id + }, + streak: record.streak, + country: record.country + })) + } + + /** + * Mark a game as finished. It will now count for the victory calculations. + */ + finishGame(gameId: string) { + const stmt = this.#db.prepare(`UPDATE games SET state = 'finished' WHERE id = ?`) + stmt.run(gameId) + } + + /** + * Get the total scores for a game, across all rounds, ordered from highest to lowest points. + */ + getGameResults(gameId: string) { + // We need to pick the last guess's streak value OR calculate them on the fly. Our streak tracking table is not suitable for + // checking the current streak at a previous point. The only option atm is to use this subquery I think, hopefully the + // performance is not too bad. + + const stmt = this.#db.prepare(` + SELECT + users.username, + users.avatar, + users.color, + users.flag, + '[' || GROUP_CONCAT(COALESCE(guesses.location, 'null')) || ']' AS guesses, + '[' || GROUP_CONCAT(COALESCE(guesses.score, 'null')) || ']' AS scores, + '[' || GROUP_CONCAT(COALESCE(guesses.distance, 'null')) || ']' AS distances, + SUM(guesses.score) AS total_score, + SUM(guesses.distance) AS total_distance, + ( + SELECT streak + FROM guesses ig, rounds ir + WHERE ir.game_id = rounds.game_id + AND ig.round_id = ir.id + AND ig.user_id = users.id + ORDER BY ig.created_at DESC + LIMIT 1 + ) AS streak + FROM rounds + JOIN users ON users.id IN ( + SELECT DISTINCT g.user_id + FROM rounds r + JOIN guesses g ON g.round_id = r.id + WHERE r.game_id = ? + ) + LEFT JOIN guesses ON guesses.round_id = rounds.id AND users.id = guesses.user_id + WHERE rounds.game_id = ? + GROUP BY users.id + ORDER BY total_score DESC, total_distance ASC + `) + + const records = stmt.all(gameId, gameId) as { + username: string + avatar: string | null + color: string + flag: string | null + streak: number + guesses: string + scores: string + distances: string + total_score: number + total_distance: number + }[] + + return records.map((record) => ({ + player: { + username: record.username, + avatar: record.avatar, + color: record.color, + flag: record.flag + }, + streak: record.streak, + guesses: JSON.parse(record.guesses), + scores: JSON.parse(record.scores), + distances: JSON.parse(record.distances), + totalScore: record.total_score, + totalDistance: record.total_distance + })) as GameResult[] + } + + #parseUser(record: Record): { + id: string + username: string + avatar: string | null + color: string + flag: string | null + previousGuess: LatLng + resetAt: number + } { + return { + id: record.id, + username: record.username, + avatar: record.avatar, + color: record.color, + flag: record.flag, + previousGuess: record.previous_guess ? JSON.parse(record.previous_guess) : null, + resetAt: record.reset_at * 1000 + } + } + + getUser(id: string) { + const user = this.#db + .prepare( + 'SELECT id, username, avatar, color, flag, previous_guess, reset_at FROM users WHERE id = ?' + ) + .get(id) + + return user ? this.#parseUser(user) : undefined + } + + getOrCreateUser(id: string, username: string, avatar: string | undefined, color = '#FFF') { + const stmt = this.#db.prepare(` + INSERT INTO users(id, username, avatar, color) + VALUES (:id, :username, :avatar, :color) + ON CONFLICT (id) DO + UPDATE SET + username = :username, + avatar = :avatar, + color = :color + RETURNING * + `) + const user = stmt.get({ id, username, avatar, color }) + + return user ? this.#parseUser(user) : undefined + } + + setUserFlag(userId: string, flag: string | null) { + this.#db.prepare(`UPDATE users SET flag = :flag WHERE id = :id`).run({ + id: userId, + flag + }) + } + + setUserPreviousGuess(userId: string, previousGuess: LatLng) { + this.#db.prepare(`UPDATE users SET previous_guess = :previousGuess WHERE id = :id`).run({ + id: userId, + previousGuess: JSON.stringify(previousGuess) + }) + } + + getUserStats(userId: string) { + const stmt = this.#db.prepare(` + SELECT + username, + flag, + COALESCE(current_streak.count, 0) AS current_streak, + COALESCE((SELECT MAX(count) FROM streaks WHERE user_id = :id AND updated_at > users.reset_at), 0) AS best_streak, + (SELECT COUNT(*) FROM guesses WHERE user_id = :id AND created_at > users.reset_at) AS total_guesses, + (SELECT COUNT(*) FROM guesses WHERE user_id = :id AND streak > 0 AND created_at > users.reset_at) AS correct_guesses, + (SELECT COUNT(*) FROM guesses WHERE user_id = :id AND score = 5000 AND created_at > users.reset_at) AS perfects, + (SELECT AVG(score) FROM guesses WHERE user_id = users.id AND created_at > users.reset_at) AS average, + (SELECT COUNT(*) FROM game_winners WHERE user_id = users.id AND created_at > users.reset_at) AS victories + FROM users + LEFT JOIN streaks current_streak ON current_streak.id = users.current_streak_id + WHERE users.id = :id + `) + + const record = stmt.get({ id: userId }) as + | { + username: string + flag: string + current_streak: number + best_streak: number + total_guesses: number + correct_guesses: number + perfects: number + average: number + victories: number + } + | undefined + + return record + ? { + username: record.username, + flag: record.flag, + streak: record.current_streak, + bestStreak: record.best_streak, + nbGuesses: record.total_guesses, + correctGuesses: record.correct_guesses, + meanScore: record.average, + perfects: record.perfects, + victories: record.victories + } + : undefined + } + + getGlobalStats() { + const streakQuery = this.#db.prepare(` + SELECT users.id, users.username, MAX(streaks.count) AS streak + FROM users, streaks + WHERE NOT users.id = 'BROADCASTER' + AND streaks.user_id = users.id + AND streaks.created_at > users.reset_at + GROUP BY users.id + ORDER BY streak DESC + `) + + const victoriesQuery = this.#db.prepare(` + SELECT users.id, users.username, COUNT(*) AS victories + FROM game_winners, users + WHERE NOT users.id = 'BROADCASTER' + AND users.id = game_winners.user_id + AND game_winners.created_at > users.reset_at + GROUP BY users.id + ORDER BY victories DESC + `) + + const perfectQuery = this.#db.prepare(` + SELECT users.id, users.username, COUNT(guesses.id) AS perfects + FROM users + LEFT JOIN guesses ON guesses.user_id = users.id AND guesses.created_at > users.reset_at + WHERE NOT users.id = 'BROADCASTER' + AND guesses.score = 5000 + GROUP BY users.id + ORDER BY perfects DESC + `) + + const bestStreak = streakQuery.get() as + | { id: string; username: string; streak: number } + | undefined + const mostVictories = victoriesQuery.get() as + | { id: string; username: string; victories: number } + | undefined + const mostPerfects = perfectQuery.get() as + | { id: string; username: string; perfects: number } + | undefined + + return { + streak: bestStreak, + victories: mostVictories, + perfects: mostPerfects + } + } + + resetUserStats(userId: string) { + this.#db + .prepare(`UPDATE users SET current_streak_id = NULL, reset_at = :resetAt WHERE id = :id`) + .run({ + id: userId, + resetAt: timestamp() + }) + } + + /** + * Check if the database contains any data. + */ + isEmpty(): boolean { + const result = this.#db.prepare('SELECT COUNT(*) as count FROM users;').get() as + | { count: number } + | undefined + return !result || result.count === 0 + } + + async clear() { + if (!this.#db.memory) { + try { + await this.#db.backup(`${this.#db.name}.bak`) + } catch {} + } + + const deleteEverything = this.#db.transaction(() => { + // Disable foreign key checking while we delete everything + this.#db.prepare('PRAGMA foreign_keys=0;').run() + this.#db.prepare('DELETE FROM guesses;').run() + this.#db.prepare('DELETE FROM streaks;').run() + this.#db.prepare('DELETE FROM rounds;').run() + this.#db.prepare('DELETE FROM games;').run() + this.#db.prepare('DELETE FROM users;').run() + this.#db.prepare('PRAGMA foreign_keys=1;').run() + }) + deleteEverything() + } + + getBannedUsers() { + const bannedUsers = this.#db.prepare(`SELECT username FROM banned_users`).all() as { + username: string + }[] + return bannedUsers + } + + addBannedUser(username: string) { + this.#db + .prepare( + ` + INSERT INTO banned_users (username) + VALUES (:username) + ` + ) + .run({ username: username }) + } + + deleteBannedUser(username: string) { + this.#db + .prepare( + ` + DELETE FROM banned_users + WHERE username = :username + ` + ) + .run({ username: username }) + } + + /** + * Run a custom SQL query, for use in tests only. + */ + [Symbol.for('chatguessr-test-run-query')](query, data) { + if (process.env.NODE_ENV !== 'test') { + throw new Error('Do not run queries outside of the test environment') + } + + return this.#db.prepare(query).run(data) + } +} + +export const database = (dbPath: string) => new db(dbPath) + +declare global { + interface Database extends db {} +} diff --git a/src/main/utils/gameHelper.test.ts b/src/main/utils/gameHelper.test.ts new file mode 100644 index 0000000..be69c3d --- /dev/null +++ b/src/main/utils/gameHelper.test.ts @@ -0,0 +1,120 @@ +import { describe, it, expect } from 'vitest' +import * as GameHelper from './gameHelper' + +describe('getCountryCode', () => { + // These are not political opinions, but checks to ensure we match whatever decisions + // GeoGuessr has made, even when those decisions are bad. + + it('identifies the country', async () => { + const korea = { lat: 37.00990352577917, lng: 128.60820945116575 } + await expect(GameHelper.getCountryCode(korea)).resolves.toBe('KR') + const luxNearBorder = { lat: 50.18241242506854, lng: 6.022353016459996 } + await expect(GameHelper.getCountryCode(luxNearBorder)).resolves.toBe('LU') + const nearNorthPole = { lat: 87.94532231211203, lng: 102.72437132716654 } + await expect(GameHelper.getCountryCode(nearNorthPole)).resolves.toBe(undefined) + }) + it('counts islands near China under TW rule as Taiwan', async () => { + const kinmen = { lat: 24.478693881519966, lng: 118.30351505188996 } + await expect(GameHelper.getCountryCode(kinmen)).resolves.toBe('TW') + const lienchiang = { lat: 26.1640452690357, lng: 119.91813403003158 } + await expect(GameHelper.getCountryCode(lienchiang)).resolves.toBe('TW') + const dongyin = { lat: 26.37011790575555, lng: 120.48353606410257 } + await expect(GameHelper.getCountryCode(dongyin)).resolves.toBe('TW') + }) + it('counts HK/Macao as China', async () => { + const hongKong = { lat: 22.424952693214557, lng: 114.12527863797602 } + await expect(GameHelper.getCountryCode(hongKong)).resolves.toBe('CN') + const macao = { lat: 22.17174108804142, lng: 113.53648510492957 } + await expect(GameHelper.getCountryCode(macao)).resolves.toBe('CN') + }) + it('counts Israel/Palestine as the same country', async () => { + const il = await GameHelper.getCountryCode({ lat: 32.034961561407215, lng: 34.75764745886409 }) + const ps = await GameHelper.getCountryCode({ lat: 31.862835854507576, lng: 35.456499397290635 }) + expect(il).toBe(ps) + }) + it('counts Åland as Finland', async () => { + const aland = { lat: 60.41415638472204, lng: 20.309877225436857 } + await expect(GameHelper.getCountryCode(aland)).resolves.toBe('FI') + }) + it('counts Lesotho as Lesotho', async () => { + const ls = { lat: -29.496987596535757, lng: 28.212890625 } + expect(await GameHelper.getCountryCode(ls)).toBe('LS') + }) + it("counts Campione d'Italia as Italy", async () => { + const campione = { lat: 45.9689301700563, lng: 8.97377014160156 } + expect(await GameHelper.getCountryCode(campione)).toBe('IT') + }) + it('counts San Marino', async () => { + const sanMarino = { lat: 43.937461690316646, lng: 12.47222900390625 } + expect(await GameHelper.getCountryCode(sanMarino)).toBe('SM') + }) + it('counts Vatican City', async () => { + const vatican = { lat: 41.903363034132724, lng: 12.452659606933594 } + expect(await GameHelper.getCountryCode(vatican)).toBe('VA') + }) + it('Baarle-Nassau and Baarle-Hertog are resolved properly', async () => { + const nl = { lat: 51.439391, lng: 4.931514 } + const be = { lat: 51.445161, lng: 4.94144 } + expect(await GameHelper.getCountryCode(nl)).toBe('NL') + expect(await GameHelper.getCountryCode(be)).toBe('BE') + }) + it('the Vennbahn is resolved properly', async () => { + const de = { lat: 50.563848, lng: 6.211089 } + const be = { lat: 50.563992, lng: 6.231465 } + expect(await GameHelper.getCountryCode(de)).toBe('DE') + expect(await GameHelper.getCountryCode(be)).toBe('BE') + }) + it('counts Llívia as spain', async () => { + const es = { lat: 42.465134, lng: 1.976742 } + expect(await GameHelper.getCountryCode(es)).toBe('ES') + }) +}) + +describe('parseCoordinates', () => { + it("Checks if '30.12345, 50.54321' are valid coordinates >> true", () => { + expect(GameHelper.parseCoordinates('30.12345, 50.54321')).toBeTruthy() + }) + it("Checks if '30.12345,50.54321' are valid coordinates >> true", () => { + expect(GameHelper.parseCoordinates('30.12345,50.54321')).toBeTruthy() + }) + it("Checks if '-30.12345, -50.54321' are valid coordinates >> true", () => { + const coord = GameHelper.parseCoordinates('-30.12345, -50.54321') + expect(coord).toBeDefined() + expect(coord!.lat).toBeCloseTo(-30.12345, 4) + expect(coord!.lng).toBeCloseTo(-50.54321, 4) + }) + it("Checks if '-30.12345,-50.54321' are valid coordinates >> true", () => { + expect(GameHelper.parseCoordinates('-30.12345,-50.54321')).toBeTruthy() + }) + it("Checks if '95.12345, 50.54321' are invalid coordinates >> false", () => { + expect(GameHelper.parseCoordinates('95.12345, 50.54321')).toBeFalsy() + }) + it("Checks if '30.12345, 190.54321' are invalid coordinates >> false", () => { + expect(GameHelper.parseCoordinates('30.12345, 190.54321')).toBeFalsy() + }) +}) + +describe('randomPlonk', () => { + // Requires ~30ms/test + const repeats = 100 + it('Checks if randomplonk without bounds avoids antarctica', async () => { + // This takes about 30ms/test, so ... + for (let i = 0; i < repeats; i++) { + const { lat, lng } = await GameHelper.getRandomCoordsInLand() + expect(lat > -60).toBeTruthy() + expect(lat < 90).toBeTruthy() + expect(lng > -180).toBeTruthy() + expect(lng < 180).toBeTruthy() + } + }) + it('Checks if randomplonk with bounds remains in bounds', async () => { + const inBounds = { min: { lat: 32, lng: -117 }, max: { lat: 33, lng: -116 } } + for (let i = 0; i < repeats; i++) { + const { lat, lng } = await GameHelper.getRandomCoordsInLand(inBounds) + expect(lat > inBounds.min.lat).toBeTruthy() + expect(lat < inBounds.max.lat).toBeTruthy() + expect(lng > inBounds.min.lng).toBeTruthy() + expect(lng < inBounds.max.lng).toBeTruthy() + } + }) +}) diff --git a/src/main/utils/gameHelper.ts b/src/main/utils/gameHelper.ts new file mode 100644 index 0000000..292eaa6 --- /dev/null +++ b/src/main/utils/gameHelper.ts @@ -0,0 +1,187 @@ +import axios from 'axios' +import countryIso from 'coordinate_to_country' +import { session } from 'electron' +/** + * Country code mapping for 2-character ISO codes that should be considered + * part of another country for GeoGuessr streak purposes. + */ +import countryCodes from '../lib/countryCodes.json' + +const GEOGUESSR_URL = 'https://geoguessr.com' +const CG_API_URL = import.meta.env.VITE_CG_API_URL ?? 'https://chatguessr.com/api' +const CG_PUBLIC_URL = import.meta.env.VITE_CG_PUBLIC_URL ?? 'chatguessr.com' + +/** + * Checks if the URL is an in-game page. + */ +export function isGameURL(url: string): boolean { + return url.includes('/game/') +} + +/** + * Gets the Game ID from a game URL + * Checks if ID is 16 characters in length + */ +export function getGameId(url: string): string | void { + const id = url.slice(url.lastIndexOf('/') + 1) + if (id.length == 16) return id +} + +/** + * Get GeoGuessr cookies + */ +async function getCookies() { + return session.defaultSession.cookies + .get({ url: 'https://www.geoguessr.com' }) + .then((cookies) => { + const ncfa = cookies.find((cookie) => cookie.name === '_ncfa') + return ncfa ? { Cookie: `${ncfa.name}=${ncfa.value}` } : null + }) + .catch((err) => { + console.error(err) + }) +} + +/** + * Fetch a game seed from the GeoGuessr API. + */ +export async function fetchSeed(url: string): Promise { + const cookies = await getCookies() + const gameId = getGameId(url) + if (!gameId || !cookies) { + return + } + + const { data } = await axios.get(`${GEOGUESSR_URL}/api/v3/games/${gameId}`, { headers: cookies }) + return data +} + +/** + * Compare two coordinates + */ +export function latLngEqual(a: LatLng, b: LatLng) { + return a.lat === b.lat && a.lng === b.lng +} + +/** + * Get the country code for a coordinate. + */ +export async function getCountryCode(location: LatLng): Promise { + const localResults = countryIso(location.lat, location.lng, true) + const localIso = localResults.length > 0 ? localResults[0] : undefined + if (!localIso) return + + return countryCodes[localIso] +} + +/** + * Parse lat/lng coordinates from a string. + */ +export function parseCoordinates(coordinates: string): LatLng | void { + const regex = + /^(?[-+]?(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?)),\s*(?[-+]?(?:180(?:\.0+)?|(?:(?:1[0-7]\d)|(?:[1-9]?\d))(?:\.\d+)?))$/ + const m = regex.exec(coordinates) + if (m?.groups) { + return { lat: parseFloat(m.groups.lat), lng: parseFloat(m.groups.lng) } + } +} + +/** + * Returns map scale + */ +export function calculateScale(bounds: Bounds): number { + return haversineDistance(bounds.min, bounds.max) / 7.458421 +} + +/** + * Returns distance in km between two coordinates + */ +export function haversineDistance(mk1: LatLng, mk2: LatLng): number { + const R = 6371.071 + const rlat1 = mk1.lat * (Math.PI / 180) + const rlat2 = mk2.lat * (Math.PI / 180) + const difflat = rlat2 - rlat1 + const difflon = (mk2.lng - mk1.lng) * (Math.PI / 180) + const km = + 2 * + R * + Math.asin( + Math.sqrt( + Math.sin(difflat / 2) * Math.sin(difflat / 2) + + Math.cos(rlat1) * Math.cos(rlat2) * Math.sin(difflon / 2) * Math.sin(difflon / 2) + ) + ) + return km +} + +/** + * Returns score based on distance and scale + */ +export function calculateScore(distance: number, scale: number): number { + if (distance * 1000 < 25) return 5000 + return Math.round(5000 * Math.pow(0.99866017, (distance * 1000) / scale)) +} + +/** + * Upload scores to the Chatguessr API and return the game summary link + */ +export async function makeLink(params: { + accessToken: string + bot: string + streamer: string + map: string + mode: GameMode + locations: Location_[] + gameResults: GameResult[] +}): Promise { + const res = await axios.post<{ code: string }>( + `${CG_API_URL}/game`, + { + bot: params.bot, + streamer: params.streamer, + map: params.map, + mode: params.mode, + locations: params.locations, + players: params.gameResults + }, + { headers: { access_token: params.accessToken } } + ) + + return `${CG_PUBLIC_URL}/game/${res.data.code}` +} + +export async function fetchMap(mapToken: string): Promise { + const cookies = await getCookies() + if (!cookies) { + return + } + + const { data } = await axios.get(`${GEOGUESSR_URL}/api/maps/${mapToken}`, { headers: cookies }) + return data +} + +/** + * Returns random coordinates within land, no Antarctica + */ +export async function getRandomCoordsInLand(bounds: Bounds | null = null): Promise { + let lat_north = 85, + lat_south = -60, + lng_west = -180, + lng_east = 180 + if (bounds != null) { + lat_north = bounds.max.lat + lat_south = Math.max(bounds.min.lat, lat_south) + lng_east = bounds.max.lng + lng_west = bounds.min.lng + } + const lat = Math.random() * (lat_north - lat_south) + lat_south + const lng = Math.random() * (lng_east - lng_west) + lng_west + const localResults = countryIso(lat, lng, true) + if (!localResults.length) return await getRandomCoordsInLand(bounds) + return { lat, lng } +} + +export async function getStreamerAvatar(channel: string): Promise<{ avatar: string }> { + const { data } = await axios.get<{ avatar: string }>(`${CG_API_URL}/channel/${channel}`) + return data +} diff --git a/src/main/utils/store.ts b/src/main/utils/store.ts new file mode 100644 index 0000000..b3d0c22 --- /dev/null +++ b/src/main/utils/store.ts @@ -0,0 +1,8 @@ +import ElectronStore from 'electron-store' + +type Schema = { + settings: Settings + session: Session | null +} + +export const store: ElectronStore = new ElectronStore() diff --git a/src/main/utils/useSettings.ts b/src/main/utils/useSettings.ts new file mode 100644 index 0000000..195247b --- /dev/null +++ b/src/main/utils/useSettings.ts @@ -0,0 +1,37 @@ +import { store } from './store' + +const storedSettings = store.get('settings') + +declare global { + type Settings = typeof defaultSettings +} + +const defaultSettings = { + channelName: '', + avatar: '', + cgCmd: '!cg', + cgCmdCooldown: 30, + cgMsg: `Two ways to play: Link your Twitch account, guess and plonk with spacebar | or paste the command into chat without editing: `, + mapCmd: '!map', + mapCmdCooldown: 30, + flagsCmd: '!flags', + getUserStatsCmd: '!me', + getBestStatsCmd: '!best', + clearUserStatsCmd: '!clear', + randomPlonkCmd: '!randomplonk', + showHasGuessed: true, + showHasAlreadyGuessed: true, + showGuessChanged: true, + showSubmittedPreviousGuess: true, + isMultiGuess: false, + guessMarkersLimit: 30 +} + +const settings = Object.assign({}, defaultSettings, storedSettings) + +const saveSettings = (settings_: Settings): void => { + Object.assign(settings, settings_) + store.set('settings', settings) +} + +export { settings, saveSettings } diff --git a/src/main/utils/useSupabase.ts b/src/main/utils/useSupabase.ts new file mode 100644 index 0000000..e282ed4 --- /dev/null +++ b/src/main/utils/useSupabase.ts @@ -0,0 +1,10 @@ +import { createClient } from '@supabase/supabase-js' + +const supabaseUrl = import.meta.env.VITE_SUPABASE_URL +const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY + +export const supabase = createClient(supabaseUrl, supabaseAnonKey) + +declare global { + type Session = import('@supabase/supabase-js').Session +} diff --git a/src/main/utils/useTwitchJS.ts b/src/main/utils/useTwitchJS.ts new file mode 100644 index 0000000..fb3c3b8 --- /dev/null +++ b/src/main/utils/useTwitchJS.ts @@ -0,0 +1,71 @@ +import { EventEmitter } from 'events' +import { Client } from 'tmi.js' + +export default class TwitchBackend extends EventEmitter { + #tmi: Client + + #closing = false + + botUsername: string + + channelName: string + + constructor(options: { botUsername: string; channelName: string; whisperToken: string }) { + super() + + this.botUsername = options.botUsername + this.channelName = options.channelName + + this.#tmi = new Client({ + options: { debug: true, messagesLogLevel: 'info' }, + connection: { + secure: true, + reconnect: false + }, + identity: { + username: this.botUsername, + password: `oauth:${options.whisperToken}` + }, + channels: [this.channelName] + }) + + this.#tmi.on('connected', () => { + this.emit('connected') + }) + + this.#tmi.on('disconnected', () => { + this.emit('disconnected', this.#closing) + }) + + this.#tmi.on('whisper', (_from, userstate, message, self) => { + if (self) return + this.emit('guess', userstate, message) + }) + + this.#tmi.on('message', (_channel, userstate, message, self) => { + if (self) return + this.emit('message', userstate, message) + }) + } + + async connect() { + await this.#tmi.connect() + } + + async close() { + this.#closing = true + await this.#tmi.disconnect() + } + + isConnected() { + return this.#tmi.readyState() === 'OPEN' + } + + async sendMessage(message: string, options: { system?: boolean } = {}) { + if (options.system) { + await this.#tmi.action(this.channelName, message) + } else { + await this.#tmi.say(this.channelName, message) + } + } +} diff --git a/src/module.d.ts b/src/module.d.ts new file mode 100644 index 0000000..4a67505 --- /dev/null +++ b/src/module.d.ts @@ -0,0 +1,7 @@ +/// +/// + +declare module 'coordinate_to_country' { + function coordinate_to_country(lat: number, lng: number, isoA2?: boolean): string[] + export = coordinate_to_country +} diff --git a/src/modules.d.ts b/src/modules.d.ts deleted file mode 100644 index 3ff0d2e..0000000 --- a/src/modules.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -declare module 'coordinate_to_country' { - function coordinate_to_country(lat: number, lng: number, isoA2?: boolean): string[]; - export = coordinate_to_country; -} - -declare module 'electron-squirrel-startup' { - export = boolean; -} - -declare module 'bundle-text:*' { - export = string; -} \ No newline at end of file diff --git a/src/preload.ts b/src/preload.ts deleted file mode 100644 index 0164908..0000000 --- a/src/preload.ts +++ /dev/null @@ -1,90 +0,0 @@ -import "./errorReporting"; -import { contextBridge, ipcRenderer } from "electron"; -import type { LatLng, Location, Guess, RoundScore, GameResult } from "./types"; - -function ipcRendererOn(event: string, callback: (...args: unknown[]) => void) { - const listener = (_event: unknown, ...args: unknown[]) => { - callback(...args); - }; - - ipcRenderer.on(event, listener); - return () => ipcRenderer.off(event, listener); -} - -export type ConnectionState = - | { state: "disconnected" } - | { state: "connecting" } - | { state: "connected"; botUsername: string; channelName: string }; - -const chatguessrApi = { - setGuessesOpen(open: boolean) { - if (open) { - ipcRenderer.send("open-guesses"); - } else { - ipcRenderer.send("close-guesses"); - } - }, - startNextRound() { - ipcRenderer.send("next-round-click"); - }, - returnToMapPage() { - ipcRenderer.send("return-to-map-page"); - }, - openSettings() { - ipcRenderer.send("openSettings"); - }, - getConnectionState(): Promise { - return ipcRenderer.invoke("get-connection-state"); - }, - appDataPathExists(subdir?: string): Promise { - return ipcRenderer.invoke("app-data-path-exists", subdir); - }, - importAudioFile() { - return ipcRenderer.invoke("import-audio-file"); - }, - - onGameStarted(callback: (isMultiGuess: boolean, restoredGuesses: Guess[], location: LatLng) => void) { - return ipcRendererOn("game-started", callback); - }, - onGameQuit(callback: () => void) { - return ipcRendererOn("game-quitted", callback); - }, - onReceiveGuess(callback: (guess: Guess) => void) { - return ipcRendererOn("render-guess", callback); - }, - onReceiveMultiGuesses(callback: (guesses: Guess[]) => void) { - return ipcRendererOn("render-multiguess", callback); - }, - onShowRoundResults( - callback: (round: number, location: Location, roundResults: RoundScore[], markerLimit: number) => void - ) { - return ipcRendererOn("show-round-results", callback); - }, - onShowGameResults(callback: (locations: Location[], gameResults: GameResult[]) => void) { - return ipcRendererOn("show-game-results", callback); - }, - onStartRound(callback: (isMultiGuess: boolean, location: LatLng) => void) { - return ipcRendererOn("next-round", callback); - }, - onRefreshRound(callback: (location: LatLng) => void) { - return ipcRendererOn("refreshed-in-game", callback); - }, - onGuessesOpenChanged(callback: (open: boolean) => void) { - const remove = [ - ipcRendererOn("switch-on", () => callback(true)), - ipcRendererOn("switch-off", () => callback(false)), - ]; - return () => { - for (const unlisten of remove) { - unlisten(); - } - }; - }, - onConnectionStateChange(callback: (state: ConnectionState) => void) { - return ipcRendererOn("connection-state", callback); - }, -}; - -export type ChatguessrApi = typeof chatguessrApi; - -contextBridge.exposeInMainWorld("chatguessrApi", chatguessrApi); diff --git a/src/preload/chatguessrApi.ts b/src/preload/chatguessrApi.ts new file mode 100644 index 0000000..eaadc11 --- /dev/null +++ b/src/preload/chatguessrApi.ts @@ -0,0 +1,159 @@ +import { ipcRenderer } from 'electron' + +declare global { + interface Window { + chatguessrApi: typeof chatguessrApi + } +} + +export const chatguessrApi = { + setGuessesOpen(open: boolean) { + if (open) { + ipcRenderer.send('open-guesses') + } else { + ipcRenderer.send('close-guesses') + } + }, + + startNextRound() { + ipcRenderer.send('next-round-click') + }, + + returnToMapPage() { + ipcRenderer.send('return-to-map-page') + }, + + getSettings(): Promise { + return ipcRenderer.invoke('get-settings') + }, + + saveSettings(settings: Settings) { + ipcRenderer.send('save-settings', settings) + }, + + getBannedUsers(): Promise<{ username: string }[]> { + return ipcRenderer.invoke('get-banned-users') + }, + + addBannedUser(username: string) { + ipcRenderer.send('add-banned-user', username) + }, + + deleteBannedUser(username: string) { + ipcRenderer.send('delete-banned-user', username) + }, + + appDataPathExists(subdir?: string): Promise { + return ipcRenderer.invoke('app-data-path-exists', subdir) + }, + + importAudioFile(): Promise { + return ipcRenderer.invoke('import-audio-file') + }, + + onGameStarted( + callback: ( + isMultiGuess: boolean, + restoredGuesses: RoundResult[] | Player[], + location: Location_ + ) => void + ) { + return ipcRendererOn('game-started', callback) + }, + + onGameQuit(callback: () => void) { + return ipcRendererOn('game-quitted', callback) + }, + + onReceiveGuess(callback: (guess: Guess) => void) { + return ipcRendererOn('render-guess', callback) + }, + + onReceiveMultiGuesses(callback: (guess: Guess) => void) { + return ipcRendererOn('render-multiguess', callback) + }, + + onShowRoundResults( + callback: ( + round: number, + location: Location_, + roundResults: RoundResult[], + markerLimit: number + ) => void + ) { + return ipcRendererOn('show-round-results', callback) + }, + + onShowGameResults(callback: (locations: Location_[], gameResults: GameResult[]) => void) { + return ipcRendererOn('show-game-results', callback) + }, + + onStartRound(callback: (location: Location_) => void) { + return ipcRendererOn('next-round', callback) + }, + + onRefreshRound(callback: (location: Location_) => void) { + return ipcRendererOn('refreshed-in-game', callback) + }, + + onGuessesOpenChanged(callback: (open: boolean) => void) { + const remove = [ + ipcRendererOn('switch-on', () => callback(true)), + ipcRendererOn('switch-off', () => callback(false)) + ] + return () => { + for (const unlisten of remove) { + unlisten() + } + } + }, + + reconnect(): void { + ipcRenderer.send('reconnect') + }, + + replaceSession(): void { + ipcRenderer.invoke('replace-session') + }, + + getTwitchConnectionState(): Promise { + return ipcRenderer.invoke('get-twitch-connection-state') + }, + + onTwitchConnectionStateChange(callback: (state: TwitchConnectionState) => void) { + return ipcRendererOn('twitch-connection-state', callback) + }, + + onTwitchError(callback: (err: unknown) => void) { + return ipcRendererOn('twitch-error', callback) + }, + + getSocketConnectionState(): Promise { + return ipcRenderer.invoke('get-socket-connection-state') + }, + + onSocketConnected(callback: () => void) { + return ipcRendererOn('socket-connected', callback) + }, + + onSocketDisconnected(callback: () => void) { + return ipcRendererOn('socket-disconnected', callback) + }, + + clearStats(): void { + ipcRenderer.send('clear-stats') + }, + + getCurrentVersion(): Promise { + return ipcRenderer.invoke('get-current-version') + } +} + +function ipcRendererOn(event: string, callback: (...args: any[]) => void) { + const listener = (_event: unknown, ...args: unknown[]) => { + callback(...args) + } + + ipcRenderer.on(event, listener) + return () => ipcRenderer.off(event, listener) +} diff --git a/src/preload/preload.ts b/src/preload/preload.ts new file mode 100644 index 0000000..e73918e --- /dev/null +++ b/src/preload/preload.ts @@ -0,0 +1,33 @@ +import fs from 'fs' +import { join } from 'path' +import { contextBridge } from 'electron' +import { chatguessrApi } from './chatguessrApi' +import whenDomReady from 'when-dom-ready' +import useLoading from './useLoading' + +const { appendLoading, removeLoading } = useLoading() + +const rendererJS = fs.readFileSync(join(__dirname, 'renderer.js'), 'utf8') +const rendererCSS = fs.readFileSync(join(__dirname, 'style.css'), 'utf8') + +whenDomReady().then(() => { + appendLoading() + + const script = document.createElement('script') + script.type = 'module' + script.innerHTML = rendererJS + document.body.appendChild(script) + + const css = document.createElement('style') + css.textContent = rendererCSS + document.body.appendChild(css) +}) + +window.onmessage = (ev: MessageEvent) => { + ev.data.payload === 'removeLoading' && removeLoading() +} +setTimeout(removeLoading, 4999) + +// Expose protected methods off of window in order to use ipcRenderer +// without exposing the entire object +contextBridge.exposeInMainWorld('chatguessrApi', chatguessrApi) diff --git a/src/preload/useLoading.ts b/src/preload/useLoading.ts new file mode 100644 index 0000000..2fe29fc --- /dev/null +++ b/src/preload/useLoading.ts @@ -0,0 +1,54 @@ +const safeDOM = { + append(parent: HTMLElement, child: HTMLElement): HTMLElement | void { + if (!Array.from(parent.children).find((e) => e === child)) { + return parent.appendChild(child) + } + }, + remove(parent: HTMLElement, child: HTMLElement): HTMLElement | void { + if (Array.from(parent.children).find((e) => e === child)) { + return parent.removeChild(child) + } + } +} + +export default function useLoading() { + const styleContent = ` + .app-loading-wrap { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: #1a1a2e; + z-index: 9; + } + .loader { + width: 60px; + animation: spin 3s infinite ease-in-out; + } + @keyframes spin { + 0% { transform: rotate(0deg) } + 100% { transform: rotate(360deg) } + } + ` + const style = document.createElement('style') + const div = document.createElement('div') + + style.innerHTML = styleContent + div.className = 'app-loading-wrap' + div.innerHTML = `` + + return { + appendLoading() { + safeDOM.append(document.head, style) + safeDOM.append(document.body, div) + }, + removeLoading() { + safeDOM.remove(document.head, style) + safeDOM.remove(document.body, div) + } + } +} diff --git a/src/renderer.js b/src/renderer.js deleted file mode 100644 index b336e59..0000000 --- a/src/renderer.js +++ /dev/null @@ -1,432 +0,0 @@ -import { createApp } from "vue"; -import "./utils/mods/extenssrMenuItemsPlugin"; -import { drParseNoCar } from "./utils/mods/drParseNoCar"; -import { blinkMode } from "./utils/mods/blinkMode"; -import { satelliteMode } from "./utils/mods/satelliteMode"; -import Frame from "./components/Frame.vue"; - -/** @typedef {import("./types").Location} Location */ -/** @typedef {import("./types").Guess} Guess */ - -function start() { - drParseNoCar(); - blinkMode(); - satelliteMode(); - - const wrapper = document.createElement("div"); - document.body.append(wrapper); - - const app = createApp(Frame, { - chatguessrApi: window.chatguessrApi, - drawRoundResults, - clearMarkers, - drParseNoCar, - blinkMode, - satelliteMode, - showSatelliteMap, - hideSatelliteMap, - centerSatelliteView, - getBounds, - focusOnGuess, - drawPlayerResults, - drawGameLocations, - }); - app.mount(wrapper); -} - -/** @type {google.maps.Map | undefined} */ -let globalMap = undefined; -/** @type {google.maps.Map | undefined} */ -let satelliteLayer = undefined; -/** @type {google.maps.Marker | undefined} */ -let satelliteMarker = undefined; -const satelliteCanvas = document.createElement("div"); -satelliteCanvas.id = "satelliteCanvas"; - -const mapReady = hijackMap(); - -/** @type {google.maps.Marker[]} */ -let guessMarkers = []; -/** @type {google.maps.Marker[]} */ -let locationMarkers = []; -/** @type {google.maps.Polyline[]} */ -let polylines = []; - -/** @type {import('./types').RendererApi['drawRoundResults']} */ -function drawRoundResults(location, roundResults, limit = 100) { - const map = globalMap; - const infowindow = new google.maps.InfoWindow(); - - const icon = makeIcon(); - const locationMarker = makeLocationMarker(location, icon, map); - locationMarkers.push(locationMarker); - - icon.scale = 1; - roundResults.forEach((result, index) => { - if (index >= limit) return; - - icon.fillColor = result.color; - - const guessMarker = new google.maps.Marker({ - position: result.position, - icon, - map, - label: { - color: "#000", - fontWeight: "bold", - fontSize: "16px", - text: `${index + 1}`, - }, - optimized: true, - }); - guessMarker.addListener("mouseover", () => { - infowindow.setContent(` - ${ - result.flag - ? `` - : "" - } - ${result.username}
- ${result.score}
- ${toMeter(result.distance)} - `); - infowindow.open(map, guessMarker); - }); - guessMarker.addListener("mouseout", () => { - infowindow.close(); - }); - guessMarkers.push(guessMarker); - - polylines.push( - new google.maps.Polyline({ - strokeColor: result.color, - strokeWeight: 4, - strokeOpacity: 0.6, - geodesic: true, - map, - path: [result.position, location], - }) - ); - }); -} - -/** @type {import('./types').RendererApi['drawGameLocations']} */ -function drawGameLocations(locations) { - const map = globalMap; - const icon = makeIcon(); - - locations.forEach((location, index) => { - const locationMarker = makeLocationMarker(location, icon, map, index + 1); - locationMarkers.push(locationMarker); - }); -} - -/** @type {import('./types').RendererApi['drawPlayerResults']} */ -function drawPlayerResults(locations, result) { - const map = globalMap; - const infowindow = new google.maps.InfoWindow(); - const color = result.color || "#fff"; - - clearMarkers(true); - - const icon = makeIcon(); - icon.scale = 1; - icon.fillColor = color; - - result.guesses.forEach((guess, index) => { - if (!guess) return; - - const guessMarker = new google.maps.Marker({ position: guess, icon, map, optimized: true }); - - guessMarker.addListener("mouseover", () => { - infowindow.setContent(` - ${result.flag ? `` : ""} - ${result.username}
- ${result.scores[index]}
- ${toMeter(result.distances[index])} - `); - infowindow.open(map, guessMarker); - }); - guessMarker.addListener("mouseout", () => { - infowindow.close(); - }); - - guessMarkers.push(guessMarker); - - polylines.push( - new google.maps.Polyline({ - strokeColor: color, - strokeWeight: 4, - strokeOpacity: 0.6, - geodesic: true, - map, - path: [guess, locations[index]], - }) - ); - }); -} - -/** - * @returns {google.maps.Symbol} - */ -function makeIcon() { - return { - path: `M13.04,41.77c-0.11-1.29-0.35-3.2-0.99-5.42c-0.91-3.17-4.74-9.54-5.49-10.79c-3.64-6.1-5.46-9.21-5.45-12.07 - c0.03-4.57,2.77-7.72,3.21-8.22c0.52-0.58,4.12-4.47,9.8-4.17c4.73,0.24,7.67,3.23,8.45,4.07c0.47,0.51,3.22,3.61,3.31,8.11 - c0.06,3.01-1.89,6.26-5.78,12.77c-0.18,0.3-4.15,6.95-5.1,10.26c-0.64,2.24-0.89,4.17-1,5.48C13.68,41.78,13.36,41.78,13.04,41.77z`, - fillColor: "#de3e3e", - fillOpacity: 0.7, - scale: 1.2, - strokeColor: "#000", - strokeWeight: 1, - anchor: new google.maps.Point(14, 43), - labelOrigin: new google.maps.Point(13.5, 15), - }; -} - -/** - * @param {Location} location - * @param {google.maps.Symbol} icon - * @param {google.maps.Map} map - * @param {number} index - * @returns {google.maps.Marker} - */ -function makeLocationMarker(location, icon, map, index = null) { - const locationMarker = new google.maps.Marker({ position: location, icon, map, optimized: true }); - if (index) { - locationMarker.setLabel({ - color: "#000", - fontWeight: "bold", - fontSize: "16px", - text: `${index}`, - }); - } - - locationMarker.addListener("click", () => { - const url = new URL("https://www.google.com/maps/@?api=1&map_action=pano"); - if (location.panoId) { - url.searchParams.set("pano", location.panoId); - } - url.searchParams.set("viewpoint", `${location.lat},${location.lng}`); - url.searchParams.set("heading", String(location.heading)); - url.searchParams.set("pitch", String(location.pitch)); - const fov = 180 / 2 ** location.zoom; - url.searchParams.set("fov", String(fov)); - window.open(url.href, "_blank"); - }); - - return locationMarker; -} - -/** @type {import('./types').RendererApi['clearMarkers']} */ -function clearMarkers(keepLocationMarkers = false) { - for (const marker of guessMarkers) { - marker.setMap(null); - } - for (const line of polylines) { - line.setMap(null); - } - guessMarkers = []; - polylines = []; - - if (!keepLocationMarkers) { - for (const marker of locationMarkers) { - marker.setMap(null); - } - locationMarkers = []; - } -} - -async function hijackMap() { - const MAPS_API_URL = "https://maps.googleapis.com/maps/api/js?"; - const MAPS_SCRIPT_SELECTOR = `script[src^="${MAPS_API_URL}"]`; - await new Promise((resolve) => { - let bodyDone = false; - let headDone = false; - - function checkBodyDone() { - if (!bodyDone && document.body) { - scriptObserver.observe(document.body, { childList: true }); - bodyDone = true; - } - } - function checkHeadDone() { - if (!headDone && document.head) { - scriptObserver.observe(document.head, { childList: true }); - headDone = true; - } - } - - /** - * Check if `element` is a Google Maps script tag and resolve the outer Promise if so. - * @param {Element} element - */ - function checkMapsScript(element) { - if (element.matches(MAPS_SCRIPT_SELECTOR)) { - const onload = () => { - pageObserver.disconnect(); - scriptObserver.disconnect(); - resolve(undefined); - }; - // It may already be loaded :O - if (typeof google !== "undefined" && google?.maps?.Map) { - onload(); - } else { - element.addEventListener("load", onload); - } - } - } - - const scriptObserver = new MutationObserver((mutations, observer) => { - for (const mutation of mutations) { - for (const tmp of mutation.addedNodes) { - if (tmp.nodeType === Node.ELEMENT_NODE) { - checkMapsScript(/** @type {Element} */ (tmp)); - } - } - } - }); - const pageObserver = new MutationObserver((_, observer) => { - checkBodyDone(); - checkHeadDone(); - if (headDone && bodyDone) { - observer.disconnect(); - } - }); - - pageObserver.observe(document.documentElement, { - childList: true, - subtree: true, - }); - - // Do an initial check, we may be running in a fully loaded game already. - checkBodyDone(); - checkHeadDone(); - /** @type {HTMLElement|undefined} */ - const existingTag = document.querySelector(MAPS_SCRIPT_SELECTOR); - if (existingTag) checkMapsScript(existingTag); - }); - - await new Promise((resolve, reject) => { - const google = window.google; - const isGamePage = () => location.pathname.startsWith("/results/") || location.pathname.startsWith("/game/"); - /** @param {google.maps.Map} map */ - function onMapUpdate(map) { - try { - if (!isGamePage()) return; - globalMap = map; - resolve(); - } catch (error) { - console.error("GeoguessrHijackMap Error:", error); - reject(error); - } - } - - google.maps.Map = class extends google.maps.Map { - /** - * @param {HTMLElement} mapDiv - * @param {google.maps.MapOptions} opts - */ - constructor(mapDiv, opts) { - super(mapDiv, opts); - this.addListener("idle", () => { - if (globalMap == null) { - onMapUpdate(this); - } - }); - this.addListener("maptypeid_changed", () => { - // Save the map type ID so we can prevent GeoGuessr from resetting it - localStorage.chatguessrMapTypeId = this.getMapTypeId(); - }); - } - /** - * @param {google.maps.MapOptions} opts - */ - setOptions(opts) { - // GeoGuessr's `setOptions` calls always include `backgroundColor` - // so this is how we can distinguish between theirs and ours - if (opts.backgroundColor) { - opts.mapTypeId = localStorage.chatguessrMapTypeId ?? opts.mapTypeId; - opts.mapTypeControl = true; - opts.mapTypeControlOptions = { - style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, - position: google.maps.ControlPosition.TOP_RIGHT, - }; - } - super.setOptions(opts); - } - }; - }); -} - -/** @type {import('./types').RendererApi['showSatelliteMap']} */ -async function showSatelliteMap(location) { - await mapReady; - - const boundsLimit = parseInt(localStorage.getItem("satelliteModeBoundsLimit")) || 10; - - if (!document.body.contains(satelliteCanvas)) { - document.querySelector('[data-qa="panorama"] [aria-label="Map"]').append(satelliteCanvas); - } - satelliteCanvas.style.display = "block"; - - satelliteLayer ??= new google.maps.Map(satelliteCanvas, { - fullscreenControl: false, - mapTypeId: google.maps.MapTypeId.SATELLITE, - }); - satelliteLayer.setOptions({ - restriction: { - latLngBounds: getBounds(location, boundsLimit * 1000), - strictBounds: true, - }, - }); - satelliteLayer.setCenter(location); - satelliteLayer.setZoom(20); - satelliteMarker?.setMap(null); - satelliteMarker = new google.maps.Marker({ - position: location, - map: satelliteLayer, - }); -} - -/** @type {import('./types').RendererApi['hideSatelliteMap']} */ -async function hideSatelliteMap() { - await mapReady; - satelliteCanvas.style.display = "none"; -} - -/** @type {import('./types').RendererApi['centerSatelliteView']} */ -function centerSatelliteView(location) { - satelliteLayer.setCenter(location); -} - -/** @type {import('./types').RendererApi['focusOnGuess']} */ -function focusOnGuess(location) { - globalMap.setCenter(location); - globalMap.setZoom(8); -} - -/** @type {import('./types').RendererApi['getBounds']} */ -function getBounds(location, limit) { - const meters = limit / 2; - const earth = 6371.071; - const pi = Math.PI; - const cos = Math.cos; - const m = 1 / (((2 * pi) / 360) * earth) / 1000; - - const north = location.lat + meters * m; - const south = location.lat - meters * m; - const west = location.lng - (meters * m) / cos(location.lat * (pi / 180)); - const east = location.lng + (meters * m) / cos(location.lat * (pi / 180)); - - return { north, south, west, east }; -} - -/** - * @param {number} distance - */ -function toMeter(distance) { - return distance >= 1 ? distance.toFixed(1) + "km" : Math.floor(distance * 1000) + "m"; -} - -start(); diff --git a/src/renderer/assets/extenssr-styles.css b/src/renderer/assets/extenssr-styles.css new file mode 100644 index 0000000..58b7ba3 --- /dev/null +++ b/src/renderer/assets/extenssr-styles.css @@ -0,0 +1,37 @@ +/* Adapted from https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/css/styles.css */ + +/* shortcut menu items */ +.extenssr__nav-submenu { + z-index: 55; + position: absolute; + top: 3rem; + padding: 0.375rem 0; + border-radius: 0.5rem; + max-width: 300px; + background: var(--ds-color-black-80); + list-style-type: none; +} + +.extenssr__nav-submenu li { + box-sizing: border-box; + width: 100%; + white-space: nowrap; + padding: 0; + margin: 0; +} + +.extenssr__nav-submenu a { + box-sizing: border-box; + display: inline-block; + width: 100%; + padding: 0.25rem 1rem 0.25rem 1rem; + color: #fff; + opacity: 0.6; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.extenssr__nav-submenu a:hover { + opacity: 1; + text-decoration: none; +} diff --git a/assets/fonts/montserrat-regular-webfont.woff2 b/src/renderer/assets/fonts/montserrat-regular-webfont.woff2 similarity index 100% rename from assets/fonts/montserrat-regular-webfont.woff2 rename to src/renderer/assets/fonts/montserrat-regular-webfont.woff2 diff --git a/src/renderer/assets/icons/audio.svg b/src/renderer/assets/icons/audio.svg new file mode 100644 index 0000000..bf051a0 --- /dev/null +++ b/src/renderer/assets/icons/audio.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/auto_scroll.svg b/src/renderer/assets/icons/auto_scroll.svg new file mode 100644 index 0000000..d43b68a --- /dev/null +++ b/src/renderer/assets/icons/auto_scroll.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/cg_icon.svg b/src/renderer/assets/icons/cg_icon.svg new file mode 100644 index 0000000..6fd2b38 --- /dev/null +++ b/src/renderer/assets/icons/cg_icon.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/gear.svg b/src/renderer/assets/icons/gear.svg new file mode 100644 index 0000000..0a06d42 --- /dev/null +++ b/src/renderer/assets/icons/gear.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/gear_stroke.svg b/src/renderer/assets/icons/gear_stroke.svg new file mode 100644 index 0000000..d2bfe25 --- /dev/null +++ b/src/renderer/assets/icons/gear_stroke.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/pause.svg b/src/renderer/assets/icons/pause.svg new file mode 100644 index 0000000..1885683 --- /dev/null +++ b/src/renderer/assets/icons/pause.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/scoreboard_hidden.svg b/src/renderer/assets/icons/scoreboard_hidden.svg new file mode 100644 index 0000000..cf78f1a --- /dev/null +++ b/src/renderer/assets/icons/scoreboard_hidden.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/scoreboard_visible.svg b/src/renderer/assets/icons/scoreboard_visible.svg new file mode 100644 index 0000000..cf6afe6 --- /dev/null +++ b/src/renderer/assets/icons/scoreboard_visible.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/start.svg b/src/renderer/assets/icons/start.svg new file mode 100644 index 0000000..83d486b --- /dev/null +++ b/src/renderer/assets/icons/start.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/start_flag.svg b/src/renderer/assets/icons/start_flag.svg new file mode 100644 index 0000000..8c204c2 --- /dev/null +++ b/src/renderer/assets/icons/start_flag.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/stop.svg b/src/renderer/assets/icons/stop.svg new file mode 100644 index 0000000..6ff04ef --- /dev/null +++ b/src/renderer/assets/icons/stop.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/timer_hidden.svg b/src/renderer/assets/icons/timer_hidden.svg new file mode 100644 index 0000000..bdaac22 --- /dev/null +++ b/src/renderer/assets/icons/timer_hidden.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/timer_visible.svg b/src/renderer/assets/icons/timer_visible.svg new file mode 100644 index 0000000..6c6ff48 --- /dev/null +++ b/src/renderer/assets/icons/timer_visible.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/icons/twitch.svg b/src/renderer/assets/icons/twitch.svg new file mode 100644 index 0000000..125a3bc --- /dev/null +++ b/src/renderer/assets/icons/twitch.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/override-gg-styles.css b/src/renderer/assets/override-gg-styles.css new file mode 100644 index 0000000..1d17873 --- /dev/null +++ b/src/renderer/assets/override-gg-styles.css @@ -0,0 +1,151 @@ +/* GAME SETTINGS SCREEN */ +[data-qa='game-type-challenge'], +[data-qa='game-type-single-player'] { + display: none !important; +} + +[class^='play_map__'] { + height: 9rem !important; +} +[class^='start-standard-game_body__'] { + margin-top: 0 !important; +} + +/* Hides friends list bar */ +[class^='version4_sidebar__'] { + display: none; +} +[class^='version4_content__'] { + max-width: 100% !important; +} + +/* Hide promo and daily challenge from menu */ +[class^='header_promoDealButtonWrapper'] { + display: none !important; +} + +[class^='header_context__'] > :nth-child(3) { + display: none !important; +} +[class^='header_loginButton__'] { + display: block !important; +} + +/* Hide Return to Home Top Left menu */ +[class^='header_mainNavigation__'] { + display: none !important; +} + +/* Hide community page menu links */ +[class^='community-navigation_tabsWrapper__'] a:not([href='/community/maps']) { + display: none; +} + +/* Hide results overlay */ +[class^='result-overlay_overlay__'], +[class^='result-overlay_overlayContent__'], +[class^='result-overlay_overlayXpBar__'], +[class^='result-layout_adWrapper__'], +[class^='standard-final-result_challengeWrapper__'] { + display: none !important; +} + +[class^='styles_friendChatButton__'] { + display: none; +} + +/* removes game breakdown button */ +[class^='standard-final-result_wrapper__'] > div:first-child { + display: none; +} +[class^='round-indicator_roundIndicator__'] { + width: 150px; +} + +/* CG Guess Markers InfoWindow */ +[data-qa="correct-location-marker"] { + position: relative; + z-index: 999; +} + +.gm-style .gm-style-iw-c, +.gm-style .gm-style-iw-tc::after { + background: rgba(0, 0, 0, 0.5) !important; +} + +.gm-style .gm-style-iw-c { + padding: 6px 8px !important; +} + +.gm-style .gm-style-iw-d { + overflow: auto !important; + color: #ffffff; + text-align: center; + font-weight: 700; +} +.gm-style-iw-d .username { + font-weight: 400; +} +.gm-ui-hover-effect { + display: none !important; +} + +.gm-style .gm-style-iw-d::-webkit-scrollbar-track, +.gm-style .gm-style-iw-d::-webkit-scrollbar-track-piece { + background: transparent !important; +} +.gm-style-cc, +#satelliteCanvas .gmnoprint { + display: none; +} + +.guess-map__canvas > div > div { + background: rgba(0, 0, 0, 0.5) !important; +} +.gm-style-mtc :is(button, ul, li) { + background: rgba(0, 0, 0, 0.5) !important; + color: #fff !important; +} +.gm-style-mtc img { + background: #22da8d !important; +} +.ssQIHO-checkbox-menu-item span span { + background-color: #fff !important; +} + +/* CUSTOM SCRIPTS UI */ +[class^='start-standard-game_settings__'] { + margin-top: 0; +} + +.custom-slider { + -webkit-appearance: none; + width: 100%; + height: 0.5rem; + border-radius: 0.625rem; + background: #a19bd9; + margin: 1.25rem 0; + padding: 0; + border: none; + outline: none; + -webkit-transition: 0.2s; + transition: opacity 0.2s; +} +.custom-slider::-webkit-slider-thumb { + -webkit-appearance: none; + box-shadow: inset 0 0.0625rem 0 0 #a19bd9; + appearance: none; + width: 1.5rem; + height: 1.5rem; + border-radius: 50%; + background: #7950e5; + cursor: pointer; +} +.custom-slider::-moz-range-thumb { + box-shadow: inset 0 0.0625rem 0 0 #a19bd9; + width: 1.5rem; + height: 1.5rem; + border-radius: 50%; + background: #7950e5; + cursor: pointer; +} diff --git a/src/renderer/assets/styles.css b/src/renderer/assets/styles.css new file mode 100644 index 0000000..6d758cf --- /dev/null +++ b/src/renderer/assets/styles.css @@ -0,0 +1,271 @@ +@import './override-gg-styles.css'; +@import './extenssr-styles.css'; +@import './utilities.css'; + +*, +*::before, +*::after { + box-sizing: border-box; +} + +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + src: url(./fonts/montserrat-regular-webfont.woff2) format('woff2'); +} + +h2, +h3 { + margin: 0.8rem 0; +} + +hr { + width: 80%; + height: 1px; + margin: 0.5rem auto; + background-color: var(--primary); + border: none; +} + +small { + font-size: 0.8rem; +} + +#satelliteCanvas { + display: none; + width: 100%; + height: 100%; + z-index: 9; +} + +.hidden { + visibility: hidden; +} + +.form__group { + display: flex; + align-items: center; + justify-content: space-between; + height: 24px; + margin-bottom: 0.3rem; +} + +.form__group input, +.form__group select { + padding: 0; + height: 24px; + font-family: inherit; + font-size: inherit; + font-weight: 700; + text-align: center; + color: #ffffff; + background: rgba(255, 255, 255, 0.2); + border-radius: 4px; + outline: 0; + cursor: pointer; +} + +.form__group input:hover, +.form__group select:hover { + filter: brightness(120%); +} + +.form__group input[type='color'] { + padding: 1px 2px; +} + +.form__group input[type='text'], +.form__group input[type='range'], +.form__group select { + width: 150px; +} + +.form__group input[type='text'], +.form__group select { + border: unset; + border-bottom: 1px solid var(--primary); +} + +.form__group input[type='range'] { + -webkit-appearance: none; + appearance: none; + background: transparent; + border: none; +} + +.form__group input[type='range']::-webkit-slider-runnable-track { + background: rgb(209, 209, 209); + border-radius: 4px; + height: 0.5rem; +} + +.form__group input[type='range']::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + height: 14px; + width: 14px; + margin-top: -3px; + border-radius: 50%; + background-color: var(--primary); +} + +.form__group input[type='checkbox'] { + -webkit-appearance: none; + appearance: none; + margin: 0; + color: var(--primary); + width: 1.15rem; + height: 1.15rem; + border: 1px solid var(--primary); + border-radius: 2px; + display: grid; + place-content: center; + outline: none; +} + +.form__group input[type='checkbox']::before { + content: ''; + width: 0.65rem; + height: 0.65rem; + clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); + transform: scale(0); + transform-origin: bottom left; + transition: 120ms transform ease-in-out; + box-shadow: inset 1em 1em var(--primary); +} + +.form__group input[type='checkbox']:checked::before { + transform: scale(1); +} + +.form__group select option { + background: rgba(0, 0, 0, 0.8); +} + +.form__group select::-webkit-scrollbar { + width: 10px; +} + +.form__group select::-webkit-scrollbar-track { + border-radius: 10px; +} + +.form__group select::-webkit-scrollbar-thumb { + background: var(--primary); +} + +textarea { + width: -webkit-fill-available; + resize: vertical; + font-family: inherit; + font-size: inherit; + font-weight: 700; + padding: 0.5rem; + color: #ffffff; + background: rgba(0, 0, 0, 0.5); + border-radius: 5px; + outline: 0; +} +textarea:focus { + border: 1px solid var(--primary); +} + +.form__group .btn { + height: 24px; + padding: 0 0.5rem; +} + +.btn { + font-family: inherit; + font-size: inherit; + line-height: 1; + padding: 0.5rem; + border-radius: 3px; + cursor: pointer; +} +.btn:hover:not([disabled]) { + opacity: 0.9; +} +.btn:active:not([disabled]) { + opacity: 0.8; +} +.btn[disabled] { + cursor: not-allowed; + color: rgb(157, 157, 157); + background-color: rgb(91, 91, 91); +} + +.flag-icon { + background-size: contain; + background-position: 50%; + background-repeat: no-repeat; + position: relative; + display: inline-block; + width: 1.33333333em; +} + +.flag-icon:before { + content: '\00a0'; +} + +/* These Scoreboard styles cannot be scoped in so we put em in here */ +.scoreboard_handle { + display: block !important; + background: none; + border: none; +} +.scoreboard_handle-tm, +.scoreboard_handle-bm { + height: 12px; + width: 100%; + left: 0; + margin: 0; +} +.scoreboard_handle-ml, +.scoreboard_handle-mr { + width: 12px; + height: 100%; + top: 0; + margin: 0; +} +.scoreboard_handle-tl, +.scoreboard_handle-tr, +.scoreboard_handle-bl, +.scoreboard_handle-br { + width: 12px; + height: 12px; + z-index: 99; +} + +/* GLOBAL MAP RENDERER */ +/* Small trick to select guess marker avatars cause we cannot add CSS class to google.maps.Marker */ +img[src$="#custom_marker"]{ + border: 2px solid white !important; + border-radius: 50%; +} + +.guess-marker-label { + background-color: white; + border-radius: 50%; + font-size: 10px !important; + font-weight: bold; + width: 13px; + height: 13px; +} + +.username, +.gm-style-iw-d .username { + padding: 3px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 15px; + text-shadow: + rgb(0 0 0) 1px 1px 0px, + rgb(255 255 255) 1px 1px 3px; +} +.gm-style-iw-d .username { + font-size: 16px; + font-weight: bold; +} diff --git a/src/renderer/assets/utilities.css b/src/renderer/assets/utilities.css new file mode 100644 index 0000000..9626462 --- /dev/null +++ b/src/renderer/assets/utilities.css @@ -0,0 +1,90 @@ +/******** COLORS ********/ +:root { + --primary: #59f3b3; + --danger: #f0625d; + --warning: #ffae00; + --bg-dark-transparent: rgba(0, 0, 0, 0.4); + /* --danger-hover: #e05e59; + --danger-active: #d35854; */ +} +.primary { + color: var(--primary); +} +.bg-primary { + background: var(--primary); +} +/* .bg-primary:hover:not([disabled]) { + background: #56ca90; +} +.bg-primary:active:not([disabled]) { + background: #4eb883; +} */ +.danger { + color: var(--danger); +} +.bg-danger { + background: var(--danger); +} +/* .bg-danger:hover::not([disabled]) { + background: var(--danger-hover); +} +.bg-danger:active:not([disabled]) { + background: var(--danger-active); +} */ +.warning { + color: var(--warning); +} +.bg-warning { + background: var(--warning); +} +/* .bg-warning:hover:not([disabled]) { + background: #e49c00; +} +.bg-warning:active:not([disabled]) { + background: #c28400; +} */ + +/******** SPACING ********/ +.flex { + display: flex; + align-items: center; +} +.flex-col { + flex-direction: column; +} +.flex-center { + justify-content: center; +} +.flex-wrap { + flex-wrap: wrap; +} +.mt-1 { + margin-top: 1rem; +} +.mx-1 { + margin: 1rem 0; +} +.mr-04 { + margin-right: 0.4rem; +} +.ml-05 { + margin-left: 0.5rem; +} +.mb-05 { + margin-bottom: 0.5rem; +} +.mb-1 { + margin-bottom: 1rem; +} +.gap-02 { + gap: 0.2rem; +} +.gap-03 { + gap: 0.3rem; +} +.gap-05 { + gap: 0.5rem; +} +.gap-1 { + gap: 1rem; +} diff --git a/src/renderer/components/Frame.vue b/src/renderer/components/Frame.vue new file mode 100644 index 0000000..83494ad --- /dev/null +++ b/src/renderer/components/Frame.vue @@ -0,0 +1,373 @@ + + + + + diff --git a/src/renderer/components/Scoreboard.vue b/src/renderer/components/Scoreboard.vue new file mode 100644 index 0000000..adab309 --- /dev/null +++ b/src/renderer/components/Scoreboard.vue @@ -0,0 +1,677 @@ + + + + + diff --git a/src/renderer/components/Settings.vue b/src/renderer/components/Settings.vue new file mode 100644 index 0000000..b4aeaea --- /dev/null +++ b/src/renderer/components/Settings.vue @@ -0,0 +1,483 @@ + + + + diff --git a/src/renderer/components/Timer.vue b/src/renderer/components/Timer.vue new file mode 100644 index 0000000..70ce65e --- /dev/null +++ b/src/renderer/components/Timer.vue @@ -0,0 +1,520 @@ + + + + + diff --git a/src/renderer/mods/blinkMode.ts b/src/renderer/mods/blinkMode.ts new file mode 100644 index 0000000..cf11e1a --- /dev/null +++ b/src/renderer/mods/blinkMode.ts @@ -0,0 +1,171 @@ +// Adapted from: https://greasyfork.org/en/scripts/438579-geoguessr-blink-mode +import { getLocalStorage, setLocalStorage } from '../useLocalStorage' +;(function blinkMode() { + const settings = getLocalStorage('cg_blinkMode__settings', { + enabled: false, + timeLimit: 0.8, + roundDelay: 1 + }) + + window.toggleBlinkMode = (el) => { + settings.enabled = el.checked + setLocalStorage('cg_blinkMode__settings', settings) + if (!el.checked) { + try { + showPanoramaCached() + } catch {} + } + } + + window.changeBlinkTime = (el) => { + if (!isNaN(Number(el.value))) { + settings.timeLimit = parseFloat(el.value) + setLocalStorage('cg_blinkMode__settings', settings) + document.getElementById('blinkTimeText')!.textContent = el.value + ' sec' + } + } + + window.changeDelayTime = (el) => { + if (!isNaN(Number(el.value))) { + settings.roundDelay = parseFloat(el.value) + setLocalStorage('cg_blinkMode__settings', settings) + document.getElementById('delayTimeText')!.textContent = el.value + ' sec' + } + } + + const classicGameGuiHTML: string = ` +
+
+
+

Blink Mode settings

+
+
+
+
+
+
+
+ Enabled + +
+
+ +
+
+ +
+
+
+
+ ` + + const checkInsertGui = () => { + if ( + document.querySelector('.radio-box_root__ka_9S') && + document.getElementById('enableScript') === null + ) { + document + .querySelector('.section_sectionMedium__yXgE6') + ?.insertAdjacentHTML('beforeend', classicGameGuiHTML) + + if (settings.enabled) { + ;(document.getElementById('enableScript') as HTMLInputElement).checked = true + } + + ;(document.getElementById('blinkTime') as HTMLInputElement).value = + settings.timeLimit.toString() + ;(document.getElementById('delayTime') as HTMLInputElement).value = + settings.roundDelay.toString() + document.getElementById('blinkTimeText')!.textContent = settings.timeLimit + ' sec' + document.getElementById('delayTimeText')!.textContent = settings.roundDelay + ' sec' + } + } + + let mapRoot: HTMLElement | null = null + function getMapRoot() { + return document.querySelector('[data-qa=panorama]') as HTMLElement + } + + function hidePanorama() { + mapRoot = getMapRoot() || mapRoot + hidePanoramaCached() + } + + function hidePanoramaCached() { + mapRoot!.style.filter = 'brightness(0%)' + } + + function showPanorama() { + mapRoot = getMapRoot() || mapRoot + showPanoramaCached() + } + + function showPanoramaCached() { + mapRoot!.style.filter = 'brightness(100%)' + } + + function isLoading() { + return ( + document.querySelector('[class^="fullscreen-spinner_root__"]') || + !document.querySelector('.widget-scene-canvas') + ) + } + + let wasBackdropThereOrLoading = false + function isBackdropThereOrLoading() { + return isLoading() || document.querySelector('[class^="result-layout_root__"]') + } + + let showTimeoutID: NodeJS.Timeout + let hideTimeoutID: NodeJS.Timeout + function triggerBlink() { + hidePanorama() + clearTimeout(showTimeoutID) + showTimeoutID = setTimeout(showPanorama, settings.roundDelay * 1000) + clearTimeout(hideTimeoutID) + hideTimeoutID = setTimeout(hidePanorama, (settings.timeLimit + settings.roundDelay) * 1000) + } + + const observer = new MutationObserver(() => { + checkInsertGui() + + if (settings.enabled) { + if (isBackdropThereOrLoading()) { + wasBackdropThereOrLoading = true + if (!isLoading()) hidePanorama() + } else if (wasBackdropThereOrLoading) { + wasBackdropThereOrLoading = false + triggerBlink() + } + } + }) + + observer.observe(document.body, { + subtree: true, + childList: true + }) +})() diff --git a/src/renderer/mods/env.d.ts b/src/renderer/mods/env.d.ts new file mode 100644 index 0000000..154d82e --- /dev/null +++ b/src/renderer/mods/env.d.ts @@ -0,0 +1,9 @@ +interface Window { + toggleNoCarMode: (el: HTMLInputElement) => void + toggleNoCompassMode: (el: HTMLInputElement) => void + toggleBlinkMode: (el: HTMLInputElement) => void + changeBlinkTime: (el: HTMLInputElement) => void + changeDelayTime: (el: HTMLInputElement) => void + toggleSatelliteMode: (el: HTMLInputElement) => void + changeBoundsLimit: (el: HTMLInputElement) => void +} diff --git a/src/renderer/mods/extenssrMenuItemsPlugin.ts b/src/renderer/mods/extenssrMenuItemsPlugin.ts new file mode 100644 index 0000000..4546474 --- /dev/null +++ b/src/renderer/mods/extenssrMenuItemsPlugin.ts @@ -0,0 +1,242 @@ +// Adapted from: +// https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/src/api/maps.ts +// https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/src/content_scripts/plugins/global/menu_items_plugin.ts +// https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/src/content_scripts/endpoint_transition_handler.ts + +import axios from 'axios' + +type MapCreator = { + email?: string + nick: string +} + +type Map = { + id: string + name: string + slug: string + description?: string + url?: string + playUrl?: string + creator?: MapCreator +} + +class MapsApi { + private client = axios.create({ baseURL: 'https://www.geoguessr.com' }) + + async getMapData(mapId: string): Promise { + return (await this.client.get(`/api/maps/${mapId}`)).data + } + + async getMyMaps(page = 0, count = 25): Promise { + const { data } = await this.client.get('/api/v3/profiles/maps', { + params: { page, count } + }) + + return data + } + + async getLikedMaps(page = 0, count = 25): Promise { + const { data } = await this.client.get('/api/v3/likes', { + params: { page, count } + }) + + return data + } +} + +const DESELECTED_MENU_ITEM_SELECTOR = 'header nav li:not([class*="selected"])' + +const customMenuItemTemplate = document.createElement('div') +customMenuItemTemplate.append(document.createElement('a')) +Object.assign(customMenuItemTemplate.style, { + display: 'flex', + flex: '0 0 auto', + height: '100%' +}) +Object.assign(customMenuItemTemplate.querySelector('a')!.style, { + color: 'white', + fontWeight: '700', + padding: '1rem', + display: 'block', + textTransform: 'uppercase' +}) + +type SubMenuItem = { + href: string + textContent: string +} + +export default class MenuItemsPlugin { + private api: MapsApi | undefined + private myMaps: Map[] | undefined + private likedMaps: Map[] | undefined + private observer: MutationObserver | undefined | null + private initialLoad = true + + constructor() { + this.api = new MapsApi() + } + + onEndpointChange(path: string): void { + // In-game screens have no `
` element + const header = document.querySelector('header') + if (document.querySelector('[data-qa="extenssr__nav-item"]') || !header) { + return + } + + // We might inject before the React tree hydrates, in that case React will remove our + // injected elements again, so we need to add them back. + if (this.initialLoad) { + this.initialLoad = false + this.observer = new MutationObserver(() => { + queueMicrotask(() => this.onEndpointChange(path)) + }) + this.observer.observe(header, { childList: true, subtree: true }) + } else if (this.observer) { + this.observer.disconnect() + this.observer = null + } + + const referenceElement = + (document.querySelector(DESELECTED_MENU_ITEM_SELECTOR) as HTMLLIElement) ?? + customMenuItemTemplate + const container = + referenceElement.closest('ol') ?? + document.querySelector('[data-qa="header-current-user-pin"]')?.parentNode + + const createMenuItem = (props: { + href: string + textContent: string + subMenu?: () => Promise + }) => { + const li = referenceElement.cloneNode(true) as HTMLLIElement + li.setAttribute('data-qa', 'extenssr__nav-item') + + const { href, textContent } = props + Object.assign(li.querySelector('a')!, { href, textContent }) + + if (props.subMenu) { + const overflows = [ + container?.parentNode, + container?.parentNode?.parentNode + ] as HTMLDivElement[] + + let controller: AbortController | null + li.addEventListener('mouseenter', () => { + controller = new AbortController() + this.showMenu(li, props.subMenu!, controller.signal) + for (const el of overflows) { + el.style.overflow = 'visible' + } + }) + li.addEventListener('mouseleave', () => { + controller?.abort() + controller = null + li.querySelector('[data-qa="extenssr__nav-submenu"]')?.remove() + for (const el of overflows) { + el.style.overflow = '' + } + }) + } + + return li + } + + const communityMaps = createMenuItem({ + href: '/community/maps', + textContent: 'Community Maps' + }) + + const myMaps = createMenuItem({ + href: '/me/maps', + textContent: 'My Maps', + // @ts-expect-error + subMenu: async () => { + this.myMaps ??= await this.api?.getMyMaps(0, 25) + const maps = this.myMaps?.map((map: Map) => ({ + href: map.url, + textContent: map.name + })) + return maps + } + }) + + const likedMaps = createMenuItem({ + href: '/me/likes', + textContent: 'Liked Maps', + // @ts-expect-error + subMenu: async () => { + this.likedMaps ??= await this.api?.getLikedMaps(0, 25) + return this.likedMaps?.map((map: Map) => ({ + href: map.url, + textContent: map.name + })) + } + }) + + if (referenceElement.tagName === 'LI') { + container?.append(communityMaps, myMaps, likedMaps) + } else { + container?.insertBefore( + likedMaps, + document.querySelector('[data-qa="header-current-user-pin"]') + ) + container?.insertBefore(myMaps, likedMaps) + container?.insertBefore(communityMaps, myMaps) + } + } + + private showMenu( + reference: HTMLElement, + items: () => Promise, + signal: AbortSignal + ) { + const subMenu = document.createElement('ol') + subMenu.classList.add('extenssr__nav-submenu') + subMenu.setAttribute('data-qa', 'extenssr__nav-submenu') + + items().then((list) => { + subMenu.replaceChildren() + subMenu.append( + ...list.map((item) => { + const li = document.createElement('li') + const a = document.createElement('a') + Object.assign(a, item) + li.append(a) + return li + }) + ) + + if (!signal.aborted) { + reference.append(subMenu) + } + }) + } +} + +const plugin = new MenuItemsPlugin() +observeNavigation() + +function observeNavigation() { + const pathChange = () => plugin.onEndpointChange(window.location.pathname) + + const observer = new MutationObserver((mutations: MutationRecord[]) => { + for (const mutation of mutations) { + for (const addition of mutation.addedNodes) { + if (addition.nodeType !== Node.ELEMENT_NODE) { + continue + } + const element = addition as HTMLElement + if (element && element.getAttribute('property') === 'og:url') { + pathChange() + return + } + } + } + }) + observer.observe(document.head, { + childList: true, + subtree: true + }) + pathChange() +} diff --git a/src/renderer/mods/noCarNoCompass.ts b/src/renderer/mods/noCarNoCompass.ts new file mode 100644 index 0000000..b5ef7e6 --- /dev/null +++ b/src/renderer/mods/noCarNoCompass.ts @@ -0,0 +1,172 @@ +// Adapted from : https://openuserjs.org/scripts/drparse/GeoNoCar +// @ts-nocheck +import { getLocalStorage, setLocalStorage } from '../useLocalStorage' +;(function noCarNoCompass() { + const settings = getLocalStorage('cg_ncnc__settings', { + noCar: false, + noCompass: false + }) + + const compassRemover = document.createElement('style') + const REMOVE_COMPASS_CSS = '[data-qa="compass"], [class^="panorama-compass_"] { display: none; }' + compassRemover.textContent = REMOVE_COMPASS_CSS + + if (settings.noCar) { + noCarScript() + } + + if (settings.noCompass) { + document.head.append(compassRemover) + } + + window.toggleNoCarMode = (el) => { + settings.noCar = el.checked + setLocalStorage('cg_ncnc__settings', settings) + location.reload() + } + + window.toggleNoCompassMode = (el) => { + settings.noCompass = el.checked + setLocalStorage('cg_ncnc__settings', settings) + if (el.checked) { + document.head.append(compassRemover) + } else { + compassRemover.remove() + } + } + + const classicGameGuiHTML = ` +
+
+
+

NCNC settings

+
+
+
+
+
+
+ No car + +
+
+ No compass + +
+
+
+ ` + + const checkInsertGui = () => { + if ( + document.querySelector('[class^="radio-box_root__"]') && + document.querySelector('#enableNoCar') === null + ) { + document + .querySelector('[class^="section_sectionMedium__"]') + ?.insertAdjacentHTML('beforeend', classicGameGuiHTML) + + if (settings.noCar) { + ;(document.querySelector('#enableNoCar') as HTMLInputElement).checked = true + } + + if (settings.noCompass) { + ;(document.querySelector('#enableNoCompass') as HTMLInputElement).checked = true + } + } + } + + const observer = new MutationObserver(() => { + checkInsertGui() + }) + + observer.observe(document.body, { + subtree: true, + childList: true + }) +})() + +function noCarScript() { + const OPTIONS = { colorR: 0.5, colorG: 0.5, colorB: 0.5 } + const vertexOld = + 'const float f=3.1415926;varying vec3 a;uniform vec4 b;attribute vec3 c;attribute vec2 d;uniform mat4 e;void main(){vec4 g=vec4(c,1);gl_Position=e*g;a=vec3(d.xy*b.xy+b.zw,1);a*=length(c);}' + const fragOld = + 'precision highp float;const float h=3.1415926;varying vec3 a;uniform vec4 b;uniform float f;uniform sampler2D g;void main(){vec4 i=vec4(texture2DProj(g,a).rgb,f);gl_FragColor=i;}' + const vertexNew = ` + const float f=3.1415926; + varying vec3 a; + varying vec3 potato; + uniform vec4 b; + attribute vec3 c; + attribute vec2 d; + uniform mat4 e; + void main(){ + vec4 g=vec4(c,1); + gl_Position=e*g; + a = vec3(d.xy * b.xy + b.zw,1); + a *= length(c); + potato = vec3(d.xy, 1.0) * length(c); + } + ` + const fragNew = ` + precision highp float; + const float h=3.1415926; + varying vec3 a; + varying vec3 potato; + uniform vec4 b; + uniform float f; + uniform sampler2D g; + void main(){ + vec2 aD = potato.xy / a.z; + float thetaD = aD.y; + float thresholdD1 = 0.6; + float thresholdD2 = 0.7; + float x = aD.x; + float y = abs(4.0*x - 2.0); + float phiD = smoothstep(0.0, 1.0, y > 1.0 ? 2.0 - y : y); + vec4 i = vec4(thetaD > mix(thresholdD1, thresholdD2, phiD) + ? vec3(float(${OPTIONS.colorR}), float(${OPTIONS.colorG}), float(${OPTIONS.colorB})) // texture2DProj(g,a).rgb * 0.25 + : texture2DProj(g,a).rgb,f); + gl_FragColor=i; + } + ` + + function installShaderSource(ctx: WebGLRenderingContext | WebGL2RenderingContext) { + const g = ctx.shaderSource + function shaderSource(...args: WebGLRenderingContext['shaderSource'][]) { + if (typeof args[1] === 'string') { + let glsl: string = args[1] + if (glsl === vertexOld) glsl = vertexNew + else if (glsl === fragOld) glsl = fragNew + return g.call(this, args[0], glsl) + } + return g.apply(this, args) + } + shaderSource.bestcity = 'bintulu' + ctx.shaderSource = shaderSource + } + + function installGetContext(el: HTMLCanvasElement) { + const g = el.getContext + el.getContext = function (...args) { + if (args[0] === 'webgl' || args[0] === 'webgl2') { + const ctx: WebGLRenderingContext | WebGL2RenderingContext = g.apply(this, args) + if (ctx && ctx.shaderSource && ctx.shaderSource.bestcity !== 'bintulu') { + installShaderSource(ctx) + } + return ctx + } + return g.apply(this, args) + } + } + + const createElement = document.createElement.bind(document) + document.createElement = function (tagName: string, options?: ElementCreationOptions) { + if (tagName === 'canvas' || tagName === 'CANVAS') { + const el = createElement('canvas') + installGetContext(el) + return el + } + return createElement(tagName, options) + } +} diff --git a/src/renderer/mods/satelliteMode.ts b/src/renderer/mods/satelliteMode.ts new file mode 100644 index 0000000..9ebf599 --- /dev/null +++ b/src/renderer/mods/satelliteMode.ts @@ -0,0 +1,85 @@ +import { getLocalStorage, setLocalStorage } from '../useLocalStorage' +;(function satelliteMode() { + const settings = getLocalStorage('cg_satelliteMode__settings', { + enabled: false, + boundsLimit: 10 + }) + + window.toggleSatelliteMode = (el) => { + settings.enabled = el.checked + setLocalStorage('cg_satelliteMode__settings', settings) + } + + window.changeBoundsLimit = (el) => { + if (!isNaN(Number(el.value))) { + settings.boundsLimit = parseFloat(el.value) + setLocalStorage('cg_satelliteMode__settings', settings) + document.querySelector('#boundsLimitText')!.textContent = el.value + ' km' + } + } + + const classicGameGuiHTML = ` +
+
+
+

Satellite Mode settings

+
+
+
+
+
+
+ Enabled + +
+
+ +
+
+
+ ` + const checkInsertGui = () => { + if ( + document.querySelector('[class^="radio-box_root__"]') && + document.querySelector('#enableSatelliteMode') === null + ) { + document + .querySelector('[class^="section_sectionMedium__"]') + ?.insertAdjacentHTML('beforeend', classicGameGuiHTML) + + if (settings.enabled) { + ;(document.querySelector('#enableSatelliteMode') as HTMLInputElement).checked = true + } + + ;(document.querySelector('#boundsLimit') as HTMLInputElement).value = + settings.boundsLimit.toString() + document.querySelector('#boundsLimitText')!.textContent = settings.boundsLimit + ' km' + } + } + + const observer = new MutationObserver(() => { + checkInsertGui() + }) + + observer.observe(document.body, { + subtree: true, + childList: true + }) +})() diff --git a/src/renderer/renderer.ts b/src/renderer/renderer.ts new file mode 100644 index 0000000..c7bbdcb --- /dev/null +++ b/src/renderer/renderer.ts @@ -0,0 +1,19 @@ +import { createApp } from 'vue' +import Vue3DraggableResizable from 'vue3-draggable-resizable' +import Frame from './components/Frame.vue' +import './assets/styles.css' + +import './mods/extenssrMenuItemsPlugin' +import './mods/noCarNoCompass' +import './mods/blinkMode' +import './mods/satelliteMode' + +const wrapper = document.createElement('div') +document.body.append(wrapper) + +createApp(Frame) + .use(Vue3DraggableResizable) + .mount(wrapper) + .$nextTick(() => { + postMessage({ payload: 'removeLoading' }, '*') + }) diff --git a/src/renderer/rendererApi.ts b/src/renderer/rendererApi.ts new file mode 100644 index 0000000..f6a78aa --- /dev/null +++ b/src/renderer/rendererApi.ts @@ -0,0 +1,307 @@ +import { getLocalStorage, setLocalStorage } from './useLocalStorage' + +let globalMap: google.maps.Map | undefined = undefined +const mapReady = hijackMap() + +let guessMarkers: google.maps.Marker[] = [] +let polylines: google.maps.Polyline[] = [] + +let satelliteLayer: google.maps.Map | undefined = undefined +let satelliteMarker: google.maps.Marker | undefined = undefined +const satelliteCanvas = document.createElement('div') +satelliteCanvas.id = 'satelliteCanvas' + +function drawRoundResults(location: Location_, roundResults: RoundResult[], limit: number = 100) { + const map = globalMap + const infowindow = new google.maps.InfoWindow() + + roundResults.forEach((result, index) => { + if (index >= limit) return + + const guessMarker = new google.maps.Marker({ + map, + position: result.position, + icon: makeIcon(result.player.avatar), + label: { + className: 'guess-marker-label', + text: `${index + 1}` + }, + optimized: true + }) + guessMarker.addListener('mouseover', () => { + infowindow.setContent(` + ${result.player.flag ? `` : ''} + ${result.player.username}
+ ${result.score}
+ ${toMeter(result.distance)} + `) + infowindow.open(map, guessMarker) + }) + guessMarker.addListener('mouseout', () => { + infowindow.close() + }) + guessMarkers.push(guessMarker) + + polylines.push( + new google.maps.Polyline({ + path: [result.position, location], + map, + strokeColor: result.player.color, + strokeWeight: 4, + strokeOpacity: 0.6, + geodesic: true + }) + ) + }) +} + +function drawPlayerResults(locations: Location_[], result: GameResultDisplay) { + const map = globalMap + clearMarkers() + + const infowindow = new google.maps.InfoWindow() + const icon = makeIcon(result.player.avatar) + + result.guesses.forEach((guess, index) => { + if (!guess) return + // We cannot apply classes if 'optimized' is set to true, anyway it's just 5 markers here + const guessMarker = new google.maps.Marker({ map, position: guess, icon, optimized: false }) + guessMarker.addListener('mouseover', () => { + infowindow.setContent(` + ${result.player.flag ? `` : ''} + ${result.player.username}
+ ${result.scores[index]}
+ ${toMeter(result.distances[index]!)} + `) + infowindow.open(map, guessMarker) + }) + guessMarker.addListener('mouseout', () => { + infowindow.close() + }) + guessMarkers.push(guessMarker) + + polylines.push( + new google.maps.Polyline({ + path: [guess, locations[index]], + map, + strokeColor: result.player.color, + strokeWeight: 4, + strokeOpacity: 0.6, + geodesic: true + }) + ) + }) +} + +function focusOnGuess(location: LatLng) { + if (!globalMap) return + globalMap.setCenter(location) + globalMap.setZoom(8) +} + +function makeIcon(_avatar: string | null): google.maps.Icon { + const avatar = _avatar ?? 'asset:avatar-default.jpg' + return { + url: avatar + '#custom_marker', + scaledSize: new google.maps.Size(32, 32), + anchor: new google.maps.Point(16, 16), + labelOrigin: new google.maps.Point(27, 27) + } +} + +function clearMarkers() { + for (const marker of guessMarkers) { + marker.setMap(null) + } + for (const line of polylines) { + line.setMap(null) + } + guessMarkers = [] + polylines = [] +} + +async function showSatelliteMap(location: LatLng) { + await mapReady + + const satelliteMode = getLocalStorage('cg_satelliteMode__settings', { boundsLimit: 10 }) + + if (!document.body.contains(satelliteCanvas)) { + document.querySelector('[data-qa="panorama"] [aria-label="Map"]')?.append(satelliteCanvas) + } + satelliteCanvas.style.display = 'block' + + satelliteLayer ??= new google.maps.Map(satelliteCanvas, { + fullscreenControl: false, + mapTypeId: google.maps.MapTypeId.SATELLITE + }) + + satelliteLayer.setOptions({ + restriction: { + latLngBounds: getBounds(location, satelliteMode.boundsLimit), + strictBounds: true + } + }) + + satelliteLayer.setCenter(location) + satelliteLayer.setZoom(15) + + satelliteMarker?.setMap(null) + + satelliteMarker = new google.maps.Marker({ + position: location, + map: satelliteLayer + }) +} + +async function hideSatelliteMap() { + await mapReady + satelliteCanvas.style.display = 'none' +} + +function centerSatelliteView(location: LatLng) { + if (!satelliteLayer) return + satelliteLayer.setCenter(location) +} + +function getBounds(location: LatLng, limitInKm: number) { + const meters = (limitInKm * 1000) / 2 + const earth = 6371.071 + const pi = Math.PI + const m = 1 / (((2 * pi) / 360) * earth) / 1000 + + const north = location.lat + meters * m + const south = location.lat - meters * m + const west = location.lng - (meters * m) / Math.cos(location.lat * (pi / 180)) + const east = location.lng + (meters * m) / Math.cos(location.lat * (pi / 180)) + + return { north, south, west, east } +} + +function toMeter(distance: number) { + return distance >= 1 ? distance.toFixed(1) + 'km' : Math.floor(distance * 1000) + 'm' +} + +async function hijackMap() { + const MAPS_API_URL = 'https://maps.googleapis.com/maps/api/js?' + const MAPS_SCRIPT_SELECTOR = `script[src^="${MAPS_API_URL}"]` + await new Promise((resolve) => { + let bodyDone = false + let headDone = false + + function checkBodyDone() { + if (!bodyDone && document.body) { + scriptObserver.observe(document.body, { childList: true }) + bodyDone = true + } + } + function checkHeadDone() { + if (!headDone && document.head) { + scriptObserver.observe(document.head, { childList: true }) + headDone = true + } + } + + /** + * Check if `element` is a Google Maps script tag and resolve the outer Promise if so. + */ + function checkMapsScript(element: Element) { + if (element.matches(MAPS_SCRIPT_SELECTOR)) { + const onload = () => { + pageObserver.disconnect() + scriptObserver.disconnect() + resolve(undefined) + } + // It may already be loaded :O + if (typeof google !== 'undefined' && google?.maps?.Map) { + onload() + } else { + element.addEventListener('load', onload) + } + } + } + + const scriptObserver = new MutationObserver((mutations) => { + for (const mutation of mutations) { + for (const tmp of mutation.addedNodes) { + if (tmp.nodeType === Node.ELEMENT_NODE) { + checkMapsScript(tmp as Element) + } + } + } + }) + const pageObserver = new MutationObserver((_, observer) => { + checkBodyDone() + checkHeadDone() + if (headDone && bodyDone) { + observer.disconnect() + } + }) + + pageObserver.observe(document.documentElement, { + childList: true, + subtree: true + }) + + // Do an initial check, we may be running in a fully loaded game already. + checkBodyDone() + checkHeadDone() + const existingTag: HTMLElement | null = document.querySelector(MAPS_SCRIPT_SELECTOR) + if (existingTag) checkMapsScript(existingTag) + }) + + await new Promise((resolve, reject) => { + const google = window.google + const isGamePage = () => + location.pathname.startsWith('/results/') || location.pathname.startsWith('/game/') + + function onMapUpdate(map: google.maps.Map) { + try { + if (!isGamePage()) return + globalMap = map + resolve() + } catch (err) { + console.error('GeoguessrHijackMap Error:', err) + reject(err) + } + } + + google.maps.Map = class extends google.maps.Map { + constructor(mapDiv: HTMLElement, opts: google.maps.MapOptions) { + super(mapDiv, opts) + this.addListener('idle', () => { + if (globalMap == null) { + onMapUpdate(this) + } + }) + this.addListener('maptypeid_changed', () => { + // Save the map type ID so we can prevent GeoGuessr from resetting it + setLocalStorage('cg_MapTypeId', this.getMapTypeId()) + }) + } + + setOptions(opts: google.maps.MapOptions) { + // GeoGuessr's `setOptions` calls always include `backgroundColor` + // so this is how we can distinguish between theirs and ours + if (opts.backgroundColor) { + opts.mapTypeId = getLocalStorage('cg_MapTypeId', opts.mapTypeId) + opts.mapTypeControl = true + opts.mapTypeControlOptions = { + style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR, + position: google.maps.ControlPosition.TOP_RIGHT + } + } + super.setOptions(opts) + } + } + }) +} + +export const rendererApi = { + drawRoundResults, + drawPlayerResults, + focusOnGuess, + clearMarkers, + showSatelliteMap, + hideSatelliteMap, + centerSatelliteView +} diff --git a/src/renderer/useLocalStorage.ts b/src/renderer/useLocalStorage.ts new file mode 100644 index 0000000..c0e2aa0 --- /dev/null +++ b/src/renderer/useLocalStorage.ts @@ -0,0 +1,18 @@ +export function getLocalStorage(key: string, initialValue: T): T { + const storedVal = window.localStorage.getItem(key) + if (storedVal) return isJsonString(storedVal) ? JSON.parse(storedVal) : storedVal + return initialValue +} + +export function setLocalStorage(key: string, value: T) { + window.localStorage.setItem(key, JSON.stringify(value)) +} + +function isJsonString(str: string) { + try { + JSON.parse(str) + } catch (e) { + return false + } + return true +} diff --git a/src/types.d.ts b/src/types.d.ts index 5885562..8988233 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,185 +1,197 @@ -import { IpcRenderer } from "electron"; -import internal from "stream"; - -export type LatLng = { lat: number; lng: number }; -export type Location = { - lat: number; - lng: number; - panoId: string | null; - heading: number; - pitch: number; - zoom: number; -}; - -export type Guess = { - user: string; - username: string; - color: string; - flag: string | null; - position: LatLng; - streak: number; - lastStreak: number | null; - distance: number; - score: number; - time?: number; -}; - -export type MultiGuess = { - user: string; - username: string; - color: string; - flag: string | null; -}; - -export type RoundScore = { - id: string; - userId: string; - username: string; - user: string; - color: string; - flag: string | null; - streak: number; - lastStreak: number | null; - distance: number; - score: number; - time: number; - position: LatLng; -}; - -export type GameResult = { - username: string; - color: string; - flag: string; - streak: number; - guesses: (LatLng | null)[]; - scores: (number | null)[]; - distances: (number | null)[]; - totalScore: number; - totalDistance: number; -}; - -export type Bounds = { - min: LatLng; - max: LatLng; -}; - -export type GameMode = "standard" | "streak"; - -export type GameType = "standard" | "streak"; - -export type GameState = "started" | "finished"; - -export type GameRound = { - lat: number; - lng: number; - panoId: string | null; - heading: number; - pitch: number; - zoom: number; - streakLocationCode: string | null; - // TODO: Add missing fields -}; - -export type GeoGuessrRoundScore = { - amount: string; - unit: string; - percentage: number; -}; - -export type Distance = { - meters: { amount: string; unit: string }; - miles: { amount: string; unit: string }; -}; - -export type GameGuess = { - lat: number; - lng: number; - timedOut: boolean; - timedOutWithGuess: boolean; - roundScore: GeoGuessrRoundScore; - roundScoreInPercentage: number; - roundScoreInPoints: number; - distance: Distance; - distanceInMeters: number; - time: number; -}; - -export type GamePlayer = { - guesses: GameGuess[]; - // TODO: Add rest -}; - -export type GameSettings = { - forbidMoving: boolean; - forbidRotating: boolean; - forbidZooming: boolean; - timeLimit: number; -}; - -export type Seed = GameSettings & { - token: string; - bounds: Bounds; - map: string; - mapName: string; - mode: GameMode; - round: number; - roundCount: number; - rounds: GameRound[]; - player: GamePlayer; - state: GameState; - type: GameType; -}; - -export type GeoguessrUser = { - nick: string; - created: string; - isVerified: boolean; - isCreator: boolean; - countryCode: string; -}; - -export type GeoGuessrMap = { - id: string; - name: string; - slug: string; - description: string; - url: string; - playUrl: string; - bounds: Bounds; - creator: GeoguessrUser; - createdAt: Date; - numFinishedGames: number; - averageScore: number; - maxErrorDistance: number; - likes: number; -}; - -export interface RendererApi { - drawRoundResults(location: Location, roundResults: Guess[], limit?: number); - drawGameLocations(locations: Location[]); - drawPlayerResults(locations: Location[], result: GameResult); - focusOnGuess(location: LatLng); - clearMarkers(keepLocationMarkers?: boolean); - drParseNoCar(); - blinkMode(); - satelliteMode(); - showSatelliteMap(location: LatLng); - hideSatelliteMap(); - centerSatelliteView(location: LatLng); - getBounds(location: LatLng, limit: number); -} - -declare global { - interface Window { - jQuery: typeof import("jquery"); - $: typeof import("jquery"); - chatguessrApi: import("./preload").ChatguessrApi; - } - - namespace DataTables { - interface Settings { - // From datatables.net-plugins - scrollResize?: boolean; - } - } +type Socket = import('socket.io-client').Socket +type ChatUserstate = import('tmi.js').ChatUserstate + +interface UserData extends ChatUserstate { + 'user-id': string + 'display-name': string + avatar?: string +} + +type LatLng = { lat: number; lng: number } + +interface Location_ extends LatLng { + panoId: string | null + heading: number + pitch: number + zoom: number +} + +interface Player { + userId?: string + username: string + color: string + avatar: string | null + flag: string | null +} + +interface Guess { + player: Player + position: LatLng + streak: number + lastStreak: number | null + distance: number + score: number + modified?: boolean +} + +interface RoundResult { + player: Player + country: string | null + streak: number + lastStreak: number | null + distance: number + score: number + time: number + position: LatLng +} + +interface GameResult { + player: Player + streak: number + guesses: (LatLng | null)[] + scores: (number | null)[] + distances: (number | null)[] + totalScore: number + totalDistance: number +} + +interface GameResultDisplay { + player: Player + guesses: (LatLng | null)[] + distances: (number | null)[] + scores: (number | null)[] +} + +interface ScoreboardRow { + index?: { value: number; display: string | number } + player: Player + streak?: { + value: number + display: number | string + } + distance?: { + value: number + display: number | string + } + score?: { + value: number + display: number | string + } + modified?: boolean + position?: LatLng + guesses?: (LatLng | null)[] + distances?: (number | null)[] + scores?: (number | null)[] + totalScore?: number + totalDistance?: number +} + +type GameType = 'standard' | 'streak' + +type GameStatus = 'started' | 'finished' + +type GameState = 'in-round' | 'round-results' | 'game-results' | 'none' + +interface Seed { + token: string + map: string + mapName: string + mode: GameType + type: GameType + forbidMoving: boolean + forbidRotating: boolean + forbidZooming: boolean + timeLimit: number + bounds: Bounds + round: number + roundCount: number + rounds: GameRound[] + player: GamePlayer + state: GameStatus +} + +type GameRound = Location_ & { + streakLocationCode: string | null + // TODO: Add missing fields } + +type GamePlayer = { + guesses: GameGuess[] + // TODO: Add rest +} + +type GameGuess = { + lat: number + lng: number + timedOut: boolean + timedOutWithGuess: boolean + roundScore: GeoGuessrRoundScore + roundScoreInPercentage: number + roundScoreInPoints: number + distance: Distance + distanceInMeters: number + time: number +} + +type GeoGuessrRoundScore = { + amount: string + unit: string + percentage: number +} + +type GeoguessrUser = { + nick: string + created: string + isVerified: boolean + isCreator: boolean + countryCode: string +} + +type GeoGuessrMap = { + id: string + name: string + slug: string + description: string + url: string + playUrl: string + bounds: Bounds + creator: GeoguessrUser + createdAt: Date + numFinishedGames: number + averageScore: number + maxErrorDistance: number + likes: number +} + +type Distance = { + meters: { amount: string; unit: string } + miles: { amount: string; unit: string } +} + +type Bounds = { + min: LatLng + max: LatLng +} + +type GameMode = { + noMove: boolean + noPan: boolean + noZoom: boolean +} + +type Flag = { + code: string + names: string + emoji?: string +} + +type TwitchConnectionState = + | { state: 'disconnected' } + | { state: 'connecting' } + | { state: 'connected'; botUsername: string; channelName: string } + | { state: 'error'; error: unknown } + +type SocketConnectionState = + | { state: 'disconnected' } + | { state: 'connecting' } + | { state: 'connected' } diff --git a/src/utils/Database.js b/src/utils/Database.js deleted file mode 100644 index 39da70c..0000000 --- a/src/utils/Database.js +++ /dev/null @@ -1,922 +0,0 @@ -"use strict"; - -const SQLite = require("better-sqlite3"); -const { randomUUID } = require("crypto"); - -/** @typedef {import('../types').LatLng} LatLng */ -/** @typedef {import("../types").GameResult} GameResult */ - -function timestamp() { - return Math.floor(Date.now() / 1000); -} - -// NEVER modify existing migrations, ONLY add new ones. -/** @type {((db: SQLite.Database) => void)[]} */ -const migrations = [ - function initialSetup(db) { - const usersTable = db.prepare(`CREATE TABLE users ( - -- Twitch user ID - id TEXT PRIMARY KEY NOT NULL, - -- Twitch display name - username TEXT NOT NULL, - flag TEXT DEFAULT NULL, - previous_guess TEXT DEFAULT NULL, - last_location TEXT DEFAULT NULL, - reset_at INT DEFAULT 0 - )`); - - const gamesTable = db.prepare(`CREATE TABLE games ( - -- GeoGuessr game token - id TEXT PRIMARY KEY NOT NULL, - map TEXT NOT NULL, - map_name TEXT NOT NULL, - -- JSON bounds: {min: LatLng, max: LatLng} - -- for the scoring formula - map_bounds TEXT NOT NULL, - -- boolean 0 or 1 - forbid_moving INT NOT NULL, - -- boolean 0 or 1 - forbid_panning INT NOT NULL, - -- boolean 0 or 1 - forbid_zooming INT NOT NULL, - -- in seconds - time_limit INT DEFAULT NULL, - created_at INT NOT NULL - )`); - - const roundsTable = db.prepare(`CREATE TABLE rounds ( - -- UUID - id TEXT PRIMARY KEY NOT NULL, - game_id TEXT NOT NULL, - -- JSON coordinates {lat,lng,heading,pitch} - location TEXT NOT NULL, - -- Country code of the location - country TEXT DEFAULT NULL, - created_at INT NOT NULL, - - FOREIGN KEY(game_id) REFERENCES games(id) - )`); - - const guessesTable = db.prepare(`CREATE TABLE guesses ( - -- UUID - id TEXT PRIMARY KEY NOT NULL, - user_id TEXT NOT NULL, - round_id TEXT NOT NULL, - -- User color at the time the guess was made. - color TEXT DEFAULT NULL, - -- User flag at the time the guess was made. - flag TEXT DEFAULT NULL, - -- JSON coordinates {lat,lng} - location TEXT NOT NULL, - -- Country code where the guess was placed - country TEXT DEFAULT NULL, - streak INT DEFAULT 0, - -- Distance (in metres?), slightly inaccurate - distance INT NOT NULL, - score INT NOT NULL, - created_at INT NOT NULL, - - FOREIGN KEY(user_id) REFERENCES users(id), - FOREIGN KEY(round_id) REFERENCES rounds(id) - )`); - - usersTable.run(); - gamesTable.run(); - roundsTable.run(); - guessesTable.run(); - - // These are all deriveable … maybe add them later if it is useful - /* - ALTER TABLE users ADD COLUMN streak INT DEFAULT 0; - ALTER TABLE users ADD COLUMN best_streak INT DEFAULT 0; - ALTER TABLE users ADD COLUMN correct_guesses INT DEFAULT 0; - ALTER TABLE users ADD COLUMN nb_guesses INT DEFAULT 0; - ALTER TABLE users ADD COLUMN perfects INT DEFAULT 0; - ALTER TABLE users ADD COLUMN victories INT DEFAULT 0; - */ - }, - function createSearchIndices(db) { - db.prepare(`CREATE INDEX guess_user_id ON guesses(user_id)`).run(); - db.prepare(`CREATE INDEX guess_round_id ON guesses(round_id)`).run(); - db.prepare(`CREATE INDEX round_game_id ON rounds(game_id)`).run(); - }, - function createStreaks(db) { - db.prepare( - `CREATE TABLE streaks ( - id TEXT PRIMARY KEY NOT NULL, - user_id TEXT NOT NULL, - last_round_id TEXT NOT NULL, - count INT NOT NULL DEFAULT 1, - created_at INT NOT NULL, - updated_at INT NOT NULL, - - FOREIGN KEY(user_id) REFERENCES users(id), - FOREIGN KEY(last_round_id) REFERENCES rounds(id) - )` - ).run(); - - db.prepare(`ALTER TABLE users ADD COLUMN current_streak_id TEXT DEFAULT NULL`).run(); - }, - function createGameWinnersObsolete(_db) { - // This used to create a game_winners view, but that was obsoleted by the next migration. - // For new users who didn't run this migration yet we can keep it a noop. - // This empty function needs to remain so the `user_version` value in SQLite stays correct. - }, - function addGameStateColumn(db) { - db.prepare(`ALTER TABLE games ADD COLUMN state TEXT DEFAULT 'started'`).run(); - db.prepare(`CREATE INDEX games_state ON games(state)`).run(); - - // Mark all existing games with at least 5 rounds as finished. - db.prepare( - ` - UPDATE games SET state = 'finished' WHERE id IN ( - SELECT games.id - FROM games, rounds - WHERE rounds.game_id = games.id - GROUP BY games.id - HAVING COUNT(rounds.id) >= 5 - ) - ` - ).run(); - }, - function createGameWinners(db) { - db.prepare(`DROP VIEW IF EXISTS game_winners`).run(); - // this query is based on https://stackoverflow.com/a/7745635/591962 - // It could be possible to use windowing functions on the game_scores query too, - // partitioning by game_id and then selecting only those where rank() = 1 to filter top scores. - db.prepare( - ` - CREATE VIEW game_winners (id, user_id, score, created_at) AS - -- Prepare all users' total scores in each game - WITH game_scores AS ( - SELECT guesses.user_id, games.id AS game_id, SUM(guesses.score) AS score, MAX(guesses.created_at) AS guessed_at - FROM games - LEFT JOIN rounds ON rounds.game_id = games.id - LEFT JOIN guesses ON guesses.round_id = rounds.id - WHERE games.state = 'finished' - GROUP BY guesses.user_id, games.id - ) - SELECT games.id, top_scores.user_id, top_scores.score, top_scores.guessed_at AS created_at - FROM games - -- Match the highest total score for each game - -- This can return multiple records if the top score was a tie: it means we count all of them as winners, which seems fair. - LEFT JOIN ( - SELECT user_id, game_id, MAX(score) AS score, guessed_at - FROM game_scores - GROUP BY game_id - ) top_scores ON games.id = top_scores.game_id - WHERE games.state = 'finished' - ` - ).run(); - }, - function createBannedUsers(db) { - const bannedUsersTable = db.prepare(`CREATE TABLE banned_users ( - username TEXT NOT NULL - )`); - - bannedUsersTable.run(); - }, - function createLastStreakField(db) { - db.prepare(`ALTER TABLE guesses ADD COLUMN last_streak INTEGER DEFAULT NULL`).run(); - }, -]; - -class Database { - /** @type {SQLite.Database} */ - #db; - - /** - * @param {string} file - */ - constructor(file) { - this.#db = new SQLite(file); - - this.#migrate(); - } - - #migrateUp() { - const version = this.#db.pragma("user_version", { simple: true }); - if (version < migrations.length) { - const up = this.#db.transaction(() => { - migrations[version](this.#db); - this.#db.pragma(`user_version=${version + 1}`); - }); - up(); - - return true; - } - return false; - } - - #migrate() { - let moreMigrations = true; - while (moreMigrations) { - moreMigrations = this.#migrateUp(); - } - } - - /** - * - * @param {import('../types').Seed} seed - */ - createGame(seed) { - const insertGame = this.#db.prepare(` - INSERT INTO games(id, map, map_name, map_bounds, forbid_moving, forbid_panning, forbid_zooming, time_limit, created_at) - VALUES (:id, :map, :mapName, :bounds, :forbidMoving, :forbidPanning, :forbidZooming, :timeLimit, :createdAt) - `); - - insertGame.run({ - id: seed.token, - map: seed.map, - mapName: seed.mapName, - bounds: JSON.stringify(seed.bounds), - forbidMoving: seed.forbidMoving ? 1 : 0, - forbidPanning: seed.forbidRotating ? 1 : 0, - forbidZooming: seed.forbidZooming ? 1 : 0, - timeLimit: seed.timeLimit, - createdAt: timestamp(), - }); - } - - /** - * - * @param {string} gameId - * @returns {string} - */ - getCurrentRound(gameId) { - const findRoundId = this.#db - .prepare( - ` - SELECT id - FROM rounds - WHERE game_id = ? - ORDER BY created_at DESC - LIMIT 1 - ` - ) - .pluck(true); - - return findRoundId.get(gameId); - } - - getLastRoundLocation() { - /** @type {{ lat: number, lng: number} | undefined} */ - const stmt = this.#db.prepare(`SELECT location from rounds ORDER BY created_at DESC LIMIT 1`).get(); - return stmt; - } - - /** - * - * @param {string} gameId - * @param {import('../types').GameRound} round - */ - createRound(gameId, round) { - const insertRound = this.#db.prepare(` - INSERT INTO rounds(id, game_id, location, created_at) - VALUES (:id, :gameId, :location, :createdAt) - `); - - const id = randomUUID(); - - insertRound.run({ - id, - gameId, - location: JSON.stringify({ - lat: round.lat, - lng: round.lng, - panoId: round.panoId, - heading: round.heading, - pitch: round.pitch, - }), - createdAt: timestamp(), - }); - - return id; - } - - /** - * - * @param {string} roundId - * @param {string} country - */ - setRoundCountry(roundId, country) { - const stmt = this.#db.prepare(`UPDATE rounds SET country = :country WHERE id = :id`); - stmt.run({ - id: roundId, - country, - }); - } - - /** - * - * @param {string} roundId - * @param {string} userId - * @param {{ color: string, flag: string, location: LatLng, country: string | null, streak: number, lastStreak: number|null, distance: number, score: number }} guess - */ - createGuess(roundId, userId, guess) { - const id = randomUUID(); - const insertGuess = this.#db.prepare(` - INSERT INTO guesses(id, round_id, user_id, color, flag, location, country, streak, last_streak, distance, score, created_at) - VALUES (:id, :roundId, :userId, :color, :flag, :location, :country, :streak, :lastStreak, :distance, :score, :createdAt) - `); - - insertGuess.run({ - id, - roundId, - userId, - color: guess.color, - flag: guess.flag, - location: JSON.stringify(guess.location), - country: guess.country, - streak: guess.streak, - lastStreak: guess.lastStreak, - distance: guess.distance, - score: guess.score, - createdAt: timestamp(), - }); - - return id; - } - - /** - * @param {string} roundId - * @param {string} userId - */ - getUserGuess(roundId, userId) { - const stmt = this.#db.prepare( - "SELECT id, color, flag, location, country, streak, last_streak AS lastStreak, distance, score FROM guesses WHERE round_id = ? AND user_id = ?" - ); - /** @type {{ id: string, color: string, flag: string, location: string, country: string | null, streak: number, lastStreak: number | null, distance: number, score: number } | undefined} */ - const row = stmt.get(roundId, userId); - if (!row) { - return; - } - - return { - ...row, - /** @type {LatLng} */ - location: JSON.parse(row.location), - }; - } - - /** - * @param {string} guessId - * @param {{ color: string, flag: string, location: LatLng, country: string | null, streak: number, lastStreak: number | null, distance: number, score: number }} guess - */ - updateGuess(guessId, guess) { - const updateGuess = this.#db.prepare(` - UPDATE guesses - SET color = :color, - flag = :flag, - location = :location, - country = :country, - streak = :streak, - last_streak = :lastStreak, - distance = :distance, - score = :score, - created_at = :updatedAt - WHERE id = :id - `); - - updateGuess.run({ - id: guessId, - color: guess.color, - flag: guess.flag, - location: JSON.stringify(guess.location), - country: guess.country, - streak: guess.streak, - lastStreak: guess.lastStreak, - distance: guess.distance, - score: guess.score, - updatedAt: timestamp(), - }); - } - - // /** - // * - // * @param {string} guessId - // * @param {number} streak - // * @param {number|null} [lastStreak] - // */ - // setGuessStreak(guessId, streak, lastStreak = null) { - // const updateGuess = this.#db.prepare(` - // UPDATE guesses - // SET streak = :streak, last_streak = :lastStreak - // WHERE id = :id - // `); - - // updateGuess.run({ - // id: guessId, - // streak, - // lastStreak, - // }); - // } - - /** - * - * @param {string} userId - * @returns {{ id: string, count: number, lastLocation: LatLng } | undefined} - */ - getUserStreak(userId) { - const stmt = this.#db.prepare(` - SELECT streaks.id, streaks.count, rounds.location - FROM users, streaks, rounds - WHERE users.id = ? - AND streaks.id = users.current_streak_id - AND rounds.id = streaks.last_round_id - `); - - /** @type {{ id: string, count: number, location: string } | undefined} */ - const row = stmt.get(userId); - return row - ? { - id: row.id, - count: row.count, - lastLocation: JSON.parse(row.location), - } - : undefined; - } - - /** - * - * @param {string} userId - * @param {string} roundId - */ - addUserStreak(userId, roundId) { - const streak = this.getUserStreak(userId); - - if (!streak) { - const id = randomUUID(); - this.#db - .prepare( - ` - INSERT INTO streaks(id, user_id, last_round_id, created_at, updated_at) - VALUES (:id, :userId, :roundId, :createdAt, :createdAt) - ` - ) - .run({ - id, - userId, - roundId, - createdAt: timestamp(), - }); - this.#db.prepare(`UPDATE users SET current_streak_id = :streakId WHERE id = :userId`).run({ - userId, - streakId: id, - }); - } else { - this.#db - .prepare( - ` - UPDATE streaks - SET count = count + 1, - last_round_id = :roundId, - updated_at = :updatedAt - WHERE id = :id - ` - ) - .run({ - id: streak.id, - roundId, - updatedAt: timestamp(), - }); - } - } - - /** - * @param {string} userId - */ - resetUserStreak(userId) { - // In handleUserGuess() we need to get lastLocation from the previous streak in order to reset the streak if the player skipped a round - // so we don't need to return last streak from here anymore, it also saves a query in processMultiGuesses() when streak is reseted - // const tx = this.#db.transaction(() => { - // const streak = this.getUserStreak(userId); - this.#db.prepare("UPDATE users SET current_streak_id = NULL WHERE id = ?").run(userId); - // return streak; - // }); - // return tx()?.count ?? null; - } - - /** - * Get all the participants for a round, sorted by time. No scores included. - * - * @param {string} roundId - */ - getRoundParticipants(roundId) { - const stmt = this.#db.prepare(` - SELECT - guesses.id, - users.username, - guesses.color, - guesses.flag - FROM guesses, users - WHERE round_id = ? AND users.id = guesses.user_id - ORDER BY created_at ASC - `); - - /** @type {{ id: string, username: string, color: string, flag: string }[]} */ - const records = stmt.all(roundId); - - return records; - } - - /** - * Get all the guesses for a round, sorted from closest distance to farthest away. - * For 5000 scores, the time to arrive at the guess is used instead of distance. - * - * @param {string} roundId - */ - getRoundResults(roundId) { - const stmt = this.#db.prepare(` - SELECT - guesses.id, - guesses.user_id, - users.username, - guesses.color, - guesses.flag, - guesses.location, - guesses.streak, - guesses.country, - guesses.last_streak, - guesses.distance, - guesses.score, - guesses.created_at - rounds.created_at AS time, - IIF(guesses.score = 5000, guesses.created_at - rounds.created_at, NULL) AS time_to_5k - FROM rounds, guesses, users - WHERE rounds.id = ? - AND guesses.round_id = rounds.id - AND users.id = guesses.user_id - ORDER BY guesses.score DESC, - time_to_5k ASC, - guesses.distance ASC - `); - - /** @type {{ id: string, user_id: string, username: string, color: string, flag: string, location: string, country: string, streak: number, last_streak: number | null, distance: number, score: number, time: number }[]} */ - const records = stmt.all(roundId); - - return records.map((record) => ({ - id: record.id, - userId: record.user_id, - username: record.username, - user: record.username, - color: record.color, - flag: record.flag, - streak: record.streak, - country: record.country, - lastStreak: record.last_streak, - distance: record.distance, - score: record.score, - time: record.time, - /** @type {LatLng} */ - position: JSON.parse(record.location), - })); - } - - /** - * Retrieve only needed values for processMultiGuesses() - * @param {string} roundId - */ - getRoundResultsSimplified(roundId) { - const stmt = this.#db.prepare(` - SELECT - guesses.id, - guesses.user_id, - guesses.streak, - guesses.country - FROM guesses, rounds - WHERE rounds.id = ? - AND guesses.round_id = rounds.id - `); - - /** @type {{ id: string, user_id: string, country: string, streak: number }[]} */ - const records = stmt.all(roundId); - - return records.map((record) => ({ - id: record.id, - userId: record.user_id, - streak: record.streak, - country: record.country, - })); - } - - /** - * Mark a game as finished. It will now count for the victory calculations. - * @param {string} gameId - */ - finishGame(gameId) { - const stmt = this.#db.prepare(`UPDATE games SET state = 'finished' WHERE id = ?`); - stmt.run(gameId); - } - - /** - * Get the total scores for a game, across all rounds, ordered from highest to lowest points. - * @param {string} gameId - * @returns {GameResult[]} - */ - getGameResults(gameId) { - // We need to pick the last guess's streak value OR calculate them on the fly. Our streak tracking table is not suitable for - // checking the current streak at a previous point. The only option atm is to use this subquery I think, hopefully the - // performance is not too bad. - - const stmt = this.#db.prepare(` - SELECT - users.username, - guesses.color, - users.flag, - '[' || GROUP_CONCAT(COALESCE(guesses.location, 'null')) || ']' AS guesses, - '[' || GROUP_CONCAT(COALESCE(guesses.score, 'null')) || ']' AS scores, - '[' || GROUP_CONCAT(COALESCE(guesses.distance, 'null')) || ']' AS distances, - SUM(guesses.score) AS total_score, - SUM(guesses.distance) AS total_distance, - ( - SELECT streak - FROM guesses ig, rounds ir - WHERE ir.game_id = rounds.game_id - AND ig.round_id = ir.id - AND ig.user_id = users.id - ORDER BY ig.created_at DESC - LIMIT 1 - ) AS streak - FROM rounds - JOIN users ON users.id IN ( - SELECT DISTINCT g.user_id - FROM rounds r - JOIN guesses g ON g.round_id = r.id - WHERE r.game_id = ? - ) - LEFT JOIN guesses ON guesses.round_id = rounds.id AND users.id = guesses.user_id - WHERE rounds.game_id = ? - GROUP BY users.id - ORDER BY total_score DESC, total_distance ASC - `); - const records = stmt.all(gameId, gameId); - - return records.map((record) => ({ - username: record.username, - color: record.color, - flag: record.flag, - streak: record.streak, - guesses: JSON.parse(record.guesses), - scores: JSON.parse(record.scores), - distances: JSON.parse(record.distances), - totalScore: record.total_score, - totalDistance: record.total_distance, - })); - } - - /** - * - * @param {Record} record - * @returns {{ id: string, username: string, flag: string|null, previousGuess: LatLng, lastLocation: LatLng, resetAt: number }} - */ - #parseUser(record) { - return { - id: record.id, - username: record.username, - flag: record.flag, - previousGuess: record.previous_guess ? JSON.parse(record.previous_guess) : null, - lastLocation: record.last_location ? JSON.parse(record.last_location) : null, - resetAt: record.reset_at * 1000, - }; - } - - /** - * - * @param {string} id - */ - getUser(id) { - const user = this.#db - .prepare("SELECT id, username, flag, previous_guess, last_location, reset_at FROM users WHERE id = ?") - .get(id); - - return user ? this.#parseUser(user) : undefined; - } - - /** - * - * @param {string} id - * @param {string} username - */ - getOrCreateUser(id, username) { - const stmt = this.#db.prepare(` - INSERT INTO users(id, username) - VALUES (:id, :username) - ON CONFLICT (id) DO - UPDATE SET username = :username - RETURNING * - `); - - const user = stmt.get({ id, username }); - - return user ? this.#parseUser(user) : undefined; - } - - /** - * - * @param {string} userId - * @param {string} flag - */ - setUserFlag(userId, flag) { - this.#db.prepare(`UPDATE users SET flag = :flag WHERE id = :id`).run({ - id: userId, - flag, - }); - } - - /** - * - * @param {string} userId - * @param {LatLng} lastLocation - */ - setUserLastLocation(userId, lastLocation) { - this.#db.prepare(`UPDATE users SET last_location = :lastLocation WHERE id = :id`).run({ - id: userId, - lastLocation: JSON.stringify(lastLocation), - }); - } - - /** - * - * @param {string} userId - * @param {LatLng} previousGuess - */ - setUserPreviousGuess(userId, previousGuess) { - this.#db.prepare(`UPDATE users SET previous_guess = :previousGuess WHERE id = :id`).run({ - id: userId, - previousGuess: JSON.stringify(previousGuess), - }); - } - - /** - * - * @param {string} userId - */ - getUserStats(userId) { - const stmt = this.#db.prepare(` - SELECT - username, - flag, - COALESCE(current_streak.count, 0) AS current_streak, - COALESCE((SELECT MAX(count) FROM streaks WHERE user_id = :id AND updated_at > users.reset_at), 0) AS best_streak, - (SELECT COUNT(*) FROM guesses WHERE user_id = :id AND created_at > users.reset_at) AS total_guesses, - (SELECT COUNT(*) FROM guesses WHERE user_id = :id AND streak > 0 AND created_at > users.reset_at) AS correct_guesses, - (SELECT COUNT(*) FROM guesses WHERE user_id = :id AND score = 5000 AND created_at > users.reset_at) AS perfects, - (SELECT AVG(score) FROM guesses WHERE user_id = users.id AND created_at > users.reset_at) AS average, - (SELECT COUNT(*) FROM game_winners WHERE user_id = users.id AND created_at > users.reset_at) AS victories - FROM users - LEFT JOIN streaks current_streak ON current_streak.id = users.current_streak_id - WHERE users.id = :id - `); - - /** @type {{ username: string, flag: string, current_streak: number, best_streak: number, total_guesses: number, correct_guesses: number, perfects: number, average: number, victories: number } | undefined} */ - const record = stmt.get({ id: userId }); - return record - ? { - username: record.username, - flag: record.flag, - streak: record.current_streak, - bestStreak: record.best_streak, - nbGuesses: record.total_guesses, - correctGuesses: record.correct_guesses, - meanScore: record.average, - perfects: record.perfects, - victories: record.victories, - } - : undefined; - } - - getGlobalStats() { - const streakQuery = this.#db.prepare(` - SELECT users.id, users.username, MAX(streaks.count) AS streak - FROM users, streaks - WHERE NOT users.id = 'BROADCASTER' - AND streaks.user_id = users.id - AND streaks.created_at > users.reset_at - GROUP BY users.id - ORDER BY streak DESC - `); - const victoriesQuery = this.#db.prepare(` - SELECT users.id, users.username, COUNT(*) AS victories - FROM game_winners, users - WHERE NOT users.id = 'BROADCASTER' - AND users.id = game_winners.user_id - AND game_winners.created_at > users.reset_at - GROUP BY users.id - ORDER BY victories DESC - `); - const perfectQuery = this.#db.prepare(` - SELECT users.id, users.username, COUNT(guesses.id) AS perfects - FROM users - LEFT JOIN guesses ON guesses.user_id = users.id AND guesses.created_at > users.reset_at - WHERE NOT users.id = 'BROADCASTER' - AND guesses.score = 5000 - GROUP BY users.id - ORDER BY perfects DESC - `); - - /** @type {{ id: string, username: string, streak: number } | undefined} */ - const bestStreak = streakQuery.get(); - /** @type {{ id: string, username: string, victories: number } | undefined} */ - const mostVictories = victoriesQuery.get(); - /** @type {{ id: string, username: string, perfects: number } | undefined} */ - const mostPerfects = perfectQuery.get(); - - return { - streak: bestStreak, - victories: mostVictories, - perfects: mostPerfects, - }; - } - - /** - * - * @param {string} userId - */ - resetUserStats(userId) { - this.#db.prepare(`UPDATE users SET current_streak_id = NULL, reset_at = :resetAt WHERE id = :id`).run({ - id: userId, - resetAt: timestamp(), - }); - } - - /** - * Check if the database contains any data. - * @returns {boolean} - */ - isEmpty() { - const result = this.#db.prepare("SELECT COUNT(*) as count FROM users;").get(); - return !result || result.count === 0; - } - - async clear() { - if (!this.#db.memory) { - try { - await this.#db.backup(`${this.#db.name}.bak`); - } catch {} - } - - const deleteEverything = this.#db.transaction(() => { - // Disable foreign key checking while we delete everything - this.#db.prepare("PRAGMA foreign_keys=0;").run(); - this.#db.prepare("DELETE FROM guesses;").run(); - this.#db.prepare("DELETE FROM streaks;").run(); - this.#db.prepare("DELETE FROM rounds;").run(); - this.#db.prepare("DELETE FROM games;").run(); - this.#db.prepare("DELETE FROM users;").run(); - this.#db.prepare("PRAGMA foreign_keys=1;").run(); - }); - deleteEverything(); - } - - /** - * - * @param {string} username - */ - addBannedUser(username) { - this.#db - .prepare( - ` - INSERT INTO banned_users (username) - VALUES (:username) - ` - ) - .run({ username: username }); - } - - /** - * - * @param {string} username - */ - deleteBannedUser(username) { - this.#db - .prepare( - ` - DELETE FROM banned_users - WHERE username = :username - ` - ) - .run({ username: username }); - } - - getBannedUsers() { - const bannedUsers = this.#db.prepare(`SELECT username FROM banned_users`).all(); - - return bannedUsers; - } - - /** - * Run a custom SQL query, for use in tests only. - * - * @param {string} query - * @param {object} data - */ - [Symbol.for("chatguessr-test-run-query")](query, data) { - if (process.env.NODE_ENV !== "test") { - throw new Error("Do not run queries outside of the test environment"); - } - - return this.#db.prepare(query).run(data); - } -} - -module.exports = Database; diff --git a/src/utils/Database.test.js b/src/utils/Database.test.js deleted file mode 100644 index 68d3008..0000000 --- a/src/utils/Database.test.js +++ /dev/null @@ -1,243 +0,0 @@ -import { beforeEach, describe, it, expect } from "vitest"; -import { randomUUID } from "node:crypto"; -import Database from "./Database"; - -/** @type {Database} */ -let db; - -beforeEach(() => { - db = new Database(":memory:"); -}); - -function createGame () { - const token = randomUUID(); - db.createGame(/** @type {any} */ ({ - token, - map: "test", - mapName: "test", - bounds: { - min: { lat: 0, lng: 0 }, - max: { lat: 0, lng: 0 }, - }, - forbidMoving: true, - forbidRotating: false, - forbidZooming: false, - timeLimit: 0, - })); - return token; -} - -describe("getUserStats", () => { - it("counts victories", () => { - const user = db.getOrCreateUser("1234567", "libreanna"); - const token = createGame(); - const createGuess = () => { - const roundId = db.createRound(token, { - lat: 0, - lng: 0, - panoId: null, - heading: 0, - pitch: 0, - zoom: 0, - streakLocationCode: null, - }); - db.createGuess(roundId, user.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 0, - score: 5000, - }); - }; - - for (let i = 0; i < 5; i += 1) { - createGuess(); - } - - // Now on round 5: this should not yet be counted as a victory - expect(db.getUserStats(user.id).victories).toEqual(0); - - db.finishGame(token); - - // Only once the game is finished, it counts. - expect(db.getUserStats(user.id).victories).toEqual(1); - }); -}); - -describe("getRoundResults", () => { - it("sorts by score and distance", () => { - const user = db.getOrCreateUser("1234567", "libreanna"); - const user2 = db.getOrCreateUser("1234568", "zehef_"); - const user3 = db.getOrCreateUser("1234569", "mramericanmike"); - const token = createGame(); - - const roundId = db.createRound(token, { - lat: 0, - lng: 0, - panoId: null, - heading: 0, - pitch: 0, - zoom: 0, - streakLocationCode: null, - }); - - db.createGuess(roundId, user2.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 1234, - score: 3000, - }); - db.createGuess(roundId, user.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 1000, - score: 3600, - }); - db.createGuess(roundId, user3.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 998, - score: 3600, - }); - - const leaderboard = db.getRoundResults(roundId).map((score) => score.username); - expect(leaderboard).toEqual([ - "mramericanmike", - "libreanna", - "zehef_", - ]); - }); - - it("sorts 5Ks by time", async () => { - const user = db.getOrCreateUser("1234567", "libreanna"); - const user2 = db.getOrCreateUser("1234568", "zehef_"); - const user3 = db.getOrCreateUser("1234569", "mramericanmike"); - const token = createGame(); - - const roundId = db.createRound(token, { - lat: 0, - lng: 0, - panoId: null, - heading: 0, - pitch: 0, - zoom: 0, - streakLocationCode: null, - }); - - db.createGuess(roundId, user.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 12, - score: 5000, - }); - db.createGuess(roundId, user3.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 998, - score: 4800, - }); - const second5k = db.createGuess(roundId, user2.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 8, - score: 5000, - }); - - // `second5k` was closer, but 20 seconds later, - // so it should show up *after* the first 5K. - // TODO maybe we can use jest simulated timers for this - db[Symbol.for('chatguessr-test-run-query')]('UPDATE guesses SET created_at = created_at + 20 WHERE id = :id', { id: second5k }); - - const leaderboard = db.getRoundResults(roundId).map((score) => score.username); - expect(leaderboard).toEqual([ - "libreanna", - "zehef_", - "mramericanmike", - ]); - }); - - it("sorts by time in multi-guess", async () => { - const user = db.getOrCreateUser("1234567", "libreanna"); - const user2 = db.getOrCreateUser("1234568", "zehef_"); - const token = createGame(); - - const roundId = db.createRound(token, { - lat: 0, - lng: 0, - panoId: null, - heading: 0, - pitch: 0, - zoom: 0, - streakLocationCode: null, - }); - - const non5k = db.createGuess(roundId, user.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 988, - score: 4924, - }); - // adjust `non5k` to be significantly earlier than user2's 5K, - // so it is earlier but worse by not being a 5K. Then we can check that after - // updating the guess, the time is also updated. - db[Symbol.for('chatguessr-test-run-query')]('UPDATE guesses SET created_at = created_at - 20 WHERE id = :id', { id: non5k }); - - db.createGuess(roundId, user2.id, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 8, - score: 5000, - }); - db.updateGuess(non5k, { - color: "#fff", - flag: "jo", - location: { lat: 0, lng: 0 }, - country: null, - streak: 0, - lastStreak: null, - distance: 12, - score: 5000, - }); - - const leaderboard = db.getRoundResults(roundId).map((score) => score.username); - expect(leaderboard).toEqual([ - "zehef_", - "libreanna", - ]); - }); -}); diff --git a/src/utils/GameHelper.js b/src/utils/GameHelper.js deleted file mode 100644 index 170cfcc..0000000 --- a/src/utils/GameHelper.js +++ /dev/null @@ -1,229 +0,0 @@ -const axios = require("axios").default; -const countryIso = require("coordinate_to_country"); -const { session } = require("electron"); - -/** - * Country code mapping for 2-character ISO codes that should be considered - * part of another country for GeoGuessr streak purposes. - * - * @type {Record} - */ -// @ts-ignore -const countryCodes = require("./countryCodes.json"); - -const GEOGUESSR_URL = "https://geoguessr.com"; -const CG_API_URL = process.env.CG_API_URL ?? "https://chatguessr.com/api"; -const CG_PUBLIC_URL = process.env.CG_PUBLIC_URL ?? "chatguessr.com"; - -/** @typedef {import('../types').LatLng} LatLng */ -/** @typedef {import('../types').GameResult} GameResult */ -/** @typedef {import('../types').Seed} Seed */ -/** @typedef {import("../types").GeoGuessrMap} GeoGuessrMap */ - -/** - * Checks if the URL is an in-game page. - * - * @param {string} url - * @return {boolean} - */ -function isGameURL(url) { - return url.includes("/game/"); -} - -/** - * Gets the Game ID from a game URL - * Checks if ID is 16 characters in length - * @param {string} url Game URL - * @return {string|undefined} - */ -function getGameId(url) { - const id = url.slice(url.lastIndexOf("/") + 1); - if (id.length == 16) { - return id; - } -} - -// Get GeoGuessr cookies -const getCookies = async () => { - return session.defaultSession.cookies - .get({ url: "https://www.geoguessr.com" }) - .then((cookies) => { - const ncfa = cookies.find((cookie) => cookie.name === "_ncfa"); - return ncfa ? { Cookie: `${ncfa.name}=${ncfa.value}` } : null; - }) - .catch((err) => { - console.error(err); - }); -}; - -/** - * Fetch a game seed from the GeoGuessr API. - * @param {string} url URL for the game. - * @return {Promise} Seed Promise - */ -async function fetchSeed(url) { - const cookies = await getCookies(); - const gameId = getGameId(url); - - if (!gameId || !cookies) { - return; - } - - const { data } = await axios.get(`${GEOGUESSR_URL}/api/v3/games/${gameId}`, { headers: cookies }); - return data; -} - -/** - * Fetch the full map info from the current game, if one is active - * @param {string} mapToken The base16 map identifier - * @return {Promise} Seed Promise - */ -async function fetchMap(mapToken) { - const cookies = await getCookies(); - if (!cookies) { - return; - } - - const { data } = await axios.get(`${GEOGUESSR_URL}/api/maps/${mapToken}`, { headers: cookies }); - return data; -} - -/** - * Get the country code for a coordinate. - * - * @param {LatLng} location - * @return {Promise} Country code or `undefined` if the location is not in a known country. - */ -async function getCountryCode(location) { - const localResults = countryIso(location.lat, location.lng, true); - let localIso = localResults.length > 0 ? localResults[0] : undefined; - if (!localIso) { - return; - } - return countryCodes[localIso]; -} - -/** - * Parse lat/lng coordinates from a string. - * - * @param {string} coordinates - * @return {LatLng | undefined} - */ -function parseCoordinates(coordinates) { - const regex = - /^(?[-+]?(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?)),\s*(?[-+]?(?:180(?:\.0+)?|(?:(?:1[0-7]\d)|(?:[1-9]?\d))(?:\.\d+)?))$/; - const m = regex.exec(coordinates); - if (m?.groups) { - return { lat: parseFloat(m.groups.lat), lng: parseFloat(m.groups.lng) }; - } -} - -/** - * Returns map scale - * @param {import("../types").Bounds} bounds map bounds - * @return {number} map scale - */ -function calculateScale(bounds) { - return haversineDistance(bounds.min, bounds.max) / 7.458421; -} - -/** - * Returns distance in km between two coordinates - * @param {LatLng} mk1 - * @param {LatLng} mk2 - * @return {number} km - */ -function haversineDistance(mk1, mk2) { - const R = 6371.071; - const rlat1 = mk1.lat * (Math.PI / 180); - const rlat2 = mk2.lat * (Math.PI / 180); - const difflat = rlat2 - rlat1; - const difflon = (mk2.lng - mk1.lng) * (Math.PI / 180); - const km = - 2 * - R * - Math.asin( - Math.sqrt( - Math.sin(difflat / 2) * Math.sin(difflat / 2) + - Math.cos(rlat1) * Math.cos(rlat2) * Math.sin(difflon / 2) * Math.sin(difflon / 2) - ) - ); - return km; -} - -/** - * Returns score based on distance and scale - * @param {number} distance - * @param {number} scale - * @return {number} score - */ -function calculateScore(distance, scale) { - if (distance * 1000 < 25) { - return 5000; - } - return Math.round(5000 * Math.pow(0.99866017, (distance * 1000) / scale)); -} - -/** - * Upload scores to the Chatguessr API and return the game summary link - * - * @param {string} accessToken - * @param {string} bot - * @param {string} streamer - * @param {string} map - * @param {Object} mode - * @param {LatLng[]} locations - * @param {GameResult[]} gameResults - * @return {Promise} - */ -async function makeLink(accessToken, bot, streamer, map, mode, locations, gameResults) { - /** @type {import("axios").AxiosResponse<{ code: string }>} */ - const res = await axios.post( - `${CG_API_URL}/game`, - { - bot: bot, - streamer: streamer, - map: map, - mode: mode, - locations: locations, - players: gameResults, - }, - { headers: { access_token: accessToken } } - ); - - return `${CG_PUBLIC_URL}/game/${res.data.code}`; -} - -/** - * Returns random coordinates within land, no Antarctica - * @param {import("../types").Bounds} bounds Optional bounds to further restrict random coordinates - * @return {Promise} - */ -async function getRandomCoordsInLand(bounds = null) { - let lat_north = 85, - lat_south = -60, - lng_west = -180, - lng_east = 180; - if (bounds != null) { - lat_north = bounds.max.lat; - lat_south = Math.max(bounds.min.lat, lat_south); - lng_east = bounds.max.lng; - lng_west = bounds.min.lng; - } - const lat = Math.random() * (lat_north - lat_south) + lat_south; - const lng = Math.random() * (lng_east - lng_west) + lng_west; - const localResults = countryIso(lat, lng, true); - if (!localResults.length) return await getRandomCoordsInLand(bounds); - return { lat, lng }; -} - -exports.isGameURL = isGameURL; -exports.fetchMap = fetchMap; -exports.fetchSeed = fetchSeed; -exports.getCountryCode = getCountryCode; -exports.parseCoordinates = parseCoordinates; -exports.calculateScale = calculateScale; -exports.haversineDistance = haversineDistance; -exports.calculateScore = calculateScore; -exports.makeLink = makeLink; -exports.getRandomCoordsInLand = getRandomCoordsInLand; diff --git a/src/utils/GameHelper.test.js b/src/utils/GameHelper.test.js deleted file mode 100644 index f372681..0000000 --- a/src/utils/GameHelper.test.js +++ /dev/null @@ -1,120 +0,0 @@ -import { describe, it, expect } from "vitest"; -import * as GameHelper from "./GameHelper"; - -describe('getCountryCode', () => { - // These are not political opinions, but checks to ensure we match whatever decisions - // GeoGuessr has made, even when those decisions are bad. - - it('identifies the country', async () => { - const korea = { lat: 37.00990352577917, lng: 128.60820945116575 }; - await expect(GameHelper.getCountryCode(korea)).resolves.toBe('KR'); - const luxNearBorder = { lat: 50.18241242506854, lng: 6.022353016459996 }; - await expect(GameHelper.getCountryCode(luxNearBorder)).resolves.toBe('LU'); - const nearNorthPole = { lat: 87.94532231211203, lng: 102.72437132716654 }; - await expect(GameHelper.getCountryCode(nearNorthPole)).resolves.toBe(undefined); - }); - it('counts islands near China under TW rule as Taiwan', async () => { - const kinmen = { lat: 24.478693881519966, lng: 118.30351505188996 }; - await expect(GameHelper.getCountryCode(kinmen)).resolves.toBe('TW'); - const lienchiang = { lat: 26.1640452690357, lng: 119.91813403003158 }; - await expect(GameHelper.getCountryCode(lienchiang)).resolves.toBe('TW'); - const dongyin = { lat: 26.37011790575555, lng: 120.48353606410257 }; - await expect(GameHelper.getCountryCode(dongyin)).resolves.toBe('TW'); - }); - it('counts HK/Macao as China', async () => { - const hongKong = { lat: 22.424952693214557, lng: 114.12527863797602 }; - await expect(GameHelper.getCountryCode(hongKong)).resolves.toBe('CN'); - const macao = { lat: 22.17174108804142, lng: 113.53648510492957 }; - await expect(GameHelper.getCountryCode(macao)).resolves.toBe('CN'); - }); - it('counts Israel/Palestine as the same country', async () => { - const il = await GameHelper.getCountryCode({ lat: 32.034961561407215, lng: 34.75764745886409 }); - const ps = await GameHelper.getCountryCode({ lat: 31.862835854507576, lng: 35.456499397290635 }); - expect(il).toBe(ps); - }); - it('counts Åland as Finland', async () => { - const aland = { lat: 60.41415638472204, lng: 20.309877225436857 }; - await expect(GameHelper.getCountryCode(aland)).resolves.toBe('FI'); - }); - it('counts Lesotho as Lesotho', async () => { - const ls = { lat: -29.496987596535757, lng: 28.212890625 }; - expect(await GameHelper.getCountryCode(ls)).toBe('LS'); - }); - it('counts Campione d\'Italia as Italy', async () => { - const campione = { lat: 45.9689301700563, lng: 8.973770141601562 }; - expect(await GameHelper.getCountryCode(campione)).toBe('IT'); - }); - it('counts San Marino', async () => { - const sanMarino = { lat: 43.937461690316646, lng: 12.47222900390625 }; - expect(await GameHelper.getCountryCode(sanMarino)).toBe('SM'); - }); - it('counts Vatican City', async () => { - const vatican = { lat: 41.903363034132724, lng: 12.452659606933594 }; - expect(await GameHelper.getCountryCode(vatican)).toBe('VA'); - }); - it('Baarle-Nassau and Baarle-Hertog are resolved properly', async () => { - const nl = {lat: 51.439391, lng: 4.931514}; - const be = {lat: 51.445161, lng: 4.941440}; - expect(await GameHelper.getCountryCode(nl)).toBe('NL'); - expect(await GameHelper.getCountryCode(be)).toBe('BE'); - }); - it('the Vennbahn is resolved properly', async () => { - const de = {lat: 50.563848, lng: 6.211089}; - const be = {lat: 50.563992, lng: 6.231465}; - expect(await GameHelper.getCountryCode(de)).toBe('DE'); - expect(await GameHelper.getCountryCode(be)).toBe('BE'); - }); - it('counts Llívia as spain', async () => { - const es = { lat:42.465134, lng:1.976742 }; - expect(await GameHelper.getCountryCode(es)).toBe('ES'); - }); -}); - -describe('parseCoordinates', () => { - it("Checks if '30.12345, 50.54321' are valid coordinates >> true", () => { - expect(GameHelper.parseCoordinates("30.12345, 50.54321")).toBeTruthy(); - }); - it("Checks if '30.12345,50.54321' are valid coordinates >> true", () => { - expect(GameHelper.parseCoordinates("30.12345,50.54321")).toBeTruthy(); - }); - it("Checks if '-30.12345, -50.54321' are valid coordinates >> true", () => { - const coord = GameHelper.parseCoordinates("-30.12345, -50.54321") - expect(coord).toBeDefined(); - expect(coord.lat).toBeCloseTo(-30.12345, 4); - expect(coord.lng).toBeCloseTo(-50.54321, 4); - }); - it("Checks if '-30.12345,-50.54321' are valid coordinates >> true", () => { - expect(GameHelper.parseCoordinates("-30.12345,-50.54321")).toBeTruthy(); - }); - it("Checks if '95.12345, 50.54321' are invalid coordinates >> false", () => { - expect(GameHelper.parseCoordinates("95.12345, 50.54321")).toBeFalsy(); - }); - it("Checks if '30.12345, 190.54321' are invalid coordinates >> false", () => { - expect(GameHelper.parseCoordinates("30.12345, 190.54321")).toBeFalsy(); - }); -}); - -describe('randomPlonk', () => { - // Requires ~30ms/test - const repeats = 100; - it("Checks if randomplonk without bounds avoids antarctica", async () => { - // This takes about 30ms/test, so ... - for(var i = 0; i < repeats; i++) { - const {lat, lng} = await GameHelper.getRandomCoordsInLand(); - expect(lat > -60).toBeTruthy(); - expect(lat < 90).toBeTruthy(); - expect(lng > -180).toBeTruthy(); - expect(lng < 180).toBeTruthy(); - } - }); - it("Checks if randomplonk with bounds remains in bounds", async () => { - const inBounds = { min: { lat: 32, lng: -117 }, max: { lat: 33, lng: -116}}; - for(var i = 0; i < repeats; i++) { - const {lat, lng} = await GameHelper.getRandomCoordsInLand(inBounds); - expect(lat > inBounds.min.lat).toBeTruthy(); - expect(lat < inBounds.max.lat).toBeTruthy(); - expect(lng > inBounds.min.lng).toBeTruthy(); - expect(lng < inBounds.max.lng).toBeTruthy(); - } - }) -}) diff --git a/src/utils/Settings.js b/src/utils/Settings.js deleted file mode 100644 index d7a23cf..0000000 --- a/src/utils/Settings.js +++ /dev/null @@ -1,157 +0,0 @@ -"use strict"; - -const store = require("./sharedStore"); - -/** - * @typedef {object} SettingsProps - * @prop {string} channelName - * @prop {string} token - * @prop {string} cgCmd - * @prop {number} cgCmdCooldown - * @prop {string} cgMsg - * @prop {string} flagsCmd - * @prop {string} flagsCmdMsg - * @prop {string} getUserStatsCmd - * @prop {string} getBestStatsCmd - * @prop {string} clearUserStatsCmd - * @prop {string} mapCmd - * @prop {number} mapCmdCooldown - * @prop {string} randomPlonkCmd - * @prop {boolean} showHasGuessed - * @prop {boolean} showHasAlreadyGuessed - * @prop {boolean} showGuessChanged - * @prop {boolean} showSubmittedPreviousGuess - * @prop {boolean} isMultiGuess - * @prop {number} guessMarkersLimit - */ - -class Settings { - /** @param {Partial} settings */ - constructor({ - channelName = "", - token = "", - cgCmd = "!cg", - cgCmdCooldown = 30, - cgMsg = `Two ways to play: -1. Login with Twitch, make your guess and press guess (spacebar). -2. Paste the command into chat without editing: `, - flagsCmd = "!flags", - flagsCmdMsg = "chatguessr.com/flags", - getUserStatsCmd = "!me", - getBestStatsCmd = "!best", - clearUserStatsCmd = "!clear", - mapCmd = "!map", - mapCmdCooldown = 30, - randomPlonkCmd = "!randomplonk", - showHasGuessed = true, - showHasAlreadyGuessed = true, - showGuessChanged = true, - showSubmittedPreviousGuess = true, - isMultiGuess = false, - guessMarkersLimit = 100, - } = {}) { - this.channelName = channelName; - this.token = token; - this.cgCmd = cgCmd; - this.cgCmdCooldown = cgCmdCooldown; - this.cgMsg = cgMsg; - this.flagsCmd = flagsCmd; - this.flagsCmdMsg = flagsCmdMsg; - this.getUserStatsCmd = getUserStatsCmd; - this.getBestStatsCmd = getBestStatsCmd; - this.clearUserStatsCmd = clearUserStatsCmd; - this.mapCmd = mapCmd; - this.mapCmdCooldown = mapCmdCooldown; - this.randomPlonkCmd = randomPlonkCmd; - this.showHasGuessed = showHasGuessed; - this.showHasAlreadyGuessed = showHasAlreadyGuessed; - this.showGuessChanged = showGuessChanged; - this.showSubmittedPreviousGuess = showSubmittedPreviousGuess; - this.isMultiGuess = isMultiGuess; - this.guessMarkersLimit = guessMarkersLimit; - } - - /** - * @param {{ - * cgCmd: string, - * cgCmdCooldown: number, - * cgMsg: string, - * flagsCmd: string, - * flagsCmdMsg: string, - * clearUserStatsCmd: string, - * getUserStatsCmd: string, - * getBestStatsCmd: string, - * mapCmd: string, - * mapCmdCooldown: number, - * randomPlonkCmd: string, - * showHasGuessed: boolean, - * showHasAlreadyGuessed: boolean, - * showGuessChanged: boolean, - * showSubmittedPreviousGuess: boolean, - * isMultiGuess: boolean, - * guessMarkersLimit: number - * }} globalSettings - */ - saveGlobalSettings(globalSettings) { - this.cgCmd = globalSettings.cgCmd; - this.cgCmdCooldown = globalSettings.cgCmdCooldown; - this.cgMsg = globalSettings.cgMsg; - this.flagsCmd = globalSettings.flagsCmd; - this.flagsCmdMsg = globalSettings.flagsCmdMsg; - this.getUserStatsCmd = globalSettings.getUserStatsCmd; - this.getBestStatsCmd = globalSettings.getBestStatsCmd; - this.clearUserStatsCmd = globalSettings.clearUserStatsCmd; - this.mapCmd = globalSettings.mapCmd; - this.mapCmdCooldown = globalSettings.mapCmdCooldown; - this.randomPlonkCmd = globalSettings.randomPlonkCmd; - this.showHasGuessed = globalSettings.showHasGuessed; - this.showHasAlreadyGuessed = globalSettings.showHasAlreadyGuessed; - this.showGuessChanged = globalSettings.showGuessChanged; - this.showSubmittedPreviousGuess = globalSettings.showSubmittedPreviousGuess; - this.isMultiGuess = globalSettings.isMultiGuess; - this.guessMarkersLimit = globalSettings.guessMarkersLimit; - this.#save(); - } - - /** - * @param {string} channelName - */ - saveTwitchSettings(channelName) { - this.channelName = channelName; - this.#save(); - } - - toJSON() { - return { - channelName: this.channelName, - token: this.token, - cgCmd: this.cgCmd, - cgCmdCooldown: this.cgCmdCooldown, - cgMsg: this.cgMsg, - flagsCmd: this.flagsCmd, - flagsCmdMsg: this.flagsCmdMsg, - getUserStatsCmd: this.getUserStatsCmd, - getBestStatsCmd: this.getBestStatsCmd, - clearUserStatsCmd: this.clearUserStatsCmd, - mapCmd: this.mapCmd, - mapCmdCooldown: this.mapCmdCooldown, - randomPlonkCmd: this.randomPlonkCmd, - showHasGuessed: this.showHasGuessed, - showHasAlreadyGuessed: this.showHasAlreadyGuessed, - showGuessChanged: this.showGuessChanged, - showSubmittedPreviousGuess: this.showSubmittedPreviousGuess, - isMultiGuess: this.isMultiGuess, - guessMarkersLimit: this.guessMarkersLimit, - }; - } - - static read() { - return new Settings(store.get("settings")); - } - - #save() { - store.set("settings", this.toJSON()); - } -} - -module.exports = Settings; diff --git a/src/utils/__mocks__/sharedStore.js b/src/utils/__mocks__/sharedStore.js deleted file mode 100644 index dc76295..0000000 --- a/src/utils/__mocks__/sharedStore.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -class MockStore { - #data; - constructor (data = {}) { - this.#data = data; - } - - setData (data) { - this.#data = data; - } - - get (path) { - return path.split('.').reduce((data, prop) => data?.[prop] ?? null, this.#data); - } -} - -module.exports = new MockStore(); \ No newline at end of file diff --git a/src/utils/builtinFlags.json b/src/utils/builtinFlags.json deleted file mode 100644 index eaf4787..0000000 --- a/src/utils/builtinFlags.json +++ /dev/null @@ -1,72 +0,0 @@ -[ - { "code": "auaboriginal", "names": "Aboriginal", "emoji": "🇦🇺 (Aboriginal)" }, - { "code": "black", "names": "Black", "emoji": "\uD83C\uDFF4" }, - { "code": "caqc", "names": "Quebec", "emoji": "🇨🇦 (QC)" }, - { "code": "checkered", "names": "Checkered flag, Chequered flag, Racing flag", "emoji": "\uD83C\uDFC1" }, - { "code": "esct", "names": "Catalonia, Catalunya, catalunia", "emoji": "🇪🇸 (CT)" }, - { "code": "esga", "names": "Galicia", "emoji": "🇪🇸 (GA)" }, - { "code": "espv", "names": "Basque Country, euskadi, Pais Vasco", "emoji": "🇪🇸 (PV)" }, - { "code": "frbre", "names": "Brittany, BZH, Bretagne", "emoji": "🇫🇷 (BRE)" }, - { "code": "frcor", "names": "Corsica, Corse", "emoji": "🇫🇷 (COR)" }, - { "code": "itsrd", "names": "Sardinia, Sardegna", "emoji": "🇮🇹 (Sardegna)" }, - { "code": "lgbt", "names": "Rainbow, Pride", "emoji": "\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08" }, - { "code": "nzmaori", "names": "Maori", "emoji": "🇳🇿 (Māori)" }, - { "code": "mypg", "names": "Penang", "emoji": "🇲🇾 (Penang)" }, - { "code": "mysb", "names": "Sabah", "emoji": "🇲🇾 (Sabah)" }, - { "code": "myswk", "names": "Sarawak", "emoji": "🇲🇾 (Sarawak)" }, - { "code": "pirate", "names": "Pirate, Jolly Roger", "emoji": "\uD83C\uDFF4\u200D\u2620\uFE0F" }, - { "code": "ussr", "names": "USSR, Soviet union", "emoji": "☭" }, - { "code": "trans", "names": "Transgender", "emoji": "\uD83C\uDFF3\uFE0F\u200D\u26A7\uFE0F" }, - { "code": "usak", "names": "Alaska", "emoji": "🇺🇸 (AK)" }, - { "code": "usal", "names": "Alabama", "emoji": "🇺🇸 (AL)" }, - { "code": "usar", "names": "Arkansas", "emoji": "🇺🇸 (AR)" }, - { "code": "usaz", "names": "Arizona", "emoji": "🇺🇸 (AZ)" }, - { "code": "usca", "names": "California", "emoji": "🇺🇸 (CA)" }, - { "code": "usco", "names": "Colorado", "emoji": "🇺🇸 (CO)" }, - { "code": "usct", "names": "Connecticut", "emoji": "🇺🇸 (CT)" }, - { "code": "usde", "names": "Delaware", "emoji": "🇺🇸 (DE)" }, - { "code": "usfl", "names": "Florida", "emoji": "🇺🇸 (FL)" }, - { "code": "usga", "names": "Georgia state", "emoji": "🇺🇸 (GA)" }, - { "code": "ushi", "names": "Hawaii", "emoji": "🇺🇸 (HI)" }, - { "code": "usia", "names": "Iowa", "emoji": "🇺🇸 (IA)" }, - { "code": "usid", "names": "Idaho", "emoji": "🇺🇸 (ID)" }, - { "code": "usil", "names": "Illinois", "emoji": "🇺🇸 (IL)" }, - { "code": "usin", "names": "Indiana", "emoji": "🇺🇸 (IN)" }, - { "code": "usks", "names": "Kansas", "emoji": "🇺🇸 (KS)" }, - { "code": "usky", "names": "Kentucky", "emoji": "🇺🇸 (KY)" }, - { "code": "usla", "names": "Louisiana", "emoji": "🇺🇸 (LA)" }, - { "code": "usma", "names": "Massachusetts", "emoji": "🇺🇸 (MA)" }, - { "code": "usmd", "names": "Maryland", "emoji": "🇺🇸 (MD)" }, - { "code": "usme", "names": "Maine", "emoji": "🇺🇸 (ME)" }, - { "code": "usmi", "names": "Michigan", "emoji": "🇺🇸 (MI)" }, - { "code": "usmn", "names": "Minnesota", "emoji": "🇺🇸 (MN)" }, - { "code": "usmo", "names": "Missouri", "emoji": "🇺🇸 (MO)" }, - { "code": "usms", "names": "Mississippi", "emoji": "🇺🇸 (MS)" }, - { "code": "usmt", "names": "Montana", "emoji": "🇺🇸 (MT)" }, - { "code": "usnc", "names": "North Carolina", "emoji": "🇺🇸 (NC)" }, - { "code": "usnd", "names": "North Dakota", "emoji": "🇺🇸 (ND)" }, - { "code": "usne", "names": "Nebraska", "emoji": "🇺🇸 (NE)" }, - { "code": "usnh", "names": "New Hampshire", "emoji": "🇺🇸 (NH)" }, - { "code": "usnj", "names": "New Jersey", "emoji": "🇺🇸 (NJ)" }, - { "code": "usnm", "names": "New Mexico", "emoji": "🇺🇸 (NM)" }, - { "code": "usnv", "names": "Nevada", "emoji": "🇺🇸 (NV)" }, - { "code": "usny", "names": "New York", "emoji": "🇺🇸(NY)" }, - { "code": "usoh", "names": "Ohio", "emoji": "🇺🇸 (OH)" }, - { "code": "usok", "names": "Oklahoma", "emoji": "🇺🇸 (OK)" }, - { "code": "usor", "names": "Oregon", "emoji": "🇺🇸 (OR)" }, - { "code": "uspa", "names": "Pennsylvania", "emoji": "🇺🇸 (PA)" }, - { "code": "usri", "names": "Rhode Island", "emoji": "🇺🇸 (RI)" }, - { "code": "ussc", "names": "South Carolina", "emoji": "🇺🇸 (SC)" }, - { "code": "ussd", "names": "South Dakota", "emoji": "🇺🇸 (SD)" }, - { "code": "ustn", "names": "Tennessee", "emoji": "🇺🇸 (TN)" }, - { "code": "ustx", "names": "Texas", "emoji": "🇺🇸 (TX)" }, - { "code": "usut", "names": "Utah", "emoji": "🇺🇸 (UT)" }, - { "code": "usva", "names": "Virginia", "emoji": "🇺🇸 (VA)" }, - { "code": "usvt", "names": "Vermont", "emoji": "🇺🇸 (VT)" }, - { "code": "uswa", "names": "Washington", "emoji": "🇺🇸 (WA)" }, - { "code": "uswi", "names": "Wisconsin", "emoji": "🇺🇸 (WI)" }, - { "code": "uswv", "names": "West Virginia", "emoji": "🇺🇸 (WV)" }, - { "code": "uswy", "names": "Wyoming", "emoji": "🇺🇸 (WY)" }, - { "code": "white", "names": "Surrender, White", "emoji": "\uD83C\uDFF3\uFE0F" }, - { "code": "yu", "names": "Yugoslavia", "emoji": "🇾🇺" } -] diff --git a/src/utils/countryCodesNames.json b/src/utils/countryCodesNames.json deleted file mode 100644 index db54267..0000000 --- a/src/utils/countryCodesNames.json +++ /dev/null @@ -1,255 +0,0 @@ -[ - { "code": "ad", "names": "Andorra" }, - { "code": "ae", "names": "UAE, United Arab Emirates" }, - { "code": "af", "names": "Afghanistan" }, - { "code": "ag", "names": "Antigua and Barbuda" }, - { "code": "ai", "names": "Anguilla" }, - { "code": "aq", "names": "Antarctica" }, - { "code": "al", "names": "Albania" }, - { "code": "am", "names": "Armenia" }, - { "code": "ao", "names": "Angola" }, - { "code": "ar", "names": "Argentina" }, - { "code": "as", "names": "American Samoa" }, - { "code": "at", "names": "Austria" }, - { "code": "au", "names": "Australia" }, - { "code": "aw", "names": "Aruba" }, - { "code": "ax", "names": "Aland Islands" }, - { "code": "az", "names": "Azerbaijan" }, - { "code": "ba", "names": "Bosnia and Herzegovina" }, - { "code": "bb", "names": "Barbados" }, - { "code": "bd", "names": "Bangladesh" }, - { "code": "be", "names": "Belgium" }, - { "code": "bf", "names": "Burkina Faso" }, - { "code": "bg", "names": "Bulgaria" }, - { "code": "bh", "names": "Bahrain" }, - { "code": "bi", "names": "Burundi" }, - { "code": "bj", "names": "Benin" }, - { "code": "bl", "names": "Saint Barthelemy" }, - { "code": "bm", "names": "Bermuda" }, - { "code": "bn", "names": "Brunei" }, - { "code": "bo", "names": "Bolivia" }, - { "code": "br", "names": "Brazil" }, - { "code": "bs", "names": "Bahamas" }, - { "code": "bt", "names": "Bhutan" }, - { "code": "bv", "names": "Bouvet Island" }, - { "code": "bw", "names": "Botswana" }, - { "code": "by", "names": "Belarus" }, - { "code": "bz", "names": "Belize" }, - { "code": "ca", "names": "Canada" }, - { "code": "cc", "names": "Cocos (Keeling) Islands" }, - { "code": "cg", "names": "Congo" }, - { "code": "cd", "names": "Democratic Republic of the Congo" }, - { "code": "cf", "names": "Central African Republic" }, - { "code": "ch", "names": "Switzerland" }, - { "code": "ci", "names": "Cote d'Ivoire, Ivory Coast" }, - { "code": "ck", "names": "Cook Islands" }, - { "code": "cl", "names": "Chile" }, - { "code": "cm", "names": "Cameroon" }, - { "code": "cn", "names": "China" }, - { "code": "co", "names": "Colombia" }, - { "code": "cr", "names": "Costa Rica" }, - { "code": "cu", "names": "Cuba" }, - { "code": "cv", "names": "Cape Verde" }, - { "code": "cw", "names": "Curaçao" }, - { "code": "cx", "names": "Christmas Island" }, - { "code": "cy", "names": "Cyprus" }, - { "code": "cz", "names": "Czech Republic, Czechia" }, - { "code": "de", "names": "Germany" }, - { "code": "dj", "names": "Djibouti" }, - { "code": "dk", "names": "Denmark" }, - { "code": "dm", "names": "Dominica" }, - { "code": "do", "names": "Dominican Republic" }, - { "code": "dz", "names": "Algeria" }, - { "code": "ec", "names": "Ecuador" }, - { "code": "ee", "names": "Estonia" }, - { "code": "eg", "names": "Egypt" }, - { "code": "eh", "names": "Western Sahara" }, - { "code": "er", "names": "Eritrea" }, - { "code": "es", "names": "Spain" }, - { "code": "et", "names": "Ethiopia" }, - { "code": "eu", "names": "Europe" }, - { "code": "fi", "names": "Finland" }, - { "code": "fj", "names": "Fiji" }, - { "code": "fk", "names": "Falkland Islands (Malvinas)" }, - { "code": "fm", "names": "Micronesia" }, - { "code": "fo", "names": "Faroe Islands" }, - { "code": "fr", "names": "France" }, - { "code": "ga", "names": "Gabon" }, - { "code": "gb", "names": "UK, Great Britain, United Kingdom" }, - { "code": "gbeng", "names": "England" }, - { "code": "gbsct", "names": "Scotland" }, - { "code": "gbwls", "names": "Wales" }, - { "code": "gd", "names": "Grenada" }, - { "code": "ge", "names": "Georgia" }, - { "code": "gf", "names": "French Guiana" }, - { "code": "gg", "names": "Guernsey" }, - { "code": "gh", "names": "Ghana" }, - { "code": "gi", "names": "Gibraltar" }, - { "code": "gl", "names": "Greenland" }, - { "code": "gm", "names": "Gambia" }, - { "code": "gn", "names": "Guinea" }, - { "code": "gp", "names": "Guadeloupe" }, - { "code": "gq", "names": "Equatorial Guinea" }, - { "code": "gr", "names": "Greece" }, - { "code": "gs", "names": "South Georgia and the South Sandwich Islands" }, - { "code": "gt", "names": "Guatemala" }, - { "code": "gu", "names": "Guam" }, - { "code": "gw", "names": "Guinea-Bissau" }, - { "code": "gy", "names": "Guyana" }, - { "code": "hk", "names": "Hong Kong" }, - { "code": "hm", "names": "Heard Island and McDonald Islands" }, - { "code": "hn", "names": "Honduras" }, - { "code": "hr", "names": "Croatia" }, - { "code": "ht", "names": "Haiti" }, - { "code": "hu", "names": "Hungary" }, - { "code": "id", "names": "Indonesia" }, - { "code": "ie", "names": "Ireland" }, - { "code": "il", "names": "Israel" }, - { "code": "im", "names": "Isle of Man" }, - { "code": "in", "names": "India" }, - { "code": "io", "names": "British Indian Ocean Territory" }, - { "code": "iq", "names": "Iraq" }, - { "code": "ir", "names": "Iran" }, - { "code": "is", "names": "Iceland" }, - { "code": "it", "names": "Italy" }, - { "code": "je", "names": "Jersey" }, - { "code": "jm", "names": "Jamaica" }, - { "code": "jo", "names": "Jordan" }, - { "code": "jp", "names": "Japan" }, - { "code": "ke", "names": "Kenya" }, - { "code": "kg", "names": "Kyrgyzstan" }, - { "code": "kh", "names": "Cambodia" }, - { "code": "ki", "names": "Kiribati" }, - { "code": "km", "names": "Comoros" }, - { "code": "kn", "names": "Saint Kitts and Nevis" }, - { "code": "kp", "names": "North Korea, DPRK" }, - { "code": "kr", "names": "Korea, South Korea, ROK" }, - { "code": "kw", "names": "Kuwait" }, - { "code": "ky", "names": "Cayman Islands" }, - { "code": "kz", "names": "Kazakhstan" }, - { "code": "la", "names": "Laos" }, - { "code": "lb", "names": "Lebanon" }, - { "code": "lc", "names": "Saint Lucia, St Lucia" }, - { "code": "li", "names": "Liechtenstein" }, - { "code": "lk", "names": "Sri Lanka" }, - { "code": "lr", "names": "Liberia" }, - { "code": "ls", "names": "Lesotho" }, - { "code": "lt", "names": "Lithuania" }, - { "code": "lu", "names": "Luxembourg" }, - { "code": "lv", "names": "Latvia" }, - { "code": "ly", "names": "Libya" }, - { "code": "ma", "names": "Morocco" }, - { "code": "mc", "names": "Monaco" }, - { "code": "md", "names": "Moldova, Moldavia" }, - { "code": "me", "names": "Montenegro" }, - { "code": "mf", "names": "Saint Martin, St Martin" }, - { "code": "mg", "names": "Madagascar" }, - { "code": "mh", "names": "Marshall Islands" }, - { "code": "mk", "names": "North Macedonia" }, - { "code": "ml", "names": "Mali" }, - { "code": "mm", "names": "Myanmar" }, - { "code": "mn", "names": "Mongolia" }, - { "code": "mo", "names": "Macao, Macau" }, - { "code": "mp", "names": "Northern Mariana Islands" }, - { "code": "mq", "names": "Martinique" }, - { "code": "mr", "names": "Mauritania" }, - { "code": "ms", "names": "Montserrat" }, - { "code": "mt", "names": "Malta" }, - { "code": "mu", "names": "Mauritius" }, - { "code": "mv", "names": "Maldives" }, - { "code": "mw", "names": "Malawi" }, - { "code": "mx", "names": "Mexico" }, - { "code": "my", "names": "Malaysia" }, - { "code": "mz", "names": "Mozambique" }, - { "code": "na", "names": "Namibia" }, - { "code": "nc", "names": "New Caledonia" }, - { "code": "ne", "names": "Niger" }, - { "code": "nf", "names": "Norfolk Island" }, - { "code": "ng", "names": "Nigeria" }, - { "code": "ni", "names": "Nicaragua" }, - { "code": "nl", "names": "Netherlands" }, - { "code": "no", "names": "Norway" }, - { "code": "np", "names": "Nepal" }, - { "code": "nr", "names": "Nauru" }, - { "code": "nu", "names": "Niue" }, - { "code": "nz", "names": "New Zealand" }, - { "code": "om", "names": "Oman" }, - { "code": "pa", "names": "Panama" }, - { "code": "pe", "names": "Peru" }, - { "code": "pf", "names": "French Polynesia" }, - { "code": "pg", "names": "Papua New Guinea" }, - { "code": "ph", "names": "Philippines" }, - { "code": "pk", "names": "Pakistan" }, - { "code": "pl", "names": "Poland" }, - { "code": "pm", "names": "Saint Pierre and Miquelon, St Pierre and Miquelon" }, - { "code": "pn", "names": "Pitcairn" }, - { "code": "pr", "names": "Puerto Rico" }, - { "code": "ps", "names": "Palestine" }, - { "code": "pt", "names": "Portugal" }, - { "code": "pw", "names": "Palau" }, - { "code": "py", "names": "Paraguay" }, - { "code": "qa", "names": "Qatar" }, - { "code": "re", "names": "Reunion" }, - { "code": "ro", "names": "Romania" }, - { "code": "rs", "names": "Serbia" }, - { "code": "ru", "names": "Russia" }, - { "code": "rw", "names": "Rwanda" }, - { "code": "sa", "names": "Saudi Arabia" }, - { "code": "sb", "names": "Solomon Islands" }, - { "code": "sc", "names": "Seychelles" }, - { "code": "sd", "names": "Sudan" }, - { "code": "se", "names": "Sweden" }, - { "code": "sg", "names": "Singapore" }, - { "code": "sh", "names": "Saint Helena, Ascension and Tristan da Cunha" }, - { "code": "si", "names": "Slovenia" }, - { "code": "sj", "names": "Svalbard" }, - { "code": "sk", "names": "Slovakia" }, - { "code": "sl", "names": "Sierra Leone" }, - { "code": "sm", "names": "San Marino" }, - { "code": "sn", "names": "Senegal" }, - { "code": "so", "names": "Somalia" }, - { "code": "sr", "names": "Suriname" }, - { "code": "ss", "names": "South Sudan" }, - { "code": "st", "names": "Sao Tome and Principe" }, - { "code": "sv", "names": "El Salvador" }, - { "code": "sx", "names": "Sint Maarten" }, - { "code": "sy", "names": "Syria" }, - { "code": "sz", "names": "Swaziland, eSwatini" }, - { "code": "tb", "names": "Tibet" }, - { "code": "tc", "names": "Turks and Caicos Islands" }, - { "code": "td", "names": "Chad" }, - { "code": "tf", "names": "French Southern Territories" }, - { "code": "tg", "names": "Togo" }, - { "code": "th", "names": "Thailand" }, - { "code": "tj", "names": "Tajikistan" }, - { "code": "tk", "names": "Tokelau" }, - { "code": "tl", "names": "Timor-Leste" }, - { "code": "tm", "names": "Turkmenistan" }, - { "code": "tn", "names": "Tunisia" }, - { "code": "to", "names": "Tonga" }, - { "code": "tr", "names": "Turkey" }, - { "code": "tt", "names": "Trinidad and Tobago" }, - { "code": "tv", "names": "Tuvalu" }, - { "code": "tw", "names": "Taiwan" }, - { "code": "tz", "names": "Tanzania" }, - { "code": "ua", "names": "Ukraine" }, - { "code": "ug", "names": "Uganda" }, - { "code": "us", "names": "US, USA, United States" }, - { "code": "uy", "names": "Uruguay" }, - { "code": "uz", "names": "Uzbekistan" }, - { "code": "va", "names": "Vatican, Vatican City, Holy See" }, - { "code": "vc", "names": "Saint Vincent and the Grenadines" }, - { "code": "ve", "names": "Venezuela" }, - { "code": "vg", "names": "British Virgin Islands" }, - { "code": "vi", "names": "US Virgin Islands" }, - { "code": "vn", "names": "Viet Nam, Vietnam" }, - { "code": "vu", "names": "Vanuatu" }, - { "code": "wf", "names": "Wallis and Futuna" }, - { "code": "ws", "names": "Samoa" }, - { "code": "ye", "names": "Yemen" }, - { "code": "yt", "names": "Mayotte" }, - { "code": "za", "names": "South Africa" }, - { "code": "zm", "names": "Zambia" }, - { "code": "zw", "names": "Zimbabwe" }, - { "code": "xk", "names": "Kosovo" } -] diff --git a/src/utils/domUtils.js b/src/utils/domUtils.js deleted file mode 100644 index 36464b7..0000000 --- a/src/utils/domUtils.js +++ /dev/null @@ -1,23 +0,0 @@ -export function qs(selector, parent = document) { - return parent.querySelector(selector); -} - -/** - * @param {String} type - * @param {Object} attributes - * @param {String[]|HTMLElement[]} children - */ -export function createEl(type, attributes, ...children) { - const el = document.createElement(type); - for (const key in attributes) { - el.setAttribute(key, attributes[key]); - } - children.forEach((child) => { - if (typeof child === "string") { - el.appendChild(document.createTextNode(child)); - } else { - el.appendChild(child); - } - }); - return el; -} diff --git a/src/utils/flags.js b/src/utils/flags.js deleted file mode 100644 index d079fb6..0000000 --- a/src/utils/flags.js +++ /dev/null @@ -1,154 +0,0 @@ -'use strict'; - -const path = require("path"); -const fs = require("fs/promises"); -const { app } = require("electron"); -const builtinFlags = require('./builtinFlags.json'); -const countryCodesNames = require("./countryCodesNames.json"); -const { matchSorter } = require("match-sorter"); - -// The fallback to `/tmp/` is so this module can be used in tests outside electron. -const appDataDir = app?.getPath("userData") ?? '/tmp/'; -const customFlagsDir = path.join(appDataDir, "flags"); - -/** @typedef {{ code: string, names: string, emoji?: string }} Flag */ - -/** - * Country flags included in Chatguessr by default. - * @type {Flag[]} - */ -const countryFlags = countryCodesNames.map(({ code, names }) => ({ - code, - names, - emoji: getCountryEmoji(code), -})); -/** - * Custom flags configured by the streamer. - * @type {Flag[]} - */ -let customFlags = []; - -/** Get all available flags: custom flags, country flags, builtin flags. */ -function getAvailableFlags () { - return [...customFlags, ...countryFlags, ...builtinFlags]; -} - -async function loadCustomFlagMetadata() { - try { - customFlags = JSON.parse(await fs.readFile(path.join(customFlagsDir, 'flags.json'), 'utf8')); - } catch { - // it's OK if it doesn't exist - } -} - -/** - * @param {Flag[]} flags - */ -function setCustomFlags(flags) { - customFlags = flags; -} - -/** - * @param {string} id - * @returns {Promise} - */ -async function findFlagFile(id) { - const customFlagPaths = [ - path.join(customFlagsDir, `${id}.png`), - path.join(customFlagsDir, `${id}.svg`), - ]; - - for (const customFlagPath of customFlagPaths) { - try { - await fs.access(customFlagPath); - return { path: customFlagPath }; - } catch { - // Flag file doesn't exist. Try the next, or fall back to builtin flags. - } - } - - // We always return a path to the builtin SVGs because it's easy. - // electron will return a 404 for us if the file doesn't exist. - return { path: path.join(__dirname, `../../assets/flags/${id.toUpperCase()}.svg`) }; -} - -/** - * Find a flag code based on user input. - * - * @param {string} input - * @returns {string|undefined} - */ -function selectFlag(input) { - const availableFlags = getAvailableFlags(); - - const matches = matchSorter(availableFlags, input, { - keys: [ - 'names', - { threshold: matchSorter.rankings.EQUAL, key: 'code' }, - ], - }); - - return matches[0]?.code; -} - -/** - * Select a random country code. - * - * @return {String} - */ -function randomCountryFlag() { - return countryCodesNames[Math.floor(Math.random() * countryCodesNames.length)].code; -} - -/** - * Convert a country code to a flag emoji. - * - * @param {string} value - */ -function getCountryEmoji(value) { - if (value.length == 2) { - return value - .toUpperCase() - .replace(/./g, (char) => - String.fromCodePoint(char.charCodeAt(0) + 127397) - ); - } else { - const flag = value - .toUpperCase() - .substring(0, 2) - .replace(/./g, (char) => - String.fromCodePoint(char.charCodeAt(0) + 127397) - ); - const region = value - .toUpperCase() - .substring(2) - .replace( - /./g, - (char) => String.fromCodePoint(char.charCodeAt(0) + 127397) + " " - ); - return `${flag} ${region}`.trim(); - } -} - -/** - * Convert a user flag to an emoji or text value. - * - * Country codes get a flag emoji, and custom flags either get their configured emoji, or the empty string. - * - * @param {string|null} value - */ -function getEmoji(value) { - if (!value) return ''; - - const flag = getAvailableFlags() - .find((flag) => flag.code === value.toLowerCase()); - - return flag?.emoji ?? ''; -} - -exports.load = loadCustomFlagMetadata; -exports.findFlagFile = findFlagFile; -exports.selectFlag = selectFlag; -exports.randomCountryFlag = randomCountryFlag; -exports.getEmoji = getEmoji; -exports.TEST_setCustomFlags = setCustomFlags; diff --git a/src/utils/flags.test.js b/src/utils/flags.test.js deleted file mode 100644 index f6d5b22..0000000 --- a/src/utils/flags.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, it, expect } from "vitest"; -import * as flags from "./flags"; - -describe('getEmoji', () => { - it("Check emoji for country flags", () => { - expect(flags.getEmoji("AR")).toBe("🇦🇷"); - expect(flags.getEmoji("GBSCT")).toBe("🇬🇧 🇸 🇨 🇹"); - }); - it("Check emoji for custom builtin flags", () => { - expect(flags.getEmoji("ESCT")).toBe("🇪🇸 (CT)"); - expect(flags.getEmoji("LGBT")).toBe("\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08"); - }); - it("should not crash with empty flags", () => { - expect(flags.getEmoji(null)).toBe(''); - expect(flags.getEmoji('')).toBe(''); - }); -}); - -describe('selectFlag', () => { - it('supports country/region code input', () => { - expect(flags.selectFlag('GB')).toBe('gb'); - expect(flags.selectFlag('uk')).toBe('gb'); - expect(flags.selectFlag('SK')).toBe('sk'); - expect(flags.selectFlag('CAqc')).toBe('caqc'); - expect(flags.selectFlag('mySWK')).toBe('myswk'); - }); - it('supports name input', () => { - expect(flags.selectFlag('Brunei')).toBe('bn'); - expect(flags.selectFlag('korea')).toBe('kr'); - expect(flags.selectFlag('dprk')).toBe('kp'); - expect(flags.selectFlag('England')).toBe('gbeng'); - expect(flags.selectFlag('alabama')).toBe('usal'); - expect(flags.selectFlag('pride')).toBe('lgbt'); - expect(flags.selectFlag('lgbt')).toBe('lgbt'); - }); - it('matches custom names', () => { - flags.TEST_setCustomFlags([ - { "code": "corgipasta", "names": "corgipasta", "emoji": "😳" }, - { "code": "eviecaps", "names": "evie, eviecaps", "emoji": "🏴‍☠️" }, - ]); - - expect(flags.selectFlag('evie')).toBe('eviecaps'); - expect(flags.selectFlag('ie')).toBe('ie'); - expect(flags.selectFlag('corgipasta')).toBe('corgipasta'); - expect(flags.selectFlag('pasta')).toBe('corgipasta'); - }); -}); diff --git a/src/utils/globalJquery.js b/src/utils/globalJquery.js deleted file mode 100644 index dfe7e99..0000000 --- a/src/utils/globalJquery.js +++ /dev/null @@ -1,2 +0,0 @@ -import $ from "jquery"; -window.$ = window.jQuery = $; \ No newline at end of file diff --git a/src/utils/mods/blinkMode.js b/src/utils/mods/blinkMode.js deleted file mode 100644 index 119e30b..0000000 --- a/src/utils/mods/blinkMode.js +++ /dev/null @@ -1,188 +0,0 @@ -// @ts-nocheck -export function blinkMode() { - let timeLimit = 0.8; - let roundDelay = 1; - - const classicGameGuiHTML = ` -
-
-
-

Blink Mode settings

-
-
-
-
-
-
-
- Enabled - -
- -
- -
- -
- -
-
-
-
- `; - - if (localStorage.getItem("blinkEnabled") == null) { - localStorage.setItem("blinkEnabled", "disabled"); - } - - if (localStorage.getItem("blinkTime") == null || isNaN(localStorage.getItem("blinkTime"))) { - localStorage.setItem("blinkTime", timeLimit); - } - - if (localStorage.getItem("delayTime") == null || isNaN(localStorage.getItem("delayTime"))) { - localStorage.setItem("delayTime", roundDelay); - } - - timeLimit = parseFloat(localStorage.getItem("blinkTime")); - roundDelay = parseFloat(localStorage.getItem("delayTime")); - - window.toggleBlinkMode = (e) => { - localStorage.setItem("blinkEnabled", e.checked ? "enabled" : "disabled"); - if (!e.checked) { - try { - showPanoramaCached(); - } catch {} - } - - if (document.querySelector("#enableScript")) { - document.querySelector("#enableScript").checked = e.checked; - } - }; - - window.changeBlinkTime = (e) => { - if (!isNaN(e.value)) { - localStorage.setItem("blinkTime", parseFloat(e.value)); - timeLimit = parseFloat(e.value); - - if (document.querySelector("#blinkTimeText")) { - document.querySelector("#blinkTimeText").textContent = e.value + " sec"; - } - } - }; - - window.changeDelayTime = (e) => { - if (!isNaN(e.value)) { - localStorage.setItem("delayTime", parseFloat(e.value)); - roundDelay = parseFloat(e.value); - - if (document.querySelector("#delayTimeText")) { - document.querySelector("#delayTimeText").textContent = e.value + " sec"; - } - } - }; - - const checkInsertGui = () => { - if (document.querySelector('[class^="radio-box_root__"]') && document.querySelector("#enableScript") === null) { - document - .querySelector('[class^="section_sectionMedium__"]') - .insertAdjacentHTML("beforeend", classicGameGuiHTML); - - if (localStorage.getItem("blinkEnabled") === "enabled") { - document.querySelector("#enableScript").checked = true; - } - - document.querySelector("#blinkTime").value = timeLimit; - document.querySelector("#delayTime").value = roundDelay; - document.querySelector("#blinkTimeText").textContent = timeLimit + " sec"; - document.querySelector("#delayTimeText").textContent = roundDelay + " sec"; - } - }; - - let mapRoot = null; - function getMapRoot() { - return document.querySelector("[data-qa=panorama]"); - } - - function hidePanorama() { - mapRoot = getMapRoot() || mapRoot; - hidePanoramaCached(); - } - - function hidePanoramaCached() { - mapRoot.style.filter = "brightness(0%)"; - } - - function showPanorama() { - mapRoot = getMapRoot() || mapRoot; - showPanoramaCached(); - } - - function showPanoramaCached() { - mapRoot.style.filter = "brightness(100%)"; - } - - function isLoading() { - return ( - document.querySelector('[class^="fullscreen-spinner_root__"]') || - !document.querySelector(".widget-scene-canvas") - ); - } - - let wasBackdropThereOrLoading = false; - function isBackdropThereOrLoading() { - return isLoading() || document.querySelector('[class^="result-layout_root__"]'); - } - - let showTimeoutID = null; - let hideTimeoutID = null; - function triggerBlink() { - hidePanorama(); - clearTimeout(showTimeoutID); - showTimeoutID = setTimeout(showPanorama, roundDelay * 1000); - clearTimeout(hideTimeoutID); - hideTimeoutID = setTimeout(hidePanorama, (timeLimit + roundDelay) * 1000); - } - - const observer = new MutationObserver(() => { - checkInsertGui(); - - if (localStorage.getItem("blinkEnabled") === "enabled") { - if (isBackdropThereOrLoading()) { - wasBackdropThereOrLoading = true; - if (!isLoading()) hidePanorama(); - } else if (wasBackdropThereOrLoading) { - wasBackdropThereOrLoading = false; - triggerBlink(); - } - } - }); - - observer.observe(document.body, { - subtree: true, - childList: true, - }); -} diff --git a/src/utils/mods/drParseNoCar.js b/src/utils/mods/drParseNoCar.js deleted file mode 100644 index 354f769..0000000 --- a/src/utils/mods/drParseNoCar.js +++ /dev/null @@ -1,188 +0,0 @@ -// @ts-nocheck -export function drParseNoCar() { - const classicGameGuiHTML = ` -
-
-
-

NCNC settings

-
-
-
-
-
-
- No car - -
-
- No compass - -
-
-
- `; - - const REMOVE_COMPASS_CSS = '[data-qa="compass"], [class^="panorama-compass_"] { display: none; }'; - - const compassRemover = document.createElement("style"); - compassRemover.textContent = REMOVE_COMPASS_CSS; - - if (localStorage.getItem("noCarEnabled") == null) { - localStorage.setItem("noCarEnabled", "disabled"); - } - - if (localStorage.getItem("noCompassEnabled") == null) { - localStorage.setItem("noCompassEnabled", "disabled"); - } - - if (localStorage.getItem("noCarEnabled") === "enabled") { - noCarScript(); - } - - if (localStorage.getItem("noCompassEnabled") === "enabled") { - document.head.append(compassRemover); - } - - window.toggleNoCarMode = (e) => { - localStorage.setItem("noCarEnabled", e.checked ? "enabled" : "disabled"); - - if (document.querySelector("#enableNoCar")) { - document.querySelector("#enableNoCar").checked = e.checked; - } - location.reload(); - }; - - window.toggleNoCompassMode = (e) => { - localStorage.setItem("noCompassEnabled", e.checked ? "enabled" : "disabled"); - - if (document.querySelector("#enableNoCompass")) { - document.querySelector("#enableNoCompass").checked = e.checked; - } - - if (e.checked) { - document.head.append(compassRemover); - } else { - compassRemover.remove(); - } - }; - - const checkInsertGui = () => { - if (document.querySelector('[class^="radio-box_root__"]') && document.querySelector("#enableNoCar") === null) { - document - .querySelector('[class^="section_sectionMedium__"]') - .insertAdjacentHTML("beforeend", classicGameGuiHTML); - - if (localStorage.getItem("noCarEnabled") === "enabled") { - document.querySelector("#enableNoCar").checked = true; - } - - if (localStorage.getItem("noCompassEnabled") === "enabled") { - document.querySelector("#enableNoCompass").checked = true; - } - } - }; - - const observer = new MutationObserver(() => { - checkInsertGui(); - }); - - observer.observe(document.body, { - subtree: true, - childList: true, - }); -} - -function noCarScript() { - const OPTIONS = { colorR: 0.5, colorG: 0.5, colorB: 0.5 }; - const vertexOld = - "const float f=3.1415926;varying vec3 a;uniform vec4 b;attribute vec3 c;attribute vec2 d;uniform mat4 e;void main(){vec4 g=vec4(c,1);gl_Position=e*g;a=vec3(d.xy*b.xy+b.zw,1);a*=length(c);}"; - const fragOld = - "precision highp float;const float h=3.1415926;varying vec3 a;uniform vec4 b;uniform float f;uniform sampler2D g;void main(){vec4 i=vec4(texture2DProj(g,a).rgb,f);gl_FragColor=i;}"; - const vertexNew = ` - const float f=3.1415926; - varying vec3 a; - varying vec3 potato; - uniform vec4 b; - attribute vec3 c; - attribute vec2 d; - uniform mat4 e; - void main(){ - vec4 g=vec4(c,1); - gl_Position=e*g; - a = vec3(d.xy * b.xy + b.zw,1); - a *= length(c); - potato = vec3(d.xy, 1.0) * length(c); - } - `; - - const fragNew = ` - precision highp float; - const float h=3.1415926; - varying vec3 a; - varying vec3 potato; - uniform vec4 b; - uniform float f; - uniform sampler2D g; - void main(){ - - vec2 aD = potato.xy / a.z; - float thetaD = aD.y; - - float thresholdD1 = 0.6; - float thresholdD2 = 0.7; - - float x = aD.x; - float y = abs(4.0*x - 2.0); - float phiD = smoothstep(0.0, 1.0, y > 1.0 ? 2.0 - y : y); - - vec4 i = vec4(thetaD > mix(thresholdD1, thresholdD2, phiD) - ? vec3(float(${OPTIONS.colorR}), float(${OPTIONS.colorG}), float(${OPTIONS.colorB})) // texture2DProj(g,a).rgb * 0.25 - : texture2DProj(g,a).rgb,f); - gl_FragColor=i; - } - `; - - /** @param {WebGLRenderingContext | WebGL2RenderingContext} ctx */ - function installShaderSource(ctx) { - const g = ctx.shaderSource; - /** @type {WebGLRenderingContext['shaderSource']} */ - function shaderSource(...args) { - if (typeof args[1] === "string") { - let glsl = args[1]; - if (glsl === vertexOld) glsl = vertexNew; - else if (glsl === fragOld) glsl = fragNew; - return g.call(this, args[0], glsl); - } - return g.apply(this, args); - } - shaderSource.bestcity = "bintulu"; - ctx.shaderSource = shaderSource; - } - - /** @param {HTMLCanvasElement} el */ - function installGetContext(el) { - const g = el.getContext; - el.getContext = function (...args) { - if (args[0] === "webgl" || args[0] === "webgl2") { - /** @type {WebGLRenderingContext | WebGL2RenderingContext} */ - const ctx = g.apply(this, args); - // @ts-ignore TS2339 - if (ctx && ctx.shaderSource && ctx.shaderSource.bestcity !== "bintulu") { - installShaderSource(ctx); - } - return ctx; - } - return g.apply(this, args); - }; - } - - const createElement = document.createElement.bind(document); - document.createElement = function (tagName, options) { - if (tagName === "canvas" || tagName === "CANVAS") { - const el = createElement("canvas"); - installGetContext(el); - return el; - } - return createElement(tagName, options); - }; -} diff --git a/src/utils/mods/extenssrMenuItemsPlugin.ts b/src/utils/mods/extenssrMenuItemsPlugin.ts deleted file mode 100644 index cce1111..0000000 --- a/src/utils/mods/extenssrMenuItemsPlugin.ts +++ /dev/null @@ -1,225 +0,0 @@ -// Adapted from: -// https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/src/api/maps.ts -// https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/src/content_scripts/plugins/global/menu_items_plugin.ts -// https://gitlab.com/nonreviad/extenssr/-/blob/c795a07e0eb64cb5b32d60e6f3784b044becb1c1/src/content_scripts/endpoint_transition_handler.ts - -import axios from 'axios' -import whenDomReady from 'when-dom-ready' - -type MapCreator = { - email?: string - nick: string -} - -type Map = { - id: string, - name: string, - slug: string, - description?: string, - url?: string, - playUrl?: string, - creator?: MapCreator -} - -class MapsApi { - private client = axios.create({ baseURL: 'https://www.geoguessr.com' }) - - async getMapData(mapId: string): Promise { - return (await this.client.get(`/api/maps/${mapId}`)).data - } - - async getMyMaps(page = 0, count = 25): Promise { - const { data } = await this.client.get('/api/v3/profiles/maps', { - params: { page, count }, - }) - - return data - } - - async getLikedMaps(page = 0, count = 25): Promise { - const { data } = await this.client.get('/api/v3/likes', { - params: { page, count }, - }) - - return data - } -} - -const DESELECTED_MENU_ITEM_SELECTOR = 'header nav li:not([class*="selected"])' - -const customMenuItemTemplate = document.createElement('div') -customMenuItemTemplate.append( - document.createElement('a'), -) -Object.assign(customMenuItemTemplate.style, { - display: 'flex', - flex: '0 0 auto', - height: '100%', -}) -Object.assign(customMenuItemTemplate.querySelector('a').style, { - color: 'white', - fontWeight: '700', - padding: '1rem', - display: 'block', - textTransform: 'uppercase', -}) - -type SubMenuItem = { - href: string, - textContent: string, -} - -export default class MenuItemsPlugin { - private api: MapsApi | undefined - private myMaps: Map[] | undefined - private likedMaps: Map[] | undefined - private observer: MutationObserver | undefined - private initialLoad = true - - constructor() { - this.api = new MapsApi() - } - - onEndpointChange(path: string): void { - // In-game screens have no `
` element - const header = document.querySelector('header') - if (document.querySelector('[data-qa="extenssr__nav-item"]') || !header) { - return - } - - // We might inject before the React tree hydrates, in that case React will remove our - // injected elements again, so we need to add them back. - if (this.initialLoad) { - this.initialLoad = false - this.observer = new MutationObserver(() => { - queueMicrotask(() => this.onEndpointChange(path)) - }) - this.observer.observe(header, { childList: true, subtree: true }) - } else if (this.observer) { - this.observer.disconnect() - this.observer = null - } - - const referenceElement = document.querySelector(DESELECTED_MENU_ITEM_SELECTOR) as HTMLLIElement - ?? customMenuItemTemplate - const container = referenceElement.closest('ol') ?? document.querySelector('[data-qa="header-current-user-pin"]')?.parentNode - - - const createMenuItem = (props: { href: string, textContent: string, subMenu?: () => Promise }) => { - const li = referenceElement.cloneNode(true) as HTMLLIElement - li.setAttribute('data-qa', 'extenssr__nav-item') - - const { href, textContent } = props - Object.assign(li.querySelector('a')!, { href, textContent }) - - if (props.subMenu) { - const overflows = [container?.parentNode, container?.parentNode?.parentNode] as HTMLDivElement[] - - let controller: AbortController - li.addEventListener('mouseenter', () => { - controller = new AbortController() - this.showMenu(li, props.subMenu!, controller.signal) - for (const el of overflows) { - el.style.overflow = 'visible' - } - }) - li.addEventListener('mouseleave', () => { - controller?.abort() - controller = null - li.querySelector('[data-qa="extenssr__nav-submenu"]')?.remove() - for (const el of overflows) { - el.style.overflow = '' - } - }) - } - - return li - } - - const communityMaps = createMenuItem({ - href: '/community/maps', - textContent: 'Community Maps' - }) - - const mapMaker = createMenuItem({ - href: '/me/maps', - textContent: 'My Maps', - subMenu: async () => { - this.myMaps ??= await this.api.getMyMaps(0, 25) - const maps = this.myMaps.map((map: Map) => ({ - href: map.url, - textContent: map.name, - })) - return maps - } - }) - - const likedMaps = createMenuItem({ - href: '/me/likes', - textContent: 'Liked Maps', - subMenu: async () => { - this.likedMaps ??= await this.api.getLikedMaps(0, 25) - return this.likedMaps.map((map: Map) => ({ - href: map.url, - textContent: map.name, - })) - } - }) - - if (referenceElement.tagName === 'LI') { - container.append(communityMaps, mapMaker, likedMaps) - } else { - container?.insertBefore(likedMaps, document.querySelector('[data-qa="header-current-user-pin"]')) - container?.insertBefore(mapMaker, likedMaps) - container?.insertBefore(communityMaps, mapMaker) - } - } - - private showMenu(reference: HTMLElement, items: () => Promise, signal: AbortSignal) { - const subMenu = document.createElement('ol') - subMenu.classList.add('extenssr__nav-submenu') - subMenu.setAttribute('data-qa', 'extenssr__nav-submenu') - - items().then((list) => { - subMenu.replaceChildren() - subMenu.append(...list.map((item) => { - const li = document.createElement('li') - const a = document.createElement('a') - Object.assign(a, item) - li.append(a) - return li - })) - - if (!signal.aborted) { - reference.append(subMenu) - } - }) - } -} - -const plugin = new MenuItemsPlugin() -whenDomReady().then(observeNavigation) - -function observeNavigation() { - const pathChange = () => plugin.onEndpointChange(window.location.pathname) - - const observer = new MutationObserver((mutations: MutationRecord[]) => { - for (const mutation of mutations) { - for (const addition of mutation.addedNodes) { - if (addition.nodeType !== Node.ELEMENT_NODE) { - continue - } - const element = addition as HTMLElement - if (element && element.getAttribute('property') === 'og:url') { - pathChange() - return - } - } - } - }) - observer.observe(document.head, { - childList: true, - subtree: true, - }) - pathChange() -} diff --git a/src/utils/mods/satelliteMode.js b/src/utils/mods/satelliteMode.js deleted file mode 100644 index 8f68747..0000000 --- a/src/utils/mods/satelliteMode.js +++ /dev/null @@ -1,104 +0,0 @@ -// @ts-nocheck -export function satelliteMode() { - let boundsLimit = 10; - - const classicGameGuiHTML = ` -
-
-
-

Satellite Mode settings

-
-
-
- -
-
-
- Enabled - -
- -
- -
-
-
- `; - - if (localStorage.getItem("satelliteModeEnabled") == null) { - localStorage.setItem("satelliteModeEnabled", "disabled"); - } - - if ( - localStorage.getItem("satelliteModeBoundsLimit") == null || - isNaN(localStorage.getItem("satelliteModeBoundsLimit")) - ) { - localStorage.setItem("satelliteModeBoundsLimit", boundsLimit); - } - - boundsLimit = parseInt(localStorage.getItem("satelliteModeBoundsLimit")); - - window.toggleSatelliteMode = (e) => { - localStorage.setItem("satelliteModeEnabled", e.checked ? "enabled" : "disabled"); - - if (document.querySelector("#enableSatelliteMode")) { - document.querySelector("#enableSatelliteMode").checked = e.checked; - } - }; - - window.changeBoundsLimit = (e) => { - if (!isNaN(e.value)) { - localStorage.setItem("satelliteModeBoundsLimit", parseInt(e.value)); - boundsLimit = parseInt(e.value); - - if (document.querySelector("#boundsLimitText")) { - document.querySelector("#boundsLimitText").textContent = e.value + " km"; - } - } - }; - - const checkInsertGui = () => { - // Play page for classic games - if ( - document.querySelector('[class^="radio-box_root__"]') && - document.querySelector("#enableSatelliteMode") === null - ) { - document - .querySelector('[class^="section_sectionMedium__"]') - .insertAdjacentHTML("beforeend", classicGameGuiHTML); - - if (localStorage.getItem("satelliteModeEnabled") === "enabled") { - document.querySelector("#enableSatelliteMode").checked = true; - } - - document.querySelector("#boundsLimit").value = boundsLimit; - document.querySelector("#boundsLimitText").textContent = boundsLimit + " km"; - } - }; - - const observer = new MutationObserver(() => { - checkInsertGui(); - }); - - observer.observe(document.body, { - subtree: true, - childList: true, - }); -} diff --git a/src/utils/sharedStore.js b/src/utils/sharedStore.js deleted file mode 100644 index ae08298..0000000 --- a/src/utils/sharedStore.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -const ElectronStore = require("electron-store"); - -/** - * @typedef {object} LegacyUser - * @prop {String} user - * @prop {String} username - * @prop {String} flag - * @prop {Number} streak - * @prop {Number} bestStreak - * @prop {Number} correctGuesses - * @prop {Number} nbGuesses - * @prop {Number} perfects - * @prop {Number} victories - * @prop {number|null} meanScore - * @prop {import("../types").LatLng|null} previousGuess - * @prop {import("../types").LatLng|null} lastLocation - */ - -/** - * @typedef {{ - * settings: import('./Settings').SettingsProps, - * users: Record, - * lastRoundPlayers: void, - * lastLocation: import('../types').LatLng | undefined, - * isSatellite: boolean, - * session: import('@supabase/supabase-js').Session | null, - * current_version: string, - * }} Schema - */ - -/** @type {ElectronStore} */ -const store = new ElectronStore(); - -module.exports = store; diff --git a/src/utils/supabase.js b/src/utils/supabase.js deleted file mode 100644 index b45669a..0000000 --- a/src/utils/supabase.js +++ /dev/null @@ -1,6 +0,0 @@ -import { createClient } from "@supabase/supabase-js"; - -const supabaseUrl = process.env.SUPABASE_URL; -const supabaseAnonKey = process.env.SUPABASE_ANON_KEY; - -export const supabase = createClient(supabaseUrl, supabaseAnonKey); diff --git a/tsconfig.json b/tsconfig.json index 3d4d467..31bac6e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,4 @@ { - "extends": "@tsconfig/node16/tsconfig.json", - "compilerOptions": { - "lib": ["es2021", "dom", "dom.iterable"], - "noEmit": true, - "strict": false, - "allowJs": true, - "checkJs": true, - "moduleResolution": "node", - "resolveJsonModule": true, - "allowSyntheticDefaultImports": true - }, - "include": [ - "src/modules.d.ts", - "src/types.d.ts", - "src/**/*.js", - "src/utils/countryCodes.json", - "src/utils/countryCodesNames.json" - ], - "exclude": [] + "files": [], + "references": [{ "path": "./tsconfig.node.json" }, { "path": "./tsconfig.web.json" }] } diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..c516877 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,19 @@ +{ + "exclude": ["src/renderer"], + "compilerOptions": { + "strict": true, + "target": "esnext", + "module": "esnext", + "esModuleInterop": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noEmit": true + }, +} diff --git a/tsconfig.web.json b/tsconfig.web.json new file mode 100644 index 0000000..8f55cd5 --- /dev/null +++ b/tsconfig.web.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "module": "esnext", + "esModuleInterop": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noEmit": true, + "paths": { + "@/*": ["./src/renderer/*"] + } + } +} diff --git a/vite.main.config.ts b/vite.main.config.ts new file mode 100644 index 0000000..ff15d1d --- /dev/null +++ b/vite.main.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from 'vite' +import pkg from './package.json' + +// https://vitejs.dev/config +export default defineConfig({ + // resolve: { + // // Some libs that can run in both Web and Node.js, such as `axios`, we need to tell Vite to build them in Node.js. + // // @ts-expect-error (browserField is deprecated, but i couldn't get it working with mainFields for now) + // browserField: false, + // conditions: ['node'], + // mainFields: ['module', 'jsnext:main', 'jsnext'] + // }, + build: { + rollupOptions: { + // external: ['better-sqlite3', 'coordinate_to_country', 'bufferutil', 'utf-8-validate'], + // Some third-party Node.js libraries may not be built correctly by Vite, + // we can use `external` to exclude them to ensure they work correctly. + external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}) + } + } +}) diff --git a/vite.renderer.config.ts b/vite.renderer.config.ts new file mode 100644 index 0000000..db83838 --- /dev/null +++ b/vite.renderer.config.ts @@ -0,0 +1,13 @@ +import path from 'path' +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import svgLoader from 'vite-svg-loader' + +// https://vitejs.dev/config +export default defineConfig({ + plugins: [vue(), svgLoader()], + define: { 'process.env': {} }, + resolve: { + alias: { '@': path.resolve(__dirname, './src/renderer') } + } +})