diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..485eb66
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,3 @@
+dist
+node_modules
+tailwind.config.ts
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..54181d5
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,40 @@
+{
+ "env": {
+ "browser": true,
+ "es6": true,
+ "node": true,
+ },
+ "extends": [
+ "eslint:recommended",
+ "plugin:react/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:react-hooks/recommended",
+ "plugin:import/recommended",
+ "plugin:jsx-a11y/recommended",
+ "plugin:tailwindcss/recommended",
+ "prettier",
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaFeatures": {
+ "jsx": true,
+ },
+ "ecmaVersion": "latest",
+ "sourceType": "module",
+ },
+ "plugins": ["react", "@typescript-eslint", "react-hooks", "import", "jsx-a11y", "prettier"],
+ "settings": {
+ "react": {
+ "version": "detect",
+ },
+ },
+ "rules": {
+ "react/react-in-jsx-scope": "off",
+ "import/no-unresolved": "off",
+ "@typescript-eslint/consistent-type-imports": "error",
+ },
+ "globals": {
+ "chrome": "readonly",
+ },
+ "ignorePatterns": ["watch.js", "dist/**"],
+}
diff --git a/.example.env b/.example.env
new file mode 100644
index 0000000..7507c20
--- /dev/null
+++ b/.example.env
@@ -0,0 +1 @@
+VITE_EXAMPLE=example
\ No newline at end of file
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..c50eb91
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @Jonghakseo
\ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..e5ab532
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: Jonghakseo
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..a144fa7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,32 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug
+assignees: Jonghakseo
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Desktop (please complete the following information):**
+ - OS: [e.g. Mac, Window, Linux]
+ - Browser [e.g. chrome, firefox]
+ - Node Version [e.g. 18.19.1]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..f076f7a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: enhancement
+assignees: Jonghakseo
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml
new file mode 100644
index 0000000..dffe542
--- /dev/null
+++ b/.github/auto_assign.yml
@@ -0,0 +1,30 @@
+# Set to true to add reviewers to pull requests
+addReviewers: true
+
+# Set to true to add assignees to pull requests
+addAssignees: author
+
+# A list of reviewers to be added to pull requests (GitHub user name)
+reviewers:
+ - Jonghakseo
+
+# A number of reviewers added to the pull request
+# Set 0 to add all the reviewers (default: 0)
+numberOfReviewers: 0
+
+# A list of assignees, overrides reviewers if set
+# assignees:
+# - assigneeA
+
+# A number of assignees to add to the pull request
+# Set to 0 to add all of the assignees.
+# Uses numberOfReviewers if unset.
+# numberOfAssignees: 2
+
+# A list of keywords to be skipped the process that add reviewers if pull requests include it
+# skipKeywords:
+# - wip
+
+filterLabels:
+ exclude:
+ - dependencies
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..3a3cce5
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "npm" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "weekly"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..a3a4409
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,23 @@
+
+
+> `*` denotes required fields
+
+## Priority*
+
+- [ ] High: This PR needs to be merged first, before other tasks.
+- [x] Medium: This PR should be merged quickly to prevent conflicts due to common changes. (default)
+- [ ] Low: This PR does not affect other tasks, so it can be merged later.
+
+## Purpose of the PR*
+
+
+## Changes*
+
+
+## How to check the feature
+
+
+
+
+## Reference
+
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 0000000..3c25536
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,21 @@
+# Number of days of inactivity before an Issue or Pull Request becomes stale
+daysUntilStale: 90
+# Number of days of inactivity before a stale Issue or Pull Request is closed
+daysUntilClose: 30
+# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
+exemptLabels:
+ - pinned
+ - security
+# Label to use when marking as stale
+staleLabel: stale
+# Comment to post when marking as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+# Comment to post when removing the stale label. Set to `false` to disable
+unmarkComment: false
+# Comment to post when closing a stale Issue or Pull Request. Set to `false` to disable
+closeComment: true
+# Limit to only `issues` or `pulls`
+only: issues
diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml
new file mode 100644
index 0000000..f4c725e
--- /dev/null
+++ b/.github/workflows/auto-assign.yml
@@ -0,0 +1,12 @@
+name: 'Auto Assign'
+on:
+ pull_request:
+ types: [opened, ready_for_review]
+
+jobs:
+ add-reviews:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: kentaro-m/auto-assign-action@v1.2.5
+ with:
+ configuration-path: '.github/auto_assign.yml'
diff --git a/.github/workflows/build-zip.yml b/.github/workflows/build-zip.yml
new file mode 100644
index 0000000..7a99be9
--- /dev/null
+++ b/.github/workflows/build-zip.yml
@@ -0,0 +1,27 @@
+name: Build And Upload Extension Zip Via Artifact
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: pnpm/action-setup@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version-file: '.nvmrc'
+ cache: pnpm
+
+ - run: pnpm install --frozen-lockfile --prefer-offline
+
+ - run: pnpm build
+
+ - uses: actions/upload-artifact@v4
+ with:
+ path: dist/*
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
new file mode 100644
index 0000000..4c55b5e
--- /dev/null
+++ b/.github/workflows/e2e.yml
@@ -0,0 +1,34 @@
+name: Run E2E Tests
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ chrome:
+ name: E2E tests for Chrome
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: pnpm/action-setup@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version-file: '.nvmrc'
+ cache: pnpm
+ - run: pnpm install --frozen-lockfile --prefer-offline
+ - run: pnpm e2e
+
+ firefox:
+ name: E2E tests for Firefox
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: pnpm/action-setup@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version-file: '.nvmrc'
+ cache: pnpm
+ - run: pnpm install --frozen-lockfile --prefer-offline
+ - run: pnpm e2e:firefox
diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml
new file mode 100644
index 0000000..bdac30b
--- /dev/null
+++ b/.github/workflows/greetings.yml
@@ -0,0 +1,16 @@
+name: Greetings
+
+on: [pull_request_target, issues]
+
+jobs:
+ greeting:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/first-interaction@v1
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-message: 'Thank you for your contribution. We will check and reply to you as soon as possible.'
+ pr-message: 'Thank you for your contribution. We will check and reply to you as soon as possible.'
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..b6bb8f8
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,23 @@
+name: Lint Check
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+
+jobs:
+ eslint:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: pnpm/action-setup@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version-file: '.nvmrc'
+ cache: pnpm
+
+ - run: pnpm install --frozen-lockfile --prefer-offline
+
+ - run: pnpm lint
diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml
new file mode 100644
index 0000000..2b962af
--- /dev/null
+++ b/.github/workflows/prettier.yml
@@ -0,0 +1,30 @@
+name: Formating validation
+
+on:
+ pull_request:
+ push:
+ branches: [main]
+
+jobs:
+ prettier:
+ name: Prettier Check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v2
+
+ - name: Run Prettier
+ id: prettier-run
+ uses: rutajdash/prettier-cli-action@v1.0.0
+ with:
+ config_path: ./.prettierrc
+ file_pattern: "*.{js,jsx,ts,tsx,json}"
+
+ # This step only runs if prettier finds errors causing the previous step to fail
+ # This steps lists the files where errors were found
+ - name: Prettier Output
+ if: ${{ failure() }}
+ shell: bash
+ run: |
+ echo "The following files aren't formatted properly:"
+ echo "${{steps.prettier-run.outputs.prettier_output}}"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..10d229f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+# dependencies
+**/node_modules
+
+# testing
+**/coverage
+
+# build
+**/dist
+**/build
+**/dist-zip
+
+# env
+**/.env.*
+**/.env
+
+# etc
+.DS_Store
+.idea
+**/.turbo
+
+# compiled
+chrome-extension/public/manifest.json
+**/tailwind-output.css
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100644
index 0000000..409035c
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1 @@
+pnpm dlx lint-staged --allow-empty
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..2687d1f
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,2 @@
+public-hoist-pattern[]=@testing-library/dom
+engine-strict=true
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 0000000..1d9b783
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+22.12.0
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..822a463
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,11 @@
+dist
+node_modules
+.gitignore
+.github
+.eslintignore
+.husky
+.nvmrc
+.prettierignore
+LICENSE
+*.md
+pnpm-lock.yaml
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..0196fc4
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,9 @@
+{
+ "trailingComma": "all",
+ "semi": true,
+ "singleQuote": true,
+ "arrowParens": "avoid",
+ "printWidth": 120,
+ "bracketSameLine": true,
+ "htmlWhitespaceSensitivity": "strict"
+}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d8c6624
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2024 Seo Jong Hak
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..0477873
--- /dev/null
+++ b/README.md
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+> This boilerplate
+> has [Legacy version](https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/tree/legacy)
+
+
+
+> [!NOTE]
+> This project is listed in the [Awesome Vite](https://github.com/vitejs/awesome-vite)
+
+> [!TIP]
+> Share storage state between all pages
+>
+> https://github.com/user-attachments/assets/3b8e189f-6443-490e-a455-4f9570267f8c
+
+## Table of Contents
+
+- [Intro](#intro)
+- [Features](#features)
+- [Structure](#structure)
+ - [ChromeExtension](#structure-chrome-extension)
+ - [Packages](#structure-packages)
+ - [Pages](#structure-pages)
+- [Getting started](#getting-started)
+ - [Chrome](#getting-started-chrome)
+ - [Firefox](#getting-started-firefox)
+- [Install dependency](#install-dependency)
+ - [For root](#install-dependency-for-root)
+ - [For module](#install-dependency-for-module)
+- [Community](#community)
+- [Reference](#reference)
+- [Star History](#star-history)
+- [Contributors](#contributors)
+
+## Intro
+
+This boilerplate helps you create Chrome/Firefox extensions using React and Typescript. It improves
+the build speed and development experience by using Vite and Turborepo.
+
+## Features
+
+- [React18](https://reactjs.org/)
+- [TypeScript](https://www.typescriptlang.org/)
+- [Tailwindcss](https://tailwindcss.com/)
+- [Vite](https://vitejs.dev/) with [Rollup](https://rollupjs.org/)
+- [Turborepo](https://turbo.build/repo)
+- [Prettier](https://prettier.io/)
+- [ESLint](https://eslint.org/)
+- [Chrome Extensions Manifest Version 3](https://developer.chrome.com/docs/extensions/mv3/intro/)
+- [Custom i18n package](/packages/i18n/)
+- [Custom HMR (Hot Module Rebuild) plugin](/packages/hmr/)
+- [End-to-end testing with WebdriverIO](https://webdriver.io/)
+
+## Getting started
+
+1. When you're using Windows run this:
+ - `git config --global core.eol lf`
+ - `git config --global core.autocrlf input`
+
+ **This will set the EOL (End of line) character to be the same as on Linux/macOS. Without this, our bash script won't work, and you will have conflicts with developers on Linux/macOS.**
+2. Clone this repository.
+3. Check your node version is >= than in `.nvmrc` file, recommend to use [nvm](https://github.com/nvm-sh/nvm?tab=readme-ov-file#intro)
+4. Edit `/packages/i18n/locales/`{your locale(s)}/`messages.json`
+5. In the objects `extensionDescription` and `extensionName`, change the `message` fields (leave `description` alone)
+6. In `/.package.json`, change the `version` to the desired version of your extension.
+7. Install pnpm globally: `npm install -g pnpm` (check your node version >= 22.12.0))
+8. Run `pnpm install`
+
+Then, depending on the target browser:
+
+### For Chrome:
+
+1. Run:
+ - Dev: `pnpm dev` (on Windows, you should run as administrator; see [issue#456](https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/issues/456))
+ - Prod: `pnpm build`
+2. Open in browser - `chrome://extensions`
+3. Check - Developer mode
+4. Click - Load unpacked in the upper left corner
+5. Select the `dist` directory from the boilerplate project
+
+### For Firefox:
+
+1. Run:
+ - Dev: `pnpm dev:firefox`
+ - Prod: `pnpm build:firefox`
+2. Open in browser - `about:debugging#/runtime/this-firefox`
+3. Click - Load Temporary Add-on... in the upper right corner
+4. Select the `./dist/manifest.json` file from the boilerplate project
+
+> [!NOTE]
+> In Firefox, you load add-ons in temporary mode. That means they'll disappear after each browser close. You have to load the add-on on every browser launch.
+
+## Install dependency for turborepo:
+
+### For root:
+
+1. Run `pnpm i -w`
+
+### For module:
+
+1. Run `pnpm i -F `
+
+`package` - Name of the package you want to install e.g. `nodemon` \
+`module-name` - You can find it inside each `package.json` under the key `name`, e.g. `@extension/content-script`, you can use only `content-script` without `@extension/` prefix
+
+## Environment variables
+
+To add an environment variable:
+
+1. Copy `.example.env` to `.env` (in the same directory)
+2. Add a new record inside `.env`, prefixed with `VITE_`, e.g. `VITE_MY_API_KEY=...`
+3. Edit `./vite-env.d.ts` and in the `ImportMetaEnv` interface, add your variable with the appropriate type, e.g.
+
+ `readonly VITE_MY_API_KEY: string;`
+4. Then you can read the variable via `import.meta.env.VITE_MY_API_KEY` (learn more at [Env Variables and Modes](https://vite.dev/guide/env-and-mode))
+
+#### If you want to set it for each package independently:
+
+1. Create `.env` inside that package
+2. Open related `vite.config.mts` and add `envDir: '.'` at the end of this config
+3. Rest steps like above
+
+#### Remember you can't use global and local at the same time for the same package(It will be overwritten)
+
+## Boilerplate structure
+
+### Chrome extension
+
+The extension lives in the `chrome-extension` directory and includes the following files:
+
+- [`manifest.js`](chrome-extension/manifest.js) - script that outputs the `manifest.json`
+- [`src/background`](chrome-extension/src/background) - [background script](https://developer.chrome.com/docs/extensions/mv3/background_pages/)
+ (`background.service_worker` in manifest.json)
+- [`public`](chrome-extension/public/) - icons referenced in the manifest; content CSS for user's page injection
+
+> [!IMPORTANT]
+> To facilitate development, the boilerplate is configured to "Read and change all your data on all websites".
+> In production, it's best practice to limit the premissions to only the strictly necessary websites. See
+> [Declaring permissions](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions)
+> and edit `manifest.js` accordingly.
+
+### Pages
+
+Code that is transpiled to be part of the extension lives in the [pages](pages/) directory.
+
+- [`content`](pages/content/) - [content scripts](https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts)
+ (`content_scripts` in manifest.json)
+- [`content-ui`](pages/content-ui) - React UI rendered in the current page (you can see it at the very bottom when you get started)
+ (`content_scripts` in manifest.json)
+- [`content-runtime`](pages/content-runtime/src/) - [injected content scripts](https://developer.chrome.com/docs/extensions/develop/concepts/content-scripts#functionality);
+ this can be injected from `popup` like standard `content`
+- [`devtools`](pages/devtools/) - [extend the browser DevTools](https://developer.chrome.com/docs/extensions/how-to/devtools/extend-devtools#creating)
+ (`devtools_page` in manifest.json)
+- [`devtools-panel`](pages/devtools-panel/) - [DevTools panel](https://developer.chrome.com/docs/extensions/reference/api/devtools/panels)
+ for [devtools](pages/devtools/src/index.ts)
+- [`new-tab`](pages/new-tab/) - [override the default New Tab page](https://developer.chrome.com/docs/extensions/develop/ui/override-chrome-pages)
+ (`chrome_url_overrides.newtab` in manifest.json)
+- [`options`](pages/options/) - [options page](https://developer.chrome.com/docs/extensions/develop/ui/options-page)
+ (`options_page` in manifest.json)
+- [`popup`](pages/popup/) - [popup](https://developer.chrome.com/docs/extensions/reference/api/action#popup) shown when clicking the extension in the toolbar
+ (`action.default_popup` in manifest.json)
+- [`side-panel`](pages/side-panel/) - [sidepanel (Chrome 114+)](https://developer.chrome.com/docs/extensions/reference/api/sidePanel)
+ (`side_panel.default_path` in manifest.json)
+
+### Packages
+
+Some shared packages:
+
+- `dev-utils` - utilities for Chrome extension development (manifest-parser, logger)
+- `i18n` - custom internationalization package; provides i18n function with type safety and other validation
+- `hmr` - custom HMR plugin for Vite, injection script for reload/refresh, HMR dev-server
+- `shared` - shared code for the entire project (types, constants, custom hooks, components etc.)
+- `storage` - helpers for easier integration with [storage](https://developer.chrome.com/docs/extensions/reference/api/storage), e.g. local/session storages
+- `tailwind-config` - shared Tailwind config for entire project
+- `tsconfig` - shared tsconfig for the entire project
+- `ui` - function to merge your Tailwind config with the global one; you can save components here
+- `vite-config` - shared Vite config for the entire project
+- `zipper` - run `pnpm zip` to pack the `dist` folder into `extension-YYYYMMDD-HHmmss.zip` inside the newly created `dist-zip`
+- `e2e` - run `pnpm e2e` for end-to-end tests of your zipped extension on different browsers
+
+## Troubleshooting
+
+### Hot module reload seems to have frozen
+
+If saving source files doesn't cause the extension HMR code to trigger a reload of the browser page, try this:
+
+1. Ctrl+C the development server and restart it (`pnpm run dev`)
+2. If you get a [`grpc` error](https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/issues/612),
+ [kill the `turbo` process](https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/issues/612#issuecomment-2518982339) and run `pnpm dev` again.
+
+## Community
+
+To chat with other community members, you can join the [Discord](https://discord.gg/4ERQ6jgV9a) server.
+You can ask questions on that server, and you can also help others.
+
+Also, suggest new features or share any challenges you've faced while developing Chrome extensions!
+
+## Reference
+
+- [Chrome Extensions](https://developer.chrome.com/docs/extensions)
+- [Vite Plugin](https://vitejs.dev/guide/api-plugin.html)
+- [Rollup](https://rollupjs.org/guide/en/)
+- [Turborepo](https://turbo.build/repo/docs)
+- [Rollup-plugin-chrome-extension](https://www.extend-chrome.dev/rollup-plugin)
+
+## Star History
+
+
+
+
+
+
+
+
+
+## Contributors
+
+This Boilerplate is made possible thanks to all of its contributors.
+
+
+
+
+
+---
+
+## Special Thanks To
+
+| | |
+|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+---
+
+Made by [Jonghakseo](https://jonghakseo.github.io/)
diff --git a/UPDATE-PACKAGE-VERSIONS.md b/UPDATE-PACKAGE-VERSIONS.md
new file mode 100644
index 0000000..d160286
--- /dev/null
+++ b/UPDATE-PACKAGE-VERSIONS.md
@@ -0,0 +1,8 @@
+For update package version in all ```package.json``` files use this command in root:
+
+FOR WINDOWS YOU NEED TO USE E.G ```GIT BASH``` CONSOLE OR OTHER WHICH SUPPORT UNIX COMMANDS
+```bash
+pnpm update-version
+```
+
+If script was run successfully you will see ```Updated versions to ```
diff --git a/chrome-extension/manifest.js b/chrome-extension/manifest.js
new file mode 100755
index 0000000..d88070c
--- /dev/null
+++ b/chrome-extension/manifest.js
@@ -0,0 +1,82 @@
+import fs from 'node:fs';
+import deepmerge from 'deepmerge';
+
+const packageJson = JSON.parse(fs.readFileSync('../package.json', 'utf8'));
+
+const isFirefox = process.env.__FIREFOX__ === 'true';
+
+/**
+ * If you want to disable the sidePanel, you can delete withSidePanel function and remove the sidePanel HoC on the manifest declaration.
+ *
+ * ```js
+ * const manifest = { // remove `withSidePanel()`
+ * ```
+ */
+function withSidePanel(manifest) {
+ // Firefox does not support sidePanel
+ if (isFirefox) {
+ return manifest;
+ }
+ return deepmerge(manifest, {
+ side_panel: {
+ default_path: 'side-panel/index.html',
+ },
+ permissions: ['sidePanel'],
+ });
+}
+
+/**
+ * After changing, please reload the extension at `chrome://extensions`
+ * @type {chrome.runtime.ManifestV3}
+ */
+const manifest = withSidePanel({
+ manifest_version: 3,
+ default_locale: 'en',
+ /**
+ * if you want to support multiple languages, you can use the following reference
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization
+ */
+ name: '__MSG_extensionName__',
+ version: packageJson.version,
+ description: '__MSG_extensionDescription__',
+ host_permissions: [''],
+ permissions: ['storage', 'scripting', 'tabs', 'notifications'],
+ options_page: 'options/index.html',
+ background: {
+ service_worker: 'background.iife.js',
+ type: 'module',
+ },
+ action: {
+ default_popup: 'popup/index.html',
+ default_icon: 'icon-34.png',
+ },
+ chrome_url_overrides: {
+ newtab: 'new-tab/index.html',
+ },
+ icons: {
+ 128: 'icon-128.png',
+ },
+ content_scripts: [
+ {
+ matches: ['http://*/*', 'https://*/*', ''],
+ js: ['content/index.iife.js'],
+ },
+ {
+ matches: ['http://*/*', 'https://*/*', ''],
+ js: ['content-ui/index.iife.js'],
+ },
+ {
+ matches: ['http://*/*', 'https://*/*', ''],
+ css: ['content.css'], // public folder
+ },
+ ],
+ devtools_page: 'devtools/index.html',
+ web_accessible_resources: [
+ {
+ resources: ['*.js', '*.css', '*.svg', 'icon-128.png', 'icon-34.png'],
+ matches: ['*://*/*'],
+ },
+ ],
+});
+
+export default manifest;
diff --git a/chrome-extension/package.json b/chrome-extension/package.json
new file mode 100644
index 0000000..1622bc0
--- /dev/null
+++ b/chrome-extension/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "chrome-extension",
+ "version": "0.3.5",
+ "description": "chrome extension - core settings",
+ "type": "module",
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "test": "vitest run",
+ "lint": "eslint ./ --ext .ts,.js,.tsx,.jsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "webextension-polyfill": "^0.12.0",
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/dev-utils": "workspace:*",
+ "@extension/hmr": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "@laynezh/vite-plugin-lib-assets": "^0.6.1",
+ "@types/ws": "^8.5.13",
+ "magic-string": "^0.30.10",
+ "ts-loader": "^9.5.1",
+ "deepmerge": "^4.3.1",
+ "cross-env": "^7.0.3"
+ }
+}
diff --git a/chrome-extension/public/content.css b/chrome-extension/public/content.css
new file mode 100644
index 0000000..e69de29
diff --git a/chrome-extension/public/icon-128.png b/chrome-extension/public/icon-128.png
new file mode 100644
index 0000000..d5bdad9
Binary files /dev/null and b/chrome-extension/public/icon-128.png differ
diff --git a/chrome-extension/public/icon-34.png b/chrome-extension/public/icon-34.png
new file mode 100644
index 0000000..a741ff6
Binary files /dev/null and b/chrome-extension/public/icon-34.png differ
diff --git a/chrome-extension/src/background/index.ts b/chrome-extension/src/background/index.ts
new file mode 100644
index 0000000..b16541b
--- /dev/null
+++ b/chrome-extension/src/background/index.ts
@@ -0,0 +1,9 @@
+import 'webextension-polyfill';
+import { exampleThemeStorage } from '@extension/storage';
+
+exampleThemeStorage.get().then(theme => {
+ console.log('theme', theme);
+});
+
+console.log('background loaded');
+console.log("Edit 'chrome-extension/src/background/index.ts' and save to reload.");
diff --git a/chrome-extension/tsconfig.json b/chrome-extension/tsconfig.json
new file mode 100644
index 0000000..c1ba1cc
--- /dev/null
+++ b/chrome-extension/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@extension/tsconfig/app",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ }
+ },
+ "include": ["src", "utils", "vite.config.mts", "../node_modules/@types"]
+}
diff --git a/chrome-extension/utils/plugins/make-manifest-plugin.ts b/chrome-extension/utils/plugins/make-manifest-plugin.ts
new file mode 100644
index 0000000..a8fe31b
--- /dev/null
+++ b/chrome-extension/utils/plugins/make-manifest-plugin.ts
@@ -0,0 +1,67 @@
+import fs from 'node:fs';
+import { resolve } from 'node:path';
+import { pathToFileURL } from 'node:url';
+import process from 'node:process';
+import { colorLog, ManifestParser } from '@extension/dev-utils';
+import type { PluginOption } from 'vite';
+import type { Manifest } from '@extension/dev-utils/dist/lib/manifest-parser/type';
+
+const rootDir = resolve(__dirname, '..', '..');
+const refreshFile = resolve(__dirname, '..', 'refresh.js');
+const manifestFile = resolve(rootDir, 'manifest.js');
+
+const getManifestWithCacheBurst = (): Promise<{ default: chrome.runtime.ManifestV3 }> => {
+ const withCacheBurst = (path: string) => `${path}?${Date.now().toString()}`;
+ /**
+ * In Windows, import() doesn't work without file:// protocol.
+ * So, we need to convert path to file:// protocol. (url.pathToFileURL)
+ */
+ if (process.platform === 'win32') {
+ return import(withCacheBurst(pathToFileURL(manifestFile).href));
+ }
+
+ return import(withCacheBurst(manifestFile));
+};
+
+export default function makeManifestPlugin(config: { outDir: string }): PluginOption {
+ function makeManifest(manifest: chrome.runtime.ManifestV3, to: string) {
+ if (!fs.existsSync(to)) {
+ fs.mkdirSync(to);
+ }
+ const manifestPath = resolve(to, 'manifest.json');
+
+ const isFirefox = process.env.__FIREFOX__ === 'true';
+ const isDev = process.env.__DEV__ === 'true';
+
+ if (isDev) {
+ addRefreshContentScript(manifest);
+ }
+
+ fs.writeFileSync(manifestPath, ManifestParser.convertManifestToString(manifest, isFirefox ? 'firefox' : 'chrome'));
+ if (isDev) {
+ fs.copyFileSync(refreshFile, resolve(to, 'refresh.js'));
+ }
+
+ colorLog(`Manifest file copy complete: ${manifestPath}`, 'success');
+ }
+
+ return {
+ name: 'make-manifest',
+ buildStart() {
+ this.addWatchFile(manifestFile);
+ },
+ async writeBundle() {
+ const outDir = config.outDir;
+ const manifest = await getManifestWithCacheBurst();
+ makeManifest(manifest.default, outDir);
+ },
+ };
+}
+
+function addRefreshContentScript(manifest: Manifest) {
+ manifest.content_scripts = manifest.content_scripts || [];
+ manifest.content_scripts.push({
+ matches: ['http://*/*', 'https://*/*', ''],
+ js: ['refresh.js'], // for public's HMR(refresh) support
+ });
+}
diff --git a/chrome-extension/utils/refresh.js b/chrome-extension/utils/refresh.js
new file mode 100644
index 0000000..5d3dad3
--- /dev/null
+++ b/chrome-extension/utils/refresh.js
@@ -0,0 +1,72 @@
+/* eslint-disable */
+(function () {
+ 'use strict';
+ // This is the custom ID for HMR (chrome-extension/vite.config.mts)
+ const __HMR_ID = 'chrome-extension-hmr';
+
+ const LOCAL_RELOAD_SOCKET_PORT = 8081;
+ const LOCAL_RELOAD_SOCKET_URL = `ws://localhost:${LOCAL_RELOAD_SOCKET_PORT}`;
+
+ const DO_UPDATE = 'do_update';
+ const DONE_UPDATE = 'done_update';
+
+ class MessageInterpreter {
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ constructor() {}
+
+ static send(message) {
+ return JSON.stringify(message);
+ }
+
+ static receive(serializedMessage) {
+ return JSON.parse(serializedMessage);
+ }
+ }
+
+ function initClient({ id, onUpdate }) {
+ const ws = new WebSocket(LOCAL_RELOAD_SOCKET_URL);
+
+ ws.onopen = () => {
+ ws.addEventListener('message', event => {
+ const message = MessageInterpreter.receive(String(event.data));
+
+ if (message.type === DO_UPDATE && message.id === id) {
+ onUpdate();
+ ws.send(MessageInterpreter.send({ type: DONE_UPDATE }));
+ return;
+ }
+ });
+ };
+ }
+
+ function addRefresh() {
+ let pendingReload = false;
+
+ initClient({
+ id: __HMR_ID,
+ onUpdate: () => {
+ // disable reload when tab is hidden
+ if (document.hidden) {
+ pendingReload = true;
+ return;
+ }
+ reload();
+ },
+ });
+
+ // reload
+ function reload() {
+ pendingReload = false;
+ window.location.reload();
+ }
+
+ // reload when tab is visible
+ function reloadWhenTabIsVisible() {
+ !document.hidden && pendingReload && reload();
+ }
+
+ document.addEventListener('visibilitychange', reloadWhenTabIsVisible);
+ }
+
+ addRefresh();
+})();
diff --git a/chrome-extension/vite.config.mts b/chrome-extension/vite.config.mts
new file mode 100644
index 0000000..295dc33
--- /dev/null
+++ b/chrome-extension/vite.config.mts
@@ -0,0 +1,47 @@
+import { resolve } from 'node:path';
+import { defineConfig, type PluginOption } from "vite";
+import libAssetsPlugin from '@laynezh/vite-plugin-lib-assets';
+import makeManifestPlugin from './utils/plugins/make-manifest-plugin';
+import { watchPublicPlugin, watchRebuildPlugin } from '@extension/hmr';
+import { isDev, isProduction, watchOption } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+const outDir = resolve(rootDir, '..', 'dist');
+export default defineConfig({
+ resolve: {
+ alias: {
+ '@root': rootDir,
+ '@src': srcDir,
+ '@assets': resolve(srcDir, 'assets'),
+ },
+ },
+ plugins: [
+ libAssetsPlugin({
+ outputPath: outDir,
+ }) as PluginOption,
+ watchPublicPlugin(),
+ makeManifestPlugin({ outDir }),
+ isDev && watchRebuildPlugin({ reload: true, id: 'chrome-extension-hmr' }),
+ ],
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ lib: {
+ formats: ['iife'],
+ entry: resolve(__dirname, 'src/background/index.ts'),
+ name: 'BackgroundScript',
+ fileName: 'background',
+ },
+ outDir,
+ emptyOutDir: false,
+ sourcemap: isDev,
+ minify: isProduction,
+ reportCompressedSize: isProduction,
+ watch: watchOption,
+ rollupOptions: {
+ external: ['chrome'],
+ },
+ },
+ envDir: '../',
+});
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..46581e8
--- /dev/null
+++ b/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "chrome-extension-boilerplate-react-vite",
+ "version": "0.3.5",
+ "description": "chrome extension boilerplate",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite.git"
+ },
+ "type": "module",
+ "scripts": {
+ "clean:bundle": "rimraf dist && turbo clean:bundle",
+ "clean:node_modules": "pnpx rimraf node_modules && pnpx turbo clean:node_modules",
+ "clean:turbo": "rimraf .turbo && turbo clean:turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:turbo && pnpm clean:node_modules",
+ "clean:install": "pnpm clean:node_modules && pnpm install --frozen-lockfile",
+ "build": "pnpm clean:bundle && turbo ready && turbo build",
+ "build:firefox": "pnpm clean:bundle && turbo ready && cross-env __FIREFOX__=true turbo build",
+ "zip": "pnpm build && pnpm -F zipper zip",
+ "zip:firefox": "pnpm build:firefox && cross-env __FIREFOX__=true pnpm -F zipper zip",
+ "dev": "turbo ready && cross-env __DEV__=true turbo watch dev --concurrency 20",
+ "dev:firefox": "turbo ready && cross-env __DEV__=true __FIREFOX__=true turbo watch dev --concurrency 20",
+ "e2e": "pnpm build && pnpm zip && turbo e2e",
+ "e2e:firefox": "pnpm build:firefox && pnpm zip:firefox && cross-env __FIREFOX__=true turbo e2e",
+ "type-check": "turbo type-check",
+ "lint": "turbo lint --continue -- --fix --cache --cache-location node_modules/.cache/.eslintcache",
+ "lint:fix": "turbo lint:fix --continue -- --fix --cache --cache-location node_modules/.cache/.eslintcache",
+ "prettier": "turbo prettier --continue -- --cache --cache-location node_modules/.cache/.prettiercache",
+ "prepare": "husky",
+ "update-version": "bash update_version.sh"
+ },
+ "dependencies": {
+ "eslint-plugin-tailwindcss": "^3.17.4",
+ "react": "18.3.1",
+ "react-dom": "18.3.1"
+ },
+ "devDependencies": {
+ "@types/chrome": "^0.0.270",
+ "@types/node": "^22.5.5",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
+ "@typescript-eslint/parser": "^7.18.0",
+ "autoprefixer": "^10.4.20",
+ "cross-env": "^7.0.3",
+ "esbuild": "^0.23.0",
+ "eslint": "8.57.0",
+ "eslint-config-airbnb-typescript": "18.0.0",
+ "eslint-config-prettier": "9.1.0",
+ "eslint-plugin-import": "2.29.1",
+ "eslint-plugin-jsx-a11y": "6.9.0",
+ "eslint-plugin-prettier": "5.2.1",
+ "eslint-plugin-react": "7.35.0",
+ "eslint-plugin-react-hooks": "4.6.2",
+ "husky": "^9.1.4",
+ "lint-staged": "^15.2.7",
+ "postcss": "^8.4.47",
+ "prettier": "^3.3.3",
+ "rimraf": "^6.0.1",
+ "tailwindcss": "^3.4.14",
+ "tslib": "^2.6.3",
+ "typescript": "5.5.4",
+ "turbo": "^2.3.3",
+ "vite": "6.0.5",
+ "run-script-os": "^1.1.6"
+ },
+ "lint-staged": {
+ "*.{js,jsx,ts,tsx,json}": [
+ "prettier --write"
+ ]
+ },
+ "packageManager": "pnpm@9.15.1",
+ "engines": {
+ "node": ">=22.12.0"
+ }
+}
diff --git a/packages/dev-utils/.eslintignore b/packages/dev-utils/.eslintignore
new file mode 100644
index 0000000..de4d1f0
--- /dev/null
+++ b/packages/dev-utils/.eslintignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/packages/dev-utils/index.ts b/packages/dev-utils/index.ts
new file mode 100644
index 0000000..6e936df
--- /dev/null
+++ b/packages/dev-utils/index.ts
@@ -0,0 +1,2 @@
+export * from './lib/manifest-parser';
+export * from './lib/logger';
diff --git a/packages/dev-utils/lib/logger.ts b/packages/dev-utils/lib/logger.ts
new file mode 100644
index 0000000..0077b60
--- /dev/null
+++ b/packages/dev-utils/lib/logger.ts
@@ -0,0 +1,53 @@
+import type { ValueOf } from '@extension/shared';
+
+type ColorType = 'success' | 'info' | 'error' | 'warning' | keyof typeof COLORS;
+
+export function colorLog(message: string, type: ColorType) {
+ let color: ValueOf;
+
+ switch (type) {
+ case 'success':
+ color = COLORS.FgGreen;
+ break;
+ case 'info':
+ color = COLORS.FgBlue;
+ break;
+ case 'error':
+ color = COLORS.FgRed;
+ break;
+ case 'warning':
+ color = COLORS.FgYellow;
+ break;
+ default:
+ color = COLORS[type];
+ break;
+ }
+
+ console.log(color, message);
+}
+
+const COLORS = {
+ Reset: '\x1b[0m',
+ Bright: '\x1b[1m',
+ Dim: '\x1b[2m',
+ Underscore: '\x1b[4m',
+ Blink: '\x1b[5m',
+ Reverse: '\x1b[7m',
+ Hidden: '\x1b[8m',
+ FgBlack: '\x1b[30m',
+ FgRed: '\x1b[31m',
+ FgGreen: '\x1b[32m',
+ FgYellow: '\x1b[33m',
+ FgBlue: '\x1b[34m',
+ FgMagenta: '\x1b[35m',
+ FgCyan: '\x1b[36m',
+ FgWhite: '\x1b[37m',
+ BgBlack: '\x1b[40m',
+ BgRed: '\x1b[41m',
+ BgGreen: '\x1b[42m',
+ BgYellow: '\x1b[43m',
+ BgBlue: '\x1b[44m',
+ BgMagenta: '\x1b[45m',
+ BgCyan: '\x1b[46m',
+ BgWhite: '\x1b[47m',
+} as const;
diff --git a/packages/dev-utils/lib/manifest-parser/impl.ts b/packages/dev-utils/lib/manifest-parser/impl.ts
new file mode 100644
index 0000000..415a2be
--- /dev/null
+++ b/packages/dev-utils/lib/manifest-parser/impl.ts
@@ -0,0 +1,36 @@
+import type { ManifestParserInterface, Manifest } from './type';
+
+export const ManifestParserImpl: ManifestParserInterface = {
+ convertManifestToString: (manifest, env) => {
+ if (env === 'firefox') {
+ manifest = convertToFirefoxCompatibleManifest(manifest);
+ }
+ return JSON.stringify(manifest, null, 2);
+ },
+};
+
+function convertToFirefoxCompatibleManifest(manifest: Manifest) {
+ const manifestCopy = {
+ ...manifest,
+ } as { [key: string]: unknown };
+
+ manifestCopy.background = {
+ scripts: [manifest.background?.service_worker],
+ type: 'module',
+ };
+ manifestCopy.options_ui = {
+ page: manifest.options_page,
+ browser_style: false,
+ };
+ manifestCopy.content_security_policy = {
+ extension_pages: "script-src 'self'; object-src 'self'",
+ };
+ manifestCopy.browser_specific_settings = {
+ gecko: {
+ id: 'example@example.com',
+ strict_min_version: '109.0',
+ },
+ };
+ delete manifestCopy.options_page;
+ return manifestCopy as Manifest;
+}
diff --git a/packages/dev-utils/lib/manifest-parser/index.ts b/packages/dev-utils/lib/manifest-parser/index.ts
new file mode 100644
index 0000000..eba4115
--- /dev/null
+++ b/packages/dev-utils/lib/manifest-parser/index.ts
@@ -0,0 +1,2 @@
+import { ManifestParserImpl } from './impl';
+export const ManifestParser = ManifestParserImpl;
diff --git a/packages/dev-utils/lib/manifest-parser/type.ts b/packages/dev-utils/lib/manifest-parser/type.ts
new file mode 100644
index 0000000..d00982c
--- /dev/null
+++ b/packages/dev-utils/lib/manifest-parser/type.ts
@@ -0,0 +1,5 @@
+export type Manifest = chrome.runtime.ManifestV3;
+
+export interface ManifestParserInterface {
+ convertManifestToString: (manifest: Manifest, env: 'chrome' | 'firefox') => string;
+}
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
new file mode 100644
index 0000000..6183a29
--- /dev/null
+++ b/packages/dev-utils/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@extension/dev-utils",
+ "version": "0.3.5",
+ "description": "chrome extension - dev utils",
+ "private": true,
+ "sideEffects": false,
+ "files": [
+ "dist/**"
+ ],
+ "main": "dist/index.js",
+ "module": "dist/index.js",
+ "types": "index.ts",
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "ready": "tsc",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "@extension/shared": "workspace:*"
+ }
+}
diff --git a/packages/dev-utils/tsconfig.json b/packages/dev-utils/tsconfig.json
new file mode 100644
index 0000000..f6877b2
--- /dev/null
+++ b/packages/dev-utils/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome"]
+ },
+ "include": ["index.ts", "lib"]
+}
diff --git a/packages/hmr/index.ts b/packages/hmr/index.ts
new file mode 100644
index 0000000..9d821d7
--- /dev/null
+++ b/packages/hmr/index.ts
@@ -0,0 +1 @@
+export * from './lib/plugins';
diff --git a/packages/hmr/lib/constant.ts b/packages/hmr/lib/constant.ts
new file mode 100644
index 0000000..8166866
--- /dev/null
+++ b/packages/hmr/lib/constant.ts
@@ -0,0 +1,6 @@
+export const LOCAL_RELOAD_SOCKET_PORT = 8081;
+export const LOCAL_RELOAD_SOCKET_URL = `ws://localhost:${LOCAL_RELOAD_SOCKET_PORT}`;
+
+export const DO_UPDATE = 'do_update';
+export const DONE_UPDATE = 'done_update';
+export const BUILD_COMPLETE = 'build_complete';
diff --git a/packages/hmr/lib/initializers/initClient.ts b/packages/hmr/lib/initializers/initClient.ts
new file mode 100644
index 0000000..d9ead86
--- /dev/null
+++ b/packages/hmr/lib/initializers/initClient.ts
@@ -0,0 +1,18 @@
+import { DO_UPDATE, DONE_UPDATE, LOCAL_RELOAD_SOCKET_URL } from '../constant';
+import MessageInterpreter from '../interpreter';
+
+export default function initClient({ id, onUpdate }: { id: string; onUpdate: () => void }) {
+ const ws = new WebSocket(LOCAL_RELOAD_SOCKET_URL);
+
+ ws.onopen = () => {
+ ws.addEventListener('message', event => {
+ const message = MessageInterpreter.receive(String(event.data));
+
+ if (message.type === DO_UPDATE && message.id === id) {
+ onUpdate();
+ ws.send(MessageInterpreter.send({ type: DONE_UPDATE }));
+ return;
+ }
+ });
+ };
+}
diff --git a/packages/hmr/lib/initializers/initReloadServer.ts b/packages/hmr/lib/initializers/initReloadServer.ts
new file mode 100644
index 0000000..7214b68
--- /dev/null
+++ b/packages/hmr/lib/initializers/initReloadServer.ts
@@ -0,0 +1,45 @@
+import type { WebSocket } from 'ws';
+import { WebSocketServer } from 'ws';
+import { BUILD_COMPLETE, DO_UPDATE, DONE_UPDATE, LOCAL_RELOAD_SOCKET_PORT, LOCAL_RELOAD_SOCKET_URL } from '../constant';
+import MessageInterpreter from '../interpreter';
+
+const clientsThatNeedToUpdate: Set = new Set();
+
+function initReloadServer() {
+ const wss = new WebSocketServer({ port: LOCAL_RELOAD_SOCKET_PORT });
+
+ wss.on('listening', () => {
+ console.log(`[HMR] Server listening at ${LOCAL_RELOAD_SOCKET_URL}`);
+ });
+
+ wss.on('connection', ws => {
+ clientsThatNeedToUpdate.add(ws);
+
+ ws.addEventListener('close', () => {
+ clientsThatNeedToUpdate.delete(ws);
+ });
+
+ ws.addEventListener('message', event => {
+ if (typeof event.data !== 'string') return;
+
+ const message = MessageInterpreter.receive(event.data);
+
+ if (message.type === DONE_UPDATE) {
+ ws.close();
+ }
+
+ if (message.type === BUILD_COMPLETE) {
+ clientsThatNeedToUpdate.forEach((ws: WebSocket) =>
+ ws.send(MessageInterpreter.send({ type: DO_UPDATE, id: message.id })),
+ );
+ }
+ });
+ });
+
+ wss.on('error', error => {
+ console.error(`[HMR] Failed to start server at ${LOCAL_RELOAD_SOCKET_URL}`);
+ throw error;
+ });
+}
+
+initReloadServer();
diff --git a/packages/hmr/lib/injections/refresh.ts b/packages/hmr/lib/injections/refresh.ts
new file mode 100644
index 0000000..8795340
--- /dev/null
+++ b/packages/hmr/lib/injections/refresh.ts
@@ -0,0 +1,33 @@
+import initClient from '../initializers/initClient';
+
+function addRefresh() {
+ let pendingReload = false;
+
+ initClient({
+ // @ts-expect-error That's because of the dynamic code loading
+ id: __HMR_ID,
+ onUpdate: () => {
+ // disable reload when tab is hidden
+ if (document.hidden) {
+ pendingReload = true;
+ return;
+ }
+ reload();
+ },
+ });
+
+ // reload
+ function reload(): void {
+ pendingReload = false;
+ window.location.reload();
+ }
+
+ // reload when tab is visible
+ function reloadWhenTabIsVisible(): void {
+ !document.hidden && pendingReload && reload();
+ }
+
+ document.addEventListener('visibilitychange', reloadWhenTabIsVisible);
+}
+
+addRefresh();
diff --git a/packages/hmr/lib/injections/reload.ts b/packages/hmr/lib/injections/reload.ts
new file mode 100644
index 0000000..10a728d
--- /dev/null
+++ b/packages/hmr/lib/injections/reload.ts
@@ -0,0 +1,15 @@
+import initClient from '../initializers/initClient';
+
+function addReload() {
+ const reload = () => {
+ chrome.runtime.reload();
+ };
+
+ initClient({
+ // @ts-expect-error That's because of the dynamic code loading
+ id: __HMR_ID,
+ onUpdate: reload,
+ });
+}
+
+addReload();
diff --git a/packages/hmr/lib/interpreter/index.ts b/packages/hmr/lib/interpreter/index.ts
new file mode 100644
index 0000000..663e277
--- /dev/null
+++ b/packages/hmr/lib/interpreter/index.ts
@@ -0,0 +1,14 @@
+import type { SerializedMessage, WebSocketMessage } from '../types';
+
+export default class MessageInterpreter {
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ private constructor() {}
+
+ static send(message: WebSocketMessage): SerializedMessage {
+ return JSON.stringify(message);
+ }
+
+ static receive(serializedMessage: SerializedMessage): WebSocketMessage {
+ return JSON.parse(serializedMessage);
+ }
+}
diff --git a/packages/hmr/lib/plugins/index.ts b/packages/hmr/lib/plugins/index.ts
new file mode 100644
index 0000000..fba147b
--- /dev/null
+++ b/packages/hmr/lib/plugins/index.ts
@@ -0,0 +1,3 @@
+export * from './watch-rebuild-plugin';
+export * from './make-entry-point-plugin';
+export * from './watch-public-plugin';
diff --git a/packages/hmr/lib/plugins/make-entry-point-plugin.ts b/packages/hmr/lib/plugins/make-entry-point-plugin.ts
new file mode 100644
index 0000000..da005b8
--- /dev/null
+++ b/packages/hmr/lib/plugins/make-entry-point-plugin.ts
@@ -0,0 +1,74 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import type { PluginOption } from 'vite';
+
+/**
+ * make entry point file for content script cache busting
+ */
+export function makeEntryPointPlugin(): PluginOption {
+ const cleanupTargets = new Set();
+ const isFirefox = process.env.__FIREFOX__ === 'true';
+
+ return {
+ name: 'make-entry-point-plugin',
+ generateBundle(options, bundle) {
+ const outputDir = options.dir;
+
+ if (!outputDir) {
+ throw new Error('Output directory not found');
+ }
+
+ for (const module of Object.values(bundle)) {
+ const fileName = path.basename(module.fileName);
+ const newFileName = fileName.replace('.js', '_dev.js');
+
+ switch (module.type) {
+ case 'asset':
+ if (fileName.endsWith('.map')) {
+ cleanupTargets.add(path.resolve(outputDir, fileName));
+
+ const originalFileName = fileName.replace('.map', '');
+ const replacedSource = String(module.source).replaceAll(originalFileName, newFileName);
+
+ module.source = '';
+ fs.writeFileSync(path.resolve(outputDir, newFileName), replacedSource);
+ break;
+ }
+ break;
+
+ case 'chunk': {
+ fs.writeFileSync(path.resolve(outputDir, newFileName), module.code);
+
+ if (isFirefox) {
+ const contentDirectory = extractContentDir(outputDir);
+ module.code = `import(browser.runtime.getURL("${contentDirectory}/${newFileName}"));`;
+ } else {
+ module.code = `import('./${newFileName}');`;
+ }
+ break;
+ }
+ }
+ }
+ },
+ closeBundle() {
+ cleanupTargets.forEach(target => {
+ fs.unlinkSync(target);
+ });
+ },
+ };
+}
+
+/**
+ * Extract content directory from output directory for Firefox
+ * @param outputDir
+ */
+function extractContentDir(outputDir: string) {
+ const parts = outputDir.split(path.sep);
+ const distIndex = parts.indexOf('dist');
+
+ if (distIndex !== -1 && distIndex < parts.length - 1) {
+ return parts.slice(distIndex + 1);
+ }
+
+ throw new Error('Output directory does not contain "dist"');
+}
diff --git a/packages/hmr/lib/plugins/watch-public-plugin.ts b/packages/hmr/lib/plugins/watch-public-plugin.ts
new file mode 100644
index 0000000..4dd184a
--- /dev/null
+++ b/packages/hmr/lib/plugins/watch-public-plugin.ts
@@ -0,0 +1,15 @@
+import type { PluginOption } from 'vite';
+import fg from 'fast-glob';
+
+export function watchPublicPlugin(): PluginOption {
+ return {
+ name: 'watch-public-plugin',
+ async buildStart() {
+ const files = await fg(['public/**/*']);
+
+ for (const file of files) {
+ this.addWatchFile(file);
+ }
+ },
+ };
+}
diff --git a/packages/hmr/lib/plugins/watch-rebuild-plugin.ts b/packages/hmr/lib/plugins/watch-rebuild-plugin.ts
new file mode 100644
index 0000000..3b3b88a
--- /dev/null
+++ b/packages/hmr/lib/plugins/watch-rebuild-plugin.ts
@@ -0,0 +1,68 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import type { PluginOption } from 'vite';
+import { WebSocket } from 'ws';
+import MessageInterpreter from '../interpreter';
+import { BUILD_COMPLETE, LOCAL_RELOAD_SOCKET_URL } from '../constant';
+import type { PluginConfig } from '../types';
+
+const injectionsPath = path.resolve(__dirname, '..', '..', '..', 'build', 'injections');
+
+const refreshCode = fs.readFileSync(path.resolve(injectionsPath, 'refresh.js'), 'utf-8');
+const reloadCode = fs.readFileSync(path.resolve(injectionsPath, 'reload.js'), 'utf-8');
+
+export function watchRebuildPlugin(config: PluginConfig): PluginOption {
+ const { refresh, reload, id: _id, onStart } = config;
+ const hmrCode = (refresh ? refreshCode : '') + (reload ? reloadCode : '');
+
+ let ws: WebSocket | null = null;
+
+ const id = _id ?? Math.random().toString(36);
+ let reconnectTries = 0;
+
+ function initializeWebSocket() {
+ ws = new WebSocket(LOCAL_RELOAD_SOCKET_URL);
+
+ ws.onopen = () => {
+ console.log(`[HMR] Connected to dev-server at ${LOCAL_RELOAD_SOCKET_URL}`);
+ };
+
+ ws.onerror = () => {
+ console.error(`[HMR] Failed to connect server at ${LOCAL_RELOAD_SOCKET_URL}`);
+ console.warn('Retrying in 3 seconds...');
+ ws = null;
+
+ if (reconnectTries <= 2) {
+ setTimeout(() => {
+ reconnectTries++;
+ initializeWebSocket();
+ }, 3_000);
+ } else {
+ console.error(`[HMR] Cannot establish connection to server at ${LOCAL_RELOAD_SOCKET_URL}`);
+ }
+ };
+ }
+
+ return {
+ name: 'watch-rebuild',
+ writeBundle() {
+ onStart?.();
+ if (!ws) {
+ initializeWebSocket();
+ return;
+ }
+ /**
+ * When the build is complete, send a message to the reload server.
+ * The reload server will send a message to the client to reload or refresh the extension.
+ */
+ ws.send(MessageInterpreter.send({ type: BUILD_COMPLETE, id }));
+ },
+ generateBundle(_options, bundle) {
+ for (const module of Object.values(bundle)) {
+ if (module.type === 'chunk') {
+ module.code = `(function() {let __HMR_ID = "${id}";\n` + hmrCode + '\n' + '})();' + '\n' + module.code;
+ }
+ }
+ },
+ };
+}
diff --git a/packages/hmr/lib/types.ts b/packages/hmr/lib/types.ts
new file mode 100644
index 0000000..d9c8e05
--- /dev/null
+++ b/packages/hmr/lib/types.ts
@@ -0,0 +1,20 @@
+import type { BUILD_COMPLETE, DO_UPDATE, DONE_UPDATE } from './constant';
+
+type UpdateRequestMessage = {
+ type: typeof DO_UPDATE;
+ id: string;
+};
+
+type UpdateCompleteMessage = { type: typeof DONE_UPDATE };
+type BuildCompletionMessage = { type: typeof BUILD_COMPLETE; id: string };
+
+export type SerializedMessage = string;
+
+export type WebSocketMessage = UpdateCompleteMessage | UpdateRequestMessage | BuildCompletionMessage;
+
+export type PluginConfig = {
+ onStart?: () => void;
+ reload?: boolean;
+ refresh?: boolean;
+ id?: string;
+};
diff --git a/packages/hmr/package.json b/packages/hmr/package.json
new file mode 100644
index 0000000..e50494d
--- /dev/null
+++ b/packages/hmr/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@extension/hmr",
+ "version": "0.3.5",
+ "description": "chrome extension - hot module reload/refresh",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "main": "dist/index.js",
+ "module": "dist/index.js",
+ "types": "index.ts",
+ "scripts": {
+ "clean:bundle": "rimraf dist && pnpx rimraf build",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "build:tsc": "tsc -b tsconfig.build.json",
+ "build:rollup": "rollup --config rollup.config.mjs",
+ "ready": "pnpm run build:tsc && pnpm run build:rollup",
+ "dev": "node dist/lib/initializers/initReloadServer.js",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "@rollup/plugin-sucrase": "^5.0.2",
+ "@types/ws": "^8.5.13",
+ "esm": "^3.2.25",
+ "fast-glob": "^3.3.2",
+ "rollup": "^4.24.0",
+ "ts-node": "^10.9.2",
+ "ws": "8.18.0"
+ }
+}
diff --git a/packages/hmr/rollup.config.mjs b/packages/hmr/rollup.config.mjs
new file mode 100644
index 0000000..7b2e0ba
--- /dev/null
+++ b/packages/hmr/rollup.config.mjs
@@ -0,0 +1,30 @@
+import sucrase from '@rollup/plugin-sucrase';
+
+const plugins = [
+ sucrase({
+ exclude: ['node_modules/**'],
+ transforms: ['typescript'],
+ }),
+];
+
+/**
+ * @type {import("rollup").RollupOptions[]}
+ */
+export default [
+ {
+ plugins,
+ input: 'lib/injections/reload.ts',
+ output: {
+ format: 'iife',
+ file: 'build/injections/reload.js',
+ },
+ },
+ {
+ plugins,
+ input: 'lib/injections/refresh.ts',
+ output: {
+ format: 'iife',
+ file: 'build/injections/refresh.js',
+ },
+ },
+];
diff --git a/packages/hmr/tsconfig.build.json b/packages/hmr/tsconfig.build.json
new file mode 100644
index 0000000..5514417
--- /dev/null
+++ b/packages/hmr/tsconfig.build.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome"]
+ },
+ "exclude": ["lib/injections/**/*"],
+ "include": ["lib", "index.ts"]
+}
diff --git a/packages/hmr/tsconfig.json b/packages/hmr/tsconfig.json
new file mode 100644
index 0000000..8656bec
--- /dev/null
+++ b/packages/hmr/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome"]
+ },
+ "include": ["lib", "index.ts", "rollup.config.mjs"]
+}
diff --git a/packages/i18n/.eslintignore b/packages/i18n/.eslintignore
new file mode 100644
index 0000000..de4d1f0
--- /dev/null
+++ b/packages/i18n/.eslintignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/packages/i18n/.gitignore b/packages/i18n/.gitignore
new file mode 100644
index 0000000..7030680
--- /dev/null
+++ b/packages/i18n/.gitignore
@@ -0,0 +1 @@
+lib/i18n.ts
diff --git a/packages/i18n/README.md b/packages/i18n/README.md
new file mode 100644
index 0000000..d95eb72
--- /dev/null
+++ b/packages/i18n/README.md
@@ -0,0 +1,223 @@
+# I18n Package
+
+This package provides a set of tools to help you internationalize your Chrome Extension.
+
+https://developer.chrome.com/docs/extensions/reference/api/i18n
+
+## Installation
+
+If you want to use the i18n translation function in each pages, you need to add the following to the package.json file.
+
+```json
+{
+ "dependencies": {
+ "@extension/i18n": "workspace:*"
+ }
+}
+```
+
+Then run the following command to install the package.
+
+```bash
+pnpm install
+```
+
+## Manage translations
+
+You can manage translations in the `locales` directory.
+
+`locales/en/messages.json`
+
+```json
+{
+ "helloWorld": {
+ "message": "Hello, World!"
+ }
+}
+```
+
+`locales/ko/messages.json`
+
+```json
+{
+ "helloWorld": {
+ "message": "μλ
νμΈμ, μ¬λ¬λΆ!"
+ }
+}
+```
+
+## Delete or Add a new language
+
+When you want to delete or add a new language, you don't need to edit some util files like `lib/types.ts` or `lib/getMessageFromLocale.ts`.
+That's because we provide a script to generate util files automatically by the `generate-i18n.mjs` file.
+
+Following the steps below to delete or add a new language.
+
+### Delete a language
+
+If you want to delete unused languages, you can delete the corresponding directory in the `locales` directory.
+
+```
+locales
+βββ en
+β βββ messages.json
+βββ ko // delete this directory
+ βββ messages.json
+```
+
+Then run the following command. (or just run `pnpm dev` or `pnpm build` on root)
+
+```bash
+pnpm genenrate-i8n
+```
+
+### Add a new language
+
+If you want to add a new language, you can create a new directory in the `locales` directory.
+
+```
+locales
+βββ en
+β βββ messages.json
+βββ ko
+β βββ messages.json
+βββ ja // create this directory
+ βββ messages.json // and create this file
+```
+
+Then same as above, run the following command. (or just run `pnpm dev` or `pnpm build` on root)
+
+```bash
+pnpm genenrate-i8n
+```
+
+
+## Usage
+
+### Translation function
+
+Just import the `t` function and use it to translate the key.
+
+```typescript
+import { t } from '@extension/i18n';
+
+console.log(t('loading')); // Loading...
+```
+
+```typescript jsx
+import { t } from '@extension/i18n';
+
+const Component = () => {
+ return (
+
+ {t('toggleTheme')} // Toggle Theme
+
+ );
+};
+```
+
+### Placeholders
+
+If you want to use placeholders, you can use the following format.
+
+> For more information, see the [Message Placeholders](https://developer.chrome.com/docs/extensions/how-to/ui/localization-message-formats#placeholders) section.
+
+`locales/en/messages.json`
+
+```json
+{
+ "greeting": {
+ "description": "Greeting message",
+ "message": "Hello, My name is $NAME$",
+ "placeholders": {
+ "name": {
+ "content": "$1",
+ "example": "John Doe"
+ }
+ }
+ },
+ "hello": {
+ "description": "Placeholder example",
+ "message": "Hello $1"
+ }
+}
+```
+
+`locales/ko/messages.json`
+
+```json
+{
+ "greeting": {
+ "description": "μΈμ¬ λ©μμ§",
+ "message": "μλ
νμΈμ, μ μ΄λ¦μ $NAME$μ
λλ€.",
+ "placeholders": {
+ "name": {
+ "content": "$1",
+ "example": "μμ’
ν"
+ }
+ }
+ },
+ "hello": {
+ "description": "Placeholder μμ",
+ "message": "μλ
$1"
+ }
+}
+```
+
+If you want to replace the placeholder, you can pass the value as the second argument.
+
+Function `t` has exactly the same interface as the `chrome.i18n.getMessage` function.
+
+```typescript
+import { t } from '@extension/i18n';
+
+console.log(t('greeting', 'John Doe')); // Hello, My name is John Doe
+console.log(t('greeting', ['John Doe'])); // Hello, My name is John Doe
+
+console.log(t('hello')); // Hello
+console.log(t('hello', 'World')); // Hello World
+console.log(t('hello', ['World'])); // Hello World
+```
+
+### Locale setting on development
+
+If you want to show specific language, you can set the `devLocale` property. (only for development)
+
+```typescript
+import { t } from '@extension/i18n';
+
+t.devLocale = "ko";
+
+console.log(t('hello')); // μλ
+```
+
+### Type Safety
+
+When you forget to add a key to all language's `messages.json` files, you will get a Typescript error.
+
+`locales/en/messages.json`
+
+```json
+{
+ "hello": {
+ "message": "Hello World!"
+ }
+}
+```
+
+`locales/ko/messages.json`
+
+```json
+{
+ "helloWorld": {
+ "message": "μλ
νμΈμ, μ¬λ¬λΆ!"
+ }
+}
+```
+
+```typescript
+import { t } from '@extension/i18n';
+
+// Error: TS2345: Argument of type "hello" is not assignable to parameter of type
+console.log(t('hello'));
+```
diff --git a/packages/i18n/build.dev.mjs b/packages/i18n/build.dev.mjs
new file mode 100644
index 0000000..f0a11fe
--- /dev/null
+++ b/packages/i18n/build.dev.mjs
@@ -0,0 +1,6 @@
+import path from 'node:path';
+import { build } from './build.mjs';
+
+const i18nPath = path.resolve('lib', 'i18n-dev.ts');
+
+void build(i18nPath);
diff --git a/packages/i18n/build.mjs b/packages/i18n/build.mjs
new file mode 100644
index 0000000..adb0674
--- /dev/null
+++ b/packages/i18n/build.mjs
@@ -0,0 +1,29 @@
+import fs from 'node:fs';
+import path from 'node:path';
+import esbuild from 'esbuild';
+import { rimraf } from 'rimraf';
+
+/**
+ * @param i18nPath {string}
+ */
+export async function build(i18nPath) {
+ fs.cpSync(i18nPath, path.resolve('lib', 'i18n.ts'));
+
+ await esbuild.build({
+ entryPoints: ['./index.ts'],
+ tsconfig: './tsconfig.json',
+ bundle: true,
+ packages: 'bundle',
+ target: 'es6',
+ outdir: './dist',
+ sourcemap: true,
+ format: 'esm',
+ });
+
+ const outDir = path.resolve('..', '..', 'dist');
+ const localePath = path.resolve(outDir, '_locales');
+ rimraf.sync(localePath);
+ fs.cpSync(path.resolve('locales'), localePath, { recursive: true });
+
+ console.log('I18n build complete');
+}
diff --git a/packages/i18n/build.prod.mjs b/packages/i18n/build.prod.mjs
new file mode 100644
index 0000000..e305a92
--- /dev/null
+++ b/packages/i18n/build.prod.mjs
@@ -0,0 +1,6 @@
+import path from 'node:path';
+import { build } from './build.mjs';
+
+const i18nPath = path.resolve('lib', 'i18n-prod.ts');
+
+void build(i18nPath);
diff --git a/packages/i18n/genenrate-i18n.mjs b/packages/i18n/genenrate-i18n.mjs
new file mode 100644
index 0000000..6caaac6
--- /dev/null
+++ b/packages/i18n/genenrate-i18n.mjs
@@ -0,0 +1,127 @@
+import fs from 'node:fs';
+
+/**
+ * @url https://developer.chrome.com/docs/extensions/reference/api/i18n#support_multiple_languages
+ */
+const SUPPORTED_LANGUAGES = {
+ ar: 'Arabic',
+ am: 'Amharic',
+ bg: 'Bulgarian',
+ bn: 'Bengali',
+ ca: 'Catalan',
+ cs: 'Czech',
+ da: 'Danish',
+ de: 'German',
+ el: 'Greek',
+ en: 'English',
+ en_AU: 'English (Australia)',
+ en_GB: 'English (Great Britain)',
+ en_US: 'English (USA)',
+ es: 'Spanish',
+ es_419: 'Spanish (Latin America and Caribbean)',
+ et: 'Estonian',
+ fa: 'Persian',
+ fi: 'Finnish',
+ fil: 'Filipino',
+ fr: 'French',
+ gu: 'Gujarati',
+ he: 'Hebrew',
+ hi: 'Hindi',
+ hr: 'Croatian',
+ hu: 'Hungarian',
+ id: 'Indonesian',
+ it: 'Italian',
+ ja: 'Japanese',
+ kn: 'Kannada',
+ ko: 'Korean',
+ lt: 'Lithuanian',
+ lv: 'Latvian',
+ ml: 'Malayalam',
+ mr: 'Marathi',
+ ms: 'Malay',
+ nl: 'Dutch',
+ no: 'Norwegian',
+ pl: 'Polish',
+ pt_BR: 'Portuguese (Brazil)',
+ pt_PT: 'Portuguese (Portugal)',
+ ro: 'Romanian',
+ ru: 'Russian',
+ sk: 'Slovak',
+ sl: 'Slovenian',
+ sr: 'Serbian',
+ sv: 'Swedish',
+ sw: 'Swahili',
+ ta: 'Tamil',
+ te: 'Telugu',
+ th: 'Thai',
+ tr: 'Turkish',
+ uk: 'Ukrainian',
+ vi: 'Vietnamese',
+ zh_CN: 'Chinese (China)',
+ zh_TW: 'Chinese (Taiwan)',
+};
+
+const locales = fs.readdirSync('locales');
+
+locales.forEach(locale => {
+ if (!(locale in SUPPORTED_LANGUAGES)) {
+ throw new Error(`Unsupported language: ${locale}`);
+ }
+});
+
+makeTypeFile(locales);
+makeGetMessageFromLocaleFile(locales);
+
+function makeTypeFile(locales) {
+ const typeFile = `/**
+ * This file is generated by generate-i18n.mjs
+ * Do not edit this file directly
+ */
+${locales.map(locale => `import type ${locale}Message from '../locales/${locale}/messages.json';`).join('\n')}
+
+export type MessageKey = ${locales.map(locale => `keyof typeof ${locale}Message`).join(' & ')};
+
+export type DevLocale = ${locales.map(locale => `'${locale}'`).join(' | ')};
+`;
+
+ fs.writeFileSync('lib/type.ts', typeFile);
+}
+
+function makeGetMessageFromLocaleFile(locales) {
+ const defaultLocaleCode = `(() => {
+ const locales = ${JSON.stringify(locales).replace(/"/g, "'").replace(/,/g, ', ')};
+ const firstLocale = locales[0];
+ const defaultLocale = Intl.DateTimeFormat().resolvedOptions().locale.replace('-', '_');
+ if (locales.includes(defaultLocale)) {
+ return defaultLocale;
+ }
+ const defaultLocaleWithoutRegion = defaultLocale.split('_')[0];
+ if (locales.includes(defaultLocaleWithoutRegion)) {
+ return defaultLocaleWithoutRegion;
+ }
+ return firstLocale;
+})()`;
+
+ const getMessageFromLocaleFile = `/**
+ * This file is generated by generate-i18n.mjs
+ * Do not edit this file directly
+ */
+${locales.map(locale => `import ${locale}Message from '../locales/${locale}/messages.json';`).join('\n')}
+
+export function getMessageFromLocale(locale: string) {
+ switch (locale) {
+${locales
+ .map(
+ locale => ` case '${locale}':
+ return ${locale}Message;`,
+ )
+ .join('\n')}
+ default:
+ throw new Error('Unsupported locale');
+ }
+}
+
+export const defaultLocale = ${defaultLocaleCode};
+`;
+ fs.writeFileSync('lib/getMessageFromLocale.ts', getMessageFromLocaleFile);
+}
diff --git a/packages/i18n/index.ts b/packages/i18n/index.ts
new file mode 100644
index 0000000..42c4f57
--- /dev/null
+++ b/packages/i18n/index.ts
@@ -0,0 +1,6 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+import { t as t_dev_or_prod } from './lib/i18n';
+import type { t as t_dev } from './lib/i18n-dev';
+
+export const t = t_dev_or_prod as unknown as typeof t_dev;
diff --git a/packages/i18n/lib/getMessageFromLocale.ts b/packages/i18n/lib/getMessageFromLocale.ts
new file mode 100644
index 0000000..e27539e
--- /dev/null
+++ b/packages/i18n/lib/getMessageFromLocale.ts
@@ -0,0 +1,31 @@
+/**
+ * This file is generated by generate-i18n.mjs
+ * Do not edit this file directly
+ */
+import enMessage from '../locales/en/messages.json';
+import koMessage from '../locales/ko/messages.json';
+
+export function getMessageFromLocale(locale: string) {
+ switch (locale) {
+ case 'en':
+ return enMessage;
+ case 'ko':
+ return koMessage;
+ default:
+ throw new Error('Unsupported locale');
+ }
+}
+
+export const defaultLocale = (() => {
+ const locales = ['en', 'ko'];
+ const firstLocale = locales[0];
+ const defaultLocale = Intl.DateTimeFormat().resolvedOptions().locale.replace('-', '_');
+ if (locales.includes(defaultLocale)) {
+ return defaultLocale;
+ }
+ const defaultLocaleWithoutRegion = defaultLocale.split('_')[0];
+ if (locales.includes(defaultLocaleWithoutRegion)) {
+ return defaultLocaleWithoutRegion;
+ }
+ return firstLocale;
+})();
diff --git a/packages/i18n/lib/i18n-dev.ts b/packages/i18n/lib/i18n-dev.ts
new file mode 100644
index 0000000..cb60cce
--- /dev/null
+++ b/packages/i18n/lib/i18n-dev.ts
@@ -0,0 +1,44 @@
+import type { DevLocale, MessageKey } from './type';
+import { defaultLocale, getMessageFromLocale } from './getMessageFromLocale';
+
+type I18nValue = {
+ message: string;
+ placeholders?: Record;
+};
+
+function translate(key: MessageKey, substitutions?: string | string[]) {
+ const value = getMessageFromLocale(t.devLocale)[key] as I18nValue;
+ let message = value.message;
+ /**
+ * This is a placeholder replacement logic. But it's not perfect.
+ * It just imitates the behavior of the Chrome extension i18n API.
+ * Please check the official document for more information And double-check the behavior on production build.
+ *
+ * @url https://developer.chrome.com/docs/extensions/how-to/ui/localization-message-formats#placeholders
+ */
+ if (value.placeholders) {
+ Object.entries(value.placeholders).forEach(([key, { content }]) => {
+ if (!content) {
+ return;
+ }
+ message = message.replace(new RegExp(`\\$${key}\\$`, 'gi'), content);
+ });
+ }
+ if (!substitutions) {
+ return message;
+ }
+ if (Array.isArray(substitutions)) {
+ return substitutions.reduce((acc, cur, idx) => acc.replace(`$${idx + 1}`, cur), message);
+ }
+ return message.replace(/\$(\d+)/, substitutions);
+}
+
+function removePlaceholder(message: string) {
+ return message.replace(/\$\d+/g, '');
+}
+
+export const t = (...args: Parameters) => {
+ return removePlaceholder(translate(...args));
+};
+
+t.devLocale = defaultLocale as DevLocale;
diff --git a/packages/i18n/lib/i18n-prod.ts b/packages/i18n/lib/i18n-prod.ts
new file mode 100644
index 0000000..3deed43
--- /dev/null
+++ b/packages/i18n/lib/i18n-prod.ts
@@ -0,0 +1,7 @@
+import type { DevLocale, MessageKey } from './type';
+
+export function t(key: MessageKey, substitutions?: string | string[]) {
+ return chrome.i18n.getMessage(key, substitutions);
+}
+
+t.devLocale = '' as DevLocale; // for type consistency with i18n-dev.ts
diff --git a/packages/i18n/lib/type.ts b/packages/i18n/lib/type.ts
new file mode 100644
index 0000000..6f038c1
--- /dev/null
+++ b/packages/i18n/lib/type.ts
@@ -0,0 +1,10 @@
+/**
+ * This file is generated by generate-i18n.mjs
+ * Do not edit this file directly
+ */
+import type enMessage from '../locales/en/messages.json';
+import type koMessage from '../locales/ko/messages.json';
+
+export type MessageKey = keyof typeof enMessage & keyof typeof koMessage;
+
+export type DevLocale = 'en' | 'ko';
diff --git a/packages/i18n/locales/en/messages.json b/packages/i18n/locales/en/messages.json
new file mode 100644
index 0000000..5a18652
--- /dev/null
+++ b/packages/i18n/locales/en/messages.json
@@ -0,0 +1,30 @@
+{
+ "extensionDescription": {
+ "description": "Extension description",
+ "message": "Chrome extension boilerplate developed with Vite, React and Typescript"
+ },
+ "extensionName": {
+ "description": "Extension name",
+ "message": "Chrome extension boilerplate"
+ },
+ "toggleTheme": {
+ "message": "Toggle theme"
+ },
+ "loading": {
+ "message": "Loading..."
+ },
+ "greeting": {
+ "description": "Greeting message",
+ "message": "Hello, My name is $NAME$",
+ "placeholders": {
+ "name": {
+ "content": "$1",
+ "example": "John Doe"
+ }
+ }
+ },
+ "hello": {
+ "description": "Placeholder example",
+ "message": "Hello $1"
+ }
+}
diff --git a/packages/i18n/locales/ko/messages.json b/packages/i18n/locales/ko/messages.json
new file mode 100644
index 0000000..fef8a7e
--- /dev/null
+++ b/packages/i18n/locales/ko/messages.json
@@ -0,0 +1,30 @@
+{
+ "extensionDescription": {
+ "description": "Extension description",
+ "message": "React, Typescript, Viteλ₯Ό μ¬μ©ν ν¬λ‘¬ μ΅μ€ν
μ
보μΌλ¬νλ μ΄νΈμ
λλ€."
+ },
+ "extensionName": {
+ "description": "Extension name",
+ "message": "ν¬λ‘¬ μ΅μ€ν
μ
보μΌλ¬νλ μ΄νΈ"
+ },
+ "toggleTheme": {
+ "message": "ν
λ§ λ³κ²½"
+ },
+ "loading": {
+ "message": "λ‘λ© μ€..."
+ },
+ "greeting": {
+ "description": "μΈμ¬ λ©μμ§",
+ "message": "μλ
νμΈμ, μ μ΄λ¦μ $NAME$μ
λλ€.",
+ "placeholders": {
+ "name": {
+ "content": "$1",
+ "example": "μμ’
ν"
+ }
+ }
+ },
+ "hello": {
+ "description": "Placeholder μμ",
+ "message": "μλ
$1"
+ }
+}
diff --git a/packages/i18n/package.json b/packages/i18n/package.json
new file mode 100644
index 0000000..1d1e74e
--- /dev/null
+++ b/packages/i18n/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "@extension/i18n",
+ "version": "0.3.5",
+ "description": "chrome extension - internationalization",
+ "private": true,
+ "sideEffects": false,
+ "files": [
+ "dist/**"
+ ],
+ "types": "index.ts",
+ "main": "./dist/index.js",
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "genenrate-i8n": "node genenrate-i18n.mjs",
+ "ready": "pnpm genenrate-i8n && node build.dev.mjs",
+ "build": "pnpm genenrate-i8n && node build.prod.mjs",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "@extension/hmr": "workspace:*"
+ }
+}
diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json
new file mode 100644
index 0000000..650fd4e
--- /dev/null
+++ b/packages/i18n/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome"]
+ },
+ "include": ["index.ts", "lib", "locales"]
+}
diff --git a/packages/shared/.eslintignore b/packages/shared/.eslintignore
new file mode 100644
index 0000000..de4d1f0
--- /dev/null
+++ b/packages/shared/.eslintignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/packages/shared/README.md b/packages/shared/README.md
new file mode 100644
index 0000000..7d40c22
--- /dev/null
+++ b/packages/shared/README.md
@@ -0,0 +1,12 @@
+# Shared Package
+
+This package contains code shared with other packages.
+To use the code in the package, you need to add the following to the package.json file.
+
+```json
+{
+ "dependencies": {
+ "@extension/shared": "workspace:*"
+ }
+}
+```
diff --git a/packages/shared/build.mjs b/packages/shared/build.mjs
new file mode 100644
index 0000000..c28a283
--- /dev/null
+++ b/packages/shared/build.mjs
@@ -0,0 +1,15 @@
+import esbuild from 'esbuild';
+
+/**
+ * @type { import('esbuild').BuildOptions }
+ */
+const buildOptions = {
+ entryPoints: ['./index.ts', './lib/**/*.ts', './lib/**/*.tsx'],
+ tsconfig: './tsconfig.json',
+ bundle: false,
+ target: 'es6',
+ outdir: './dist',
+ sourcemap: true,
+};
+
+await esbuild.build(buildOptions);
diff --git a/packages/shared/index.ts b/packages/shared/index.ts
new file mode 100644
index 0000000..80eece6
--- /dev/null
+++ b/packages/shared/index.ts
@@ -0,0 +1,3 @@
+export * from './lib/hooks';
+export * from './lib/hoc';
+export * from './lib/utils';
diff --git a/packages/shared/lib/hoc/index.ts b/packages/shared/lib/hoc/index.ts
new file mode 100644
index 0000000..0ea60db
--- /dev/null
+++ b/packages/shared/lib/hoc/index.ts
@@ -0,0 +1,4 @@
+import { withSuspense } from './withSuspense';
+import { withErrorBoundary } from './withErrorBoundary';
+
+export { withSuspense, withErrorBoundary };
diff --git a/packages/shared/lib/hoc/withErrorBoundary.tsx b/packages/shared/lib/hoc/withErrorBoundary.tsx
new file mode 100644
index 0000000..4b6f950
--- /dev/null
+++ b/packages/shared/lib/hoc/withErrorBoundary.tsx
@@ -0,0 +1,43 @@
+import type { ComponentType, ErrorInfo, ReactElement } from 'react';
+import { Component } from 'react';
+
+class ErrorBoundary extends Component<
+ {
+ children: ReactElement;
+ fallback: ReactElement;
+ },
+ {
+ hasError: boolean;
+ }
+> {
+ state = { hasError: false };
+
+ static getDerivedStateFromError() {
+ return { hasError: true };
+ }
+
+ componentDidCatch(error: Error, errorInfo: ErrorInfo) {
+ console.error(error, errorInfo);
+ }
+
+ render() {
+ if (this.state.hasError) {
+ return this.props.fallback;
+ }
+
+ return this.props.children;
+ }
+}
+
+export function withErrorBoundary>(
+ Component: ComponentType,
+ ErrorComponent: ReactElement,
+) {
+ return function WithErrorBoundary(props: T) {
+ return (
+
+
+
+ );
+ };
+}
diff --git a/packages/shared/lib/hoc/withSuspense.tsx b/packages/shared/lib/hoc/withSuspense.tsx
new file mode 100644
index 0000000..8f7c94f
--- /dev/null
+++ b/packages/shared/lib/hoc/withSuspense.tsx
@@ -0,0 +1,15 @@
+import type { ComponentType, ReactElement } from 'react';
+import { Suspense } from 'react';
+
+export function withSuspense>(
+ Component: ComponentType,
+ SuspenseComponent: ReactElement,
+) {
+ return function WithSuspense(props: T) {
+ return (
+
+
+
+ );
+ };
+}
diff --git a/packages/shared/lib/hooks/index.ts b/packages/shared/lib/hooks/index.ts
new file mode 100644
index 0000000..ce185d9
--- /dev/null
+++ b/packages/shared/lib/hooks/index.ts
@@ -0,0 +1 @@
+export * from './useStorage';
diff --git a/packages/shared/lib/hooks/useStorage.tsx b/packages/shared/lib/hooks/useStorage.tsx
new file mode 100644
index 0000000..4285f85
--- /dev/null
+++ b/packages/shared/lib/hooks/useStorage.tsx
@@ -0,0 +1,50 @@
+import { useSyncExternalStore } from 'react';
+import type { BaseStorage } from '@extension/storage';
+
+type WrappedPromise = ReturnType;
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const storageMap: Map, WrappedPromise> = new Map();
+
+export function useStorage<
+ Storage extends BaseStorage,
+ Data = Storage extends BaseStorage ? Data : unknown,
+>(storage: Storage) {
+ const _data = useSyncExternalStore(storage.subscribe, storage.getSnapshot);
+
+ if (!storageMap.has(storage)) {
+ storageMap.set(storage, wrapPromise(storage.get()));
+ }
+ if (_data !== null) {
+ storageMap.set(storage, { read: () => _data });
+ }
+
+ return (_data ?? storageMap.get(storage)!.read()) as Exclude>;
+}
+
+function wrapPromise(promise: Promise) {
+ let status = 'pending';
+ let result: R;
+ const suspender = promise.then(
+ r => {
+ status = 'success';
+ result = r;
+ },
+ e => {
+ status = 'error';
+ result = e;
+ },
+ );
+
+ return {
+ read() {
+ switch (status) {
+ case 'pending':
+ throw suspender;
+ case 'error':
+ throw result;
+ default:
+ return result;
+ }
+ },
+ };
+}
diff --git a/packages/shared/lib/utils/index.ts b/packages/shared/lib/utils/index.ts
new file mode 100644
index 0000000..40b21b3
--- /dev/null
+++ b/packages/shared/lib/utils/index.ts
@@ -0,0 +1 @@
+export * from './shared-types';
diff --git a/packages/shared/lib/utils/shared-types.ts b/packages/shared/lib/utils/shared-types.ts
new file mode 100644
index 0000000..5f2cf2c
--- /dev/null
+++ b/packages/shared/lib/utils/shared-types.ts
@@ -0,0 +1 @@
+export type ValueOf = T[keyof T];
diff --git a/packages/shared/package.json b/packages/shared/package.json
new file mode 100644
index 0000000..5c1bca0
--- /dev/null
+++ b/packages/shared/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "@extension/shared",
+ "version": "0.3.5",
+ "description": "chrome extension - shared code",
+ "private": true,
+ "sideEffects": false,
+ "files": [
+ "dist/**"
+ ],
+ "types": "index.ts",
+ "main": "./dist/index.js",
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "ready": "node build.mjs",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/storage": "workspace:*",
+ "@extension/tsconfig": "workspace:*"
+ }
+}
diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json
new file mode 100644
index 0000000..f6877b2
--- /dev/null
+++ b/packages/shared/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome"]
+ },
+ "include": ["index.ts", "lib"]
+}
diff --git a/packages/storage/.eslintignore b/packages/storage/.eslintignore
new file mode 100644
index 0000000..de4d1f0
--- /dev/null
+++ b/packages/storage/.eslintignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/packages/storage/build.mjs b/packages/storage/build.mjs
new file mode 100644
index 0000000..4cfc753
--- /dev/null
+++ b/packages/storage/build.mjs
@@ -0,0 +1,15 @@
+import esbuild from 'esbuild';
+
+/**
+ * @type { import('esbuild').BuildOptions }
+ */
+const buildOptions = {
+ entryPoints: ['./index.ts', './lib/**/*.ts'],
+ tsconfig: './tsconfig.json',
+ bundle: false,
+ target: 'es6',
+ outdir: './dist',
+ sourcemap: true,
+};
+
+await esbuild.build(buildOptions);
diff --git a/packages/storage/index.ts b/packages/storage/index.ts
new file mode 100644
index 0000000..f41a696
--- /dev/null
+++ b/packages/storage/index.ts
@@ -0,0 +1 @@
+export * from './lib';
diff --git a/packages/storage/lib/base/base.ts b/packages/storage/lib/base/base.ts
new file mode 100644
index 0000000..0ed6ccc
--- /dev/null
+++ b/packages/storage/lib/base/base.ts
@@ -0,0 +1,157 @@
+import type { BaseStorage, StorageConfig, ValueOrUpdate } from './types';
+import { SessionAccessLevelEnum, StorageEnum } from './enums';
+
+/**
+ * Chrome reference error while running `processTailwindFeatures` in tailwindcss.
+ * To avoid this, we need to check if the globalThis.chrome is available and add fallback logic.
+ */
+const chrome = globalThis.chrome;
+
+/**
+ * Sets or updates an arbitrary cache with a new value or the result of an update function.
+ */
+async function updateCache(valueOrUpdate: ValueOrUpdate, cache: D | null): Promise {
+ // Type guard to check if our value or update is a function
+ function isFunction(value: ValueOrUpdate): value is (prev: D) => D | Promise {
+ return typeof value === 'function';
+ }
+
+ // Type guard to check in case of a function, if its a Promise
+ function returnsPromise(func: (prev: D) => D | Promise): func is (prev: D) => Promise {
+ // Use ReturnType to infer the return type of the function and check if it's a Promise
+ return (func as (prev: D) => Promise) instanceof Promise;
+ }
+
+ if (isFunction(valueOrUpdate)) {
+ // Check if the function returns a Promise
+ if (returnsPromise(valueOrUpdate)) {
+ return valueOrUpdate(cache as D);
+ } else {
+ return valueOrUpdate(cache as D);
+ }
+ } else {
+ return valueOrUpdate;
+ }
+}
+
+/**
+ * If one session storage needs access from content scripts, we need to enable it globally.
+ * @default false
+ */
+let globalSessionAccessLevelFlag: StorageConfig['sessionAccessForContentScripts'] = false;
+
+/**
+ * Checks if the storage permission is granted in the manifest.json.
+ */
+function checkStoragePermission(storageEnum: StorageEnum): void {
+ if (!chrome) {
+ return;
+ }
+
+ if (chrome.storage[storageEnum] === undefined) {
+ throw new Error(`Check your storage permission in manifest.json: ${storageEnum} is not defined`);
+ }
+}
+
+/**
+ * Creates a storage area for persisting and exchanging data.
+ */
+export function createStorage(key: string, fallback: D, config?: StorageConfig): BaseStorage {
+ let cache: D | null = null;
+ let initedCache = false;
+ let listeners: Array<() => void> = [];
+
+ const storageEnum = config?.storageEnum ?? StorageEnum.Local;
+ const liveUpdate = config?.liveUpdate ?? false;
+
+ const serialize = config?.serialization?.serialize ?? ((v: D) => v);
+ const deserialize = config?.serialization?.deserialize ?? (v => v as D);
+
+ // Set global session storage access level for StoryType.Session, only when not already done but needed.
+ if (
+ globalSessionAccessLevelFlag === false &&
+ storageEnum === StorageEnum.Session &&
+ config?.sessionAccessForContentScripts === true
+ ) {
+ checkStoragePermission(storageEnum);
+ chrome?.storage[storageEnum]
+ .setAccessLevel({
+ accessLevel: SessionAccessLevelEnum.ExtensionPagesAndContentScripts,
+ })
+ .catch(error => {
+ console.warn(error);
+ console.warn('Please call setAccessLevel into different context, like a background script.');
+ });
+ globalSessionAccessLevelFlag = true;
+ }
+
+ // Register life cycle methods
+ const get = async (): Promise => {
+ checkStoragePermission(storageEnum);
+ const value = await chrome?.storage[storageEnum].get([key]);
+
+ if (!value) {
+ return fallback;
+ }
+
+ return deserialize(value[key]) ?? fallback;
+ };
+
+ const _emitChange = () => {
+ listeners.forEach(listener => listener());
+ };
+
+ const set = async (valueOrUpdate: ValueOrUpdate) => {
+ if (!initedCache) {
+ cache = await get();
+ }
+ cache = await updateCache(valueOrUpdate, cache);
+
+ await chrome?.storage[storageEnum].set({ [key]: serialize(cache) });
+ _emitChange();
+ };
+
+ const subscribe = (listener: () => void) => {
+ listeners = [...listeners, listener];
+
+ return () => {
+ listeners = listeners.filter(l => l !== listener);
+ };
+ };
+
+ const getSnapshot = () => {
+ return cache;
+ };
+
+ get().then(data => {
+ cache = data;
+ initedCache = true;
+ _emitChange();
+ });
+
+ // Listener for live updates from the browser
+ async function _updateFromStorageOnChanged(changes: { [key: string]: chrome.storage.StorageChange }) {
+ // Check if the key we are listening for is in the changes object
+ if (changes[key] === undefined) return;
+
+ const valueOrUpdate: ValueOrUpdate = deserialize(changes[key].newValue);
+
+ if (cache === valueOrUpdate) return;
+
+ cache = await updateCache(valueOrUpdate, cache);
+
+ _emitChange();
+ }
+
+ // Register listener for live updates for our storage area
+ if (liveUpdate) {
+ chrome?.storage[storageEnum].onChanged.addListener(_updateFromStorageOnChanged);
+ }
+
+ return {
+ get,
+ set,
+ getSnapshot,
+ subscribe,
+ };
+}
diff --git a/packages/storage/lib/base/enums.ts b/packages/storage/lib/base/enums.ts
new file mode 100644
index 0000000..4f76282
--- /dev/null
+++ b/packages/storage/lib/base/enums.ts
@@ -0,0 +1,42 @@
+/**
+ * Storage area type for persisting and exchanging data.
+ * @see https://developer.chrome.com/docs/extensions/reference/storage/#overview
+ */
+export enum StorageEnum {
+ /**
+ * Persist data locally against browser restarts. Will be deleted by uninstalling the extension.
+ * @default
+ */
+ Local = 'local',
+ /**
+ * Uploads data to the users account in the cloud and syncs to the users browsers on other devices. Limits apply.
+ */
+ Sync = 'sync',
+ /**
+ * Requires an [enterprise policy](https://www.chromium.org/administrators/configuring-policy-for-extensions) with a
+ * json schema for company wide config.
+ */
+ Managed = 'managed',
+ /**
+ * Only persist data until the browser is closed. Recommended for service workers which can shutdown anytime and
+ * therefore need to restore their state. Set {@link SessionAccessLevelEnum} for permitting content scripts access.
+ * @implements Chromes [Session Storage](https://developer.chrome.com/docs/extensions/reference/storage/#property-session)
+ */
+ Session = 'session',
+}
+
+/**
+ * Global access level requirement for the {@link StorageEnum.Session} Storage Area.
+ * @implements Chromes [Session Access Level](https://developer.chrome.com/docs/extensions/reference/storage/#method-StorageArea-setAccessLevel)
+ */
+export enum SessionAccessLevelEnum {
+ /**
+ * Storage can only be accessed by Extension pages (not Content scripts).
+ * @default
+ */
+ ExtensionPagesOnly = 'TRUSTED_CONTEXTS',
+ /**
+ * Storage can be accessed by both Extension pages and Content scripts.
+ */
+ ExtensionPagesAndContentScripts = 'TRUSTED_AND_UNTRUSTED_CONTEXTS',
+}
diff --git a/packages/storage/lib/base/types.ts b/packages/storage/lib/base/types.ts
new file mode 100644
index 0000000..52fd09f
--- /dev/null
+++ b/packages/storage/lib/base/types.ts
@@ -0,0 +1,45 @@
+import type { StorageEnum } from './enums';
+
+export type ValueOrUpdate = D | ((prev: D) => Promise | D);
+
+export type BaseStorage = {
+ get: () => Promise;
+ set: (value: ValueOrUpdate) => Promise;
+ getSnapshot: () => D | null;
+ subscribe: (listener: () => void) => () => void;
+};
+
+export type StorageConfig = {
+ /**
+ * Assign the {@link StorageEnum} to use.
+ * @default Local
+ */
+ storageEnum?: StorageEnum;
+ /**
+ * Only for {@link StorageEnum.Session}: Grant Content scripts access to storage area?
+ * @default false
+ */
+ sessionAccessForContentScripts?: boolean;
+ /**
+ * Keeps state live in sync between all instances of the extension. Like between popup, side panel and content scripts.
+ * To allow chrome background scripts to stay in sync as well, use {@link StorageEnum.Session} storage area with
+ * {@link StorageConfig.sessionAccessForContentScripts} potentially also set to true.
+ * @see https://stackoverflow.com/a/75637138/2763239
+ * @default false
+ */
+ liveUpdate?: boolean;
+ /**
+ * An optional props for converting values from storage and into it.
+ * @default undefined
+ */
+ serialization?: {
+ /**
+ * convert non-native values to string to be saved in storage
+ */
+ serialize: (value: D) => string;
+ /**
+ * convert string value from storage to non-native values
+ */
+ deserialize: (text: string) => D;
+ };
+};
diff --git a/packages/storage/lib/impl/exampleThemeStorage.ts b/packages/storage/lib/impl/exampleThemeStorage.ts
new file mode 100644
index 0000000..9573c27
--- /dev/null
+++ b/packages/storage/lib/impl/exampleThemeStorage.ts
@@ -0,0 +1,24 @@
+import { StorageEnum } from '../base/enums';
+import { createStorage } from '../base/base';
+import type { BaseStorage } from '../base/types';
+
+type Theme = 'light' | 'dark';
+
+type ThemeStorage = BaseStorage & {
+ toggle: () => Promise;
+};
+
+const storage = createStorage('theme-storage-key', 'light', {
+ storageEnum: StorageEnum.Local,
+ liveUpdate: true,
+});
+
+// You can extend it with your own methods
+export const exampleThemeStorage: ThemeStorage = {
+ ...storage,
+ toggle: async () => {
+ await storage.set(currentTheme => {
+ return currentTheme === 'light' ? 'dark' : 'light';
+ });
+ },
+};
diff --git a/packages/storage/lib/impl/index.ts b/packages/storage/lib/impl/index.ts
new file mode 100644
index 0000000..bb9f0cb
--- /dev/null
+++ b/packages/storage/lib/impl/index.ts
@@ -0,0 +1 @@
+export * from './exampleThemeStorage';
diff --git a/packages/storage/lib/index.ts b/packages/storage/lib/index.ts
new file mode 100644
index 0000000..3172289
--- /dev/null
+++ b/packages/storage/lib/index.ts
@@ -0,0 +1,2 @@
+export type { BaseStorage } from './base/types';
+export * from './impl';
diff --git a/packages/storage/package.json b/packages/storage/package.json
new file mode 100644
index 0000000..ac6f7d4
--- /dev/null
+++ b/packages/storage/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "@extension/storage",
+ "version": "0.3.5",
+ "description": "chrome extension - storage",
+ "private": true,
+ "sideEffects": false,
+ "files": [
+ "dist/**"
+ ],
+ "main": "./dist/index.js",
+ "types": "index.ts",
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "ready": "node build.mjs",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*"
+ }
+}
diff --git a/packages/storage/tsconfig.json b/packages/storage/tsconfig.json
new file mode 100644
index 0000000..f6877b2
--- /dev/null
+++ b/packages/storage/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome"]
+ },
+ "include": ["index.ts", "lib"]
+}
diff --git a/packages/tailwind-config/package.json b/packages/tailwind-config/package.json
new file mode 100644
index 0000000..f651647
--- /dev/null
+++ b/packages/tailwind-config/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "@extension/tailwindcss-config",
+ "version": "0.3.5",
+ "description": "chrome extension - tailwindcss configuration",
+ "main": "tailwind.config.ts",
+ "private": true
+}
diff --git a/packages/tailwind-config/tailwind.config.ts b/packages/tailwind-config/tailwind.config.ts
new file mode 100644
index 0000000..1b88671
--- /dev/null
+++ b/packages/tailwind-config/tailwind.config.ts
@@ -0,0 +1,8 @@
+import type { Config } from 'tailwindcss/types/config';
+
+export default {
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+} as Omit;
diff --git a/packages/tsconfig/app.json b/packages/tsconfig/app.json
new file mode 100644
index 0000000..aa9d24d
--- /dev/null
+++ b/packages/tsconfig/app.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Chrome Extension App",
+ "extends": "./base.json"
+}
diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json
new file mode 100644
index 0000000..98562ce
--- /dev/null
+++ b/packages/tsconfig/base.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Base",
+ "compilerOptions": {
+ "allowJs": true,
+ "noEmit": true,
+ "module": "esnext",
+ "downlevelIteration": true,
+ "isolatedModules": true,
+ "strict": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "moduleResolution": "node",
+ "allowSyntheticDefaultImports": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "noImplicitReturns": true,
+ "jsx": "react-jsx",
+ "lib": ["DOM", "ESNext"]
+ }
+}
diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json
new file mode 100644
index 0000000..57b3bea
--- /dev/null
+++ b/packages/tsconfig/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@extension/tsconfig",
+ "version": "0.3.5",
+ "description": "chrome extension - tsconfig",
+ "private": true
+}
diff --git a/packages/tsconfig/utils.json b/packages/tsconfig/utils.json
new file mode 100644
index 0000000..fd59646
--- /dev/null
+++ b/packages/tsconfig/utils.json
@@ -0,0 +1,13 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Chrome Extension Utils",
+ "extends": "./base.json",
+ "compilerOptions": {
+ "noEmit": false,
+ "declaration": true,
+ "module": "CommonJS",
+ "moduleResolution": "Node",
+ "target": "ES6",
+ "types": ["node"]
+ }
+}
diff --git a/packages/ui/README.md b/packages/ui/README.md
new file mode 100644
index 0000000..dee0fac
--- /dev/null
+++ b/packages/ui/README.md
@@ -0,0 +1,352 @@
+# UI Package
+
+This package provides components that make up the UI.
+
+## Installation
+
+First, move to the page you want to use.
+
+```shell
+cd pages/options
+```
+
+Add the following to the dependencies in `package.json`.
+
+```json
+{
+ "dependencies": {
+ "@extension/ui": "workspace:*"
+ }
+}
+```
+
+Then, run `pnpm install`.
+
+```shell
+pnpm install
+```
+
+Add the following to the `tailwind.config.ts` file.
+
+```ts
+import baseConfig from '@extension/tailwindcss-config';
+import { withUI } from '@extension/ui';
+
+export default withUI({
+ ...baseConfig,
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
+});
+```
+
+Add the following to the `index.tsx` file.
+
+```tsx
+import '@extension/ui/dist/global.css';
+```
+
+## Add Component
+
+Add the following to the `lib/components/index.ts` file.
+
+```tsx
+export * from './Button';
+```
+
+Add the following to the `lib/components/Button.tsx` file.
+
+```tsx
+import { ComponentPropsWithoutRef } from 'react';
+import { cn } from '../utils';
+
+export type ButtonProps = {
+ theme?: 'light' | 'dark';
+} & ComponentPropsWithoutRef<'button'>;
+
+export function Button({ theme, className, children, ...props }: ButtonProps) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+## Usage
+
+```tsx
+import { Button } from '@extension/ui';
+
+export default function ToggleButton() {
+ const [theme, setTheme] = useState<'light' | 'dark'>('light');
+
+ const toggle = () => {
+ setTheme(theme === 'light' ? 'dark' : 'light');
+ };
+
+ return (
+
+ Toggle
+
+ );
+}
+```
+
+## Modifying the tailwind config of the UI library
+
+Modify the `tailwind.config.ts` file to make global style changes to the package.
+
+## Modifying the css variable of the UI library
+
+Modify the css variable in the `ui/lib/global.css` code to change the css variable of the package.
+
+## Guide for Adding shadcn to the UI Package
+
+You can refer to the this [manual guide](https://ui.shadcn.com/docs/installation/manual)
+
+1. Create components.json in packages/ui
+
+Create a file named `components.json` in the `packages/ui` directory with the following content:
+
+```json
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "default",
+ "rsc": false,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.ts",
+ "css": "lib/global.css",
+ "baseColor": "neutral",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/lib/components",
+ "utils": "@/lib/utils",
+ "ui": "@/lib/components/ui",
+ "lib": "@/lib"
+ }
+}
+```
+
+2. Install dependencies
+
+Run the following command from the root of your project:
+
+```shell
+pnpm add tailwindcss-animate class-variance-authority -F ui
+```
+
+3. Edit `withUI.ts` in `lib` folder
+
+This configuration file is from the manual guide. You can refer to the manual guide to modify the configuration file. ([`Configure tailwind.config.js`](https://ui.shadcn.com/docs/installation/manual))
+
+```ts
+import deepmerge from 'deepmerge';
+import type { Config } from 'tailwindcss/types/config';
+import { fontFamily } from 'tailwindcss/defaultTheme';
+import tailwindAnimate from 'tailwindcss-animate';
+
+export function withUI(tailwindConfig: Config): Config {
+ return deepmerge(
+ shadcnConfig,
+ deepmerge(tailwindConfig, {
+ content: ['./node_modules/@extension/ui/lib/**/*.{tsx,ts,js,jsx}'],
+ }),
+ );
+}
+
+const shadcnConfig = {
+ darkMode: ['class'],
+ theme: {
+ container: {
+ center: true,
+ padding: '2rem',
+ screens: {
+ '2xl': '1400px',
+ },
+ },
+ extend: {
+ colors: {
+ border: 'hsl(var(--border))',
+ input: 'hsl(var(--input))',
+ ring: 'hsl(var(--ring))',
+ background: 'hsl(var(--background))',
+ foreground: 'hsl(var(--foreground))',
+ primary: {
+ DEFAULT: 'hsl(var(--primary))',
+ foreground: 'hsl(var(--primary-foreground))',
+ },
+ secondary: {
+ DEFAULT: 'hsl(var(--secondary))',
+ foreground: 'hsl(var(--secondary-foreground))',
+ },
+ destructive: {
+ DEFAULT: 'hsl(var(--destructive))',
+ foreground: 'hsl(var(--destructive-foreground))',
+ },
+ muted: {
+ DEFAULT: 'hsl(var(--muted))',
+ foreground: 'hsl(var(--muted-foreground))',
+ },
+ accent: {
+ DEFAULT: 'hsl(var(--accent))',
+ foreground: 'hsl(var(--accent-foreground))',
+ },
+ popover: {
+ DEFAULT: 'hsl(var(--popover))',
+ foreground: 'hsl(var(--popover-foreground))',
+ },
+ card: {
+ DEFAULT: 'hsl(var(--card))',
+ foreground: 'hsl(var(--card-foreground))',
+ },
+ },
+ borderRadius: {
+ lg: `var(--radius)`,
+ md: `calc(var(--radius) - 2px)`,
+ sm: 'calc(var(--radius) - 4px)',
+ },
+ fontFamily: {
+ sans: ['var(--font-sans)', ...fontFamily.sans],
+ },
+ keyframes: {
+ 'accordion-down': {
+ from: { height: '0' },
+ to: { height: 'var(--radix-accordion-content-height)' },
+ },
+ 'accordion-up': {
+ from: { height: 'var(--radix-accordion-content-height)' },
+ to: { height: '0' },
+ },
+ },
+ animation: {
+ 'accordion-down': 'accordion-down 0.2s ease-out',
+ 'accordion-up': 'accordion-up 0.2s ease-out',
+ },
+ },
+ },
+ plugins: [tailwindAnimate],
+};
+```
+
+4. Edit `global.css` in `lib` folder
+
+This configuration also comes from the manual guide. You can refer to the manual guide to modify the configuration file. ([`Configure styles`](https://ui.shadcn.com/docs/installation/manual))
+
+```css
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 47.4% 11.2%;
+
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 47.4% 11.2%;
+
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 47.4% 11.2%;
+
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
+
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+
+ --destructive: 0 100% 50%;
+ --destructive-foreground: 210 40% 98%;
+
+ --ring: 215 20.2% 65.1%;
+
+ --radius: 0.5rem;
+ }
+
+ .dark {
+ --background: 224 71% 4%;
+ --foreground: 213 31% 91%;
+
+ --muted: 223 47% 11%;
+ --muted-foreground: 215.4 16.3% 56.9%;
+
+ --accent: 216 34% 17%;
+ --accent-foreground: 210 40% 98%;
+
+ --popover: 224 71% 4%;
+ --popover-foreground: 215 20.2% 65.1%;
+
+ --border: 216 34% 17%;
+ --input: 216 34% 17%;
+
+ --card: 224 71% 4%;
+ --card-foreground: 213 31% 91%;
+
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 1.2%;
+
+ --secondary: 222.2 47.4% 11.2%;
+ --secondary-foreground: 210 40% 98%;
+
+ --destructive: 0 63% 31%;
+ --destructive-foreground: 210 40% 98%;
+
+ --ring: 216 34% 17%;
+
+ --radius: 0.5rem;
+ }
+}
+
+@layer base {
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground;
+ font-feature-settings: "rlig" 1, "calt" 1;
+ }
+}
+```
+
+5. Add shadcn components
+
+Finally, run this command from the root of your project to add the button component:
+
+```shell
+pnpm dlx shadcn@latest add button -c ./packages/ui
+```
+
+This will add the shadcn button component to your UI package.
+
+Remember to adjust any paths or package names if your project structure differs from the assumed layout in this guide.
+
+6. Export components
+
+Make the `index.ts` file in the `components/ui` directory export the button component:
+
+```ts
+export * from './button';
+```
+
+Edit the `index.ts` file in the `packages/ui` directory to export the shadcn ui component:
+
+```ts
+// export * from './lib/components'; // remove this line: duplicated button component
+export * from './lib/components/ui';
+```
diff --git a/packages/ui/build.mjs b/packages/ui/build.mjs
new file mode 100644
index 0000000..5b6d691
--- /dev/null
+++ b/packages/ui/build.mjs
@@ -0,0 +1,32 @@
+import fs from 'node:fs';
+import { replaceTscAliasPaths } from 'tsc-alias';
+import { resolve } from 'node:path';
+import esbuild from 'esbuild';
+
+/**
+ * @type { import('esbuild').BuildOptions }
+ */
+const buildOptions = {
+ entryPoints: ['./index.ts', './lib/**/*.ts', './lib/**/*.tsx'],
+ tsconfig: './tsconfig.json',
+ bundle: false,
+ target: 'es6',
+ outdir: './dist',
+ sourcemap: true,
+};
+
+await esbuild.build(buildOptions);
+
+/**
+ * Post build paths resolve since ESBuild only natively
+ * support paths resolution for bundling scenario
+ * @url https://github.com/evanw/esbuild/issues/394#issuecomment-1537247216
+ */
+await replaceTscAliasPaths({
+ configFile: 'tsconfig.json',
+ watch: false,
+ outDir: 'dist',
+ declarationDir: 'dist',
+});
+
+fs.copyFileSync(resolve('lib', 'global.css'), resolve('dist', 'global.css'));
diff --git a/packages/ui/index.ts b/packages/ui/index.ts
new file mode 100644
index 0000000..69816af
--- /dev/null
+++ b/packages/ui/index.ts
@@ -0,0 +1,3 @@
+export * from './lib/components';
+export * from './lib/utils';
+export * from './lib/withUI';
diff --git a/packages/ui/lib/components/Button.tsx b/packages/ui/lib/components/Button.tsx
new file mode 100644
index 0000000..88c4100
--- /dev/null
+++ b/packages/ui/lib/components/Button.tsx
@@ -0,0 +1,20 @@
+import type { ComponentPropsWithoutRef } from 'react';
+import { cn } from '../utils';
+
+export type ButtonProps = {
+ theme?: 'light' | 'dark';
+} & ComponentPropsWithoutRef<'button'>;
+
+export function Button({ theme, className, children, ...props }: ButtonProps) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/ui/lib/components/index.ts b/packages/ui/lib/components/index.ts
new file mode 100644
index 0000000..8b166a8
--- /dev/null
+++ b/packages/ui/lib/components/index.ts
@@ -0,0 +1 @@
+export * from './Button';
diff --git a/packages/ui/lib/global.css b/packages/ui/lib/global.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/packages/ui/lib/global.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/packages/ui/lib/utils.ts b/packages/ui/lib/utils.ts
new file mode 100644
index 0000000..a4a5e22
--- /dev/null
+++ b/packages/ui/lib/utils.ts
@@ -0,0 +1,7 @@
+import type { ClassValue } from 'clsx';
+import { clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export const cn = (...inputs: ClassValue[]) => {
+ return twMerge(clsx(inputs));
+};
diff --git a/packages/ui/lib/withUI.ts b/packages/ui/lib/withUI.ts
new file mode 100644
index 0000000..ce7de6e
--- /dev/null
+++ b/packages/ui/lib/withUI.ts
@@ -0,0 +1,8 @@
+import deepmerge from 'deepmerge';
+import type { Config } from 'tailwindcss/types/config';
+
+export function withUI(tailwindConfig: Config): Config {
+ return deepmerge(tailwindConfig, {
+ content: ['./node_modules/@extension/ui/lib/**/*.{tsx,ts,js,jsx}'],
+ });
+}
diff --git a/packages/ui/package.json b/packages/ui/package.json
new file mode 100644
index 0000000..0eb8d03
--- /dev/null
+++ b/packages/ui/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@extension/ui",
+ "version": "0.3.5",
+ "description": "chrome extension - ui components",
+ "private": true,
+ "sideEffects": false,
+ "type": "module",
+ "files": [
+ "dist/**",
+ "dist/global.css"
+ ],
+ "types": "index.ts",
+ "main": "./dist/index.js",
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "ready": "node build.mjs",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "deepmerge": "^4.3.1",
+ "tsc-alias": "^1.8.10"
+ },
+ "dependencies": {
+ "clsx": "^2.1.1",
+ "tailwind-merge": "^2.4.0"
+ }
+}
diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json
new file mode 100644
index 0000000..f09ba2f
--- /dev/null
+++ b/packages/ui/tsconfig.json
@@ -0,0 +1,12 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "outDir": "dist",
+ "baseUrl": ".",
+ "types": ["chrome"],
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": ["index.ts", "lib"]
+}
diff --git a/packages/vite-config/index.mjs b/packages/vite-config/index.mjs
new file mode 100644
index 0000000..5e70410
--- /dev/null
+++ b/packages/vite-config/index.mjs
@@ -0,0 +1,2 @@
+export * from './lib/env.mjs';
+export * from './lib/withPageConfig.mjs';
diff --git a/packages/vite-config/lib/env.mjs b/packages/vite-config/lib/env.mjs
new file mode 100644
index 0000000..34ed304
--- /dev/null
+++ b/packages/vite-config/lib/env.mjs
@@ -0,0 +1,2 @@
+export const isDev = process.env.__DEV__ === 'true';
+export const isProduction = !isDev;
diff --git a/packages/vite-config/lib/withPageConfig.mjs b/packages/vite-config/lib/withPageConfig.mjs
new file mode 100644
index 0000000..bf91e3d
--- /dev/null
+++ b/packages/vite-config/lib/withPageConfig.mjs
@@ -0,0 +1,45 @@
+import { defineConfig } from 'vite';
+import { watchRebuildPlugin } from '@extension/hmr';
+import react from '@vitejs/plugin-react-swc';
+import deepmerge from 'deepmerge';
+import { isDev, isProduction } from './env.mjs';
+
+export const watchOption = isDev ? {
+ buildDelay: 100,
+ chokidar: {
+ ignored:[
+ /\/packages\/.*\.(ts|tsx|map)$/,
+ ]
+ }
+}: undefined;
+
+/**
+ * @typedef {import('vite').UserConfig} UserConfig
+ * @param {UserConfig} config
+ * @returns {UserConfig}
+ */
+export function withPageConfig(config) {
+ return defineConfig(
+ deepmerge(
+ {
+ base: '',
+ plugins: [react(), isDev && watchRebuildPlugin({ refresh: true })],
+ build: {
+ sourcemap: isDev,
+ minify: isProduction,
+ reportCompressedSize: isProduction,
+ emptyOutDir: isProduction,
+ watch: watchOption,
+ rollupOptions: {
+ external: ['chrome'],
+ },
+ },
+ define: {
+ 'process.env.NODE_ENV': isDev ? `"development"` : `"production"`,
+ },
+ envDir: '../..'
+ },
+ config,
+ ),
+ );
+}
diff --git a/packages/vite-config/package.json b/packages/vite-config/package.json
new file mode 100644
index 0000000..1e76f39
--- /dev/null
+++ b/packages/vite-config/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@extension/vite-config",
+ "version": "0.3.5",
+ "description": "chrome extension - vite base configuration",
+ "main": "index.mjs",
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean": "pnpm clean:node_modules"
+ },
+ "devDependencies": {
+ "@extension/hmr": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@vitejs/plugin-react-swc": "^3.7.2",
+ "deepmerge": "^4.3.1"
+ }
+}
diff --git a/packages/zipper/.eslintignore b/packages/zipper/.eslintignore
new file mode 100644
index 0000000..de4d1f0
--- /dev/null
+++ b/packages/zipper/.eslintignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/packages/zipper/index.ts b/packages/zipper/index.ts
new file mode 100644
index 0000000..efbfe21
--- /dev/null
+++ b/packages/zipper/index.ts
@@ -0,0 +1,13 @@
+import { resolve } from 'node:path';
+import { zipBundle } from './lib/zip-bundle';
+
+const YYYYMMDD = new Date().toISOString().slice(0, 10).replace(/-/g, '');
+const HHmmss = new Date().toISOString().slice(11, 19).replace(/:/g, '');
+const fileName = `extension-${YYYYMMDD}-${HHmmss}`;
+
+// package the root dist file
+zipBundle({
+ distDirectory: resolve(__dirname, '../../dist'),
+ buildDirectory: resolve(__dirname, '../../dist-zip'),
+ archiveName: process.env.__FIREFOX__ ? `${fileName}.xpi` : `${fileName}.zip`,
+});
diff --git a/packages/zipper/lib/zip-bundle/index.ts b/packages/zipper/lib/zip-bundle/index.ts
new file mode 100644
index 0000000..ddb5f2c
--- /dev/null
+++ b/packages/zipper/lib/zip-bundle/index.ts
@@ -0,0 +1,113 @@
+import { createReadStream, createWriteStream, existsSync, mkdirSync } from 'node:fs';
+import { posix, resolve } from 'node:path';
+import glob from 'fast-glob';
+import { AsyncZipDeflate, Zip } from 'fflate';
+
+// Converts bytes to megabytes
+function toMB(bytes: number): number {
+ return bytes / 1024 / 1024;
+}
+
+// Creates the build directory if it doesn't exist
+function ensureBuildDirectoryExists(buildDirectory: string): void {
+ if (!existsSync(buildDirectory)) {
+ mkdirSync(buildDirectory, { recursive: true });
+ }
+}
+
+// Logs the package size and duration
+function logPackageSize(size: number, startTime: number): void {
+ console.log(`Zip Package size: ${toMB(size).toFixed(2)} MB in ${Date.now() - startTime}ms`);
+}
+
+// Handles file streaming and zipping
+function streamFileToZip(
+ absPath: string,
+ relPath: string,
+ zip: Zip,
+ onAbort: () => void,
+ onError: (error: Error) => void,
+): void {
+ const data = new AsyncZipDeflate(relPath, { level: 9 });
+ zip.add(data);
+
+ createReadStream(absPath)
+ .on('data', (chunk: Buffer) => data.push(chunk, false))
+ .on('end', () => data.push(new Uint8Array(0), true))
+ .on('error', error => {
+ onAbort();
+ onError(error);
+ });
+}
+
+// Zips the bundle
+export const zipBundle = async (
+ {
+ distDirectory,
+ buildDirectory,
+ archiveName,
+ }: {
+ distDirectory: string;
+ buildDirectory: string;
+ archiveName: string;
+ },
+ withMaps = false,
+): Promise => {
+ ensureBuildDirectoryExists(buildDirectory);
+
+ const zipFilePath = resolve(buildDirectory, archiveName);
+ const output = createWriteStream(zipFilePath);
+
+ const fileList = await glob(
+ [
+ '**/*', // Pick all nested files
+ ...(!withMaps ? ['!**/(*.js.map|*.css.map)'] : []), // Exclude source maps conditionally
+ ],
+ {
+ cwd: distDirectory,
+ onlyFiles: true,
+ },
+ );
+
+ return new Promise((pResolve, pReject) => {
+ let aborted = false;
+ let totalSize = 0;
+ const timer = Date.now();
+ const zip = new Zip((err, data, final) => {
+ if (err) {
+ pReject(err);
+ } else {
+ totalSize += data.length;
+ output.write(data);
+ if (final) {
+ logPackageSize(totalSize, timer);
+ output.end();
+ pResolve();
+ }
+ }
+ });
+
+ // Handle file read streams
+ for (const file of fileList) {
+ if (aborted) return;
+
+ const absPath = resolve(distDirectory, file);
+ const absPosixPath = posix.resolve(distDirectory, file);
+ const relPosixPath = posix.relative(distDirectory, absPosixPath);
+
+ console.log(`Adding file: ${relPosixPath}`);
+ streamFileToZip(
+ absPath,
+ relPosixPath,
+ zip,
+ () => {
+ aborted = true;
+ zip.terminate();
+ },
+ error => pReject(`Error reading file ${absPath}: ${error.message}`),
+ );
+ }
+
+ zip.end();
+ });
+};
diff --git a/packages/zipper/package.json b/packages/zipper/package.json
new file mode 100644
index 0000000..7c470a5
--- /dev/null
+++ b/packages/zipper/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "@extension/zipper",
+ "version": "0.3.5",
+ "description": "chrome extension - zipper",
+ "private": true,
+ "sideEffects": false,
+ "files": [
+ "dist/**"
+ ],
+ "main": "dist/index.js",
+ "module": "dist/index.js",
+ "types": "index.ts",
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "zip": "tsx index.ts",
+ "ready": "tsc",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "fast-glob": "^3.3.2",
+ "fflate": "^0.8.2",
+ "tsx": "^4.19.2"
+ }
+}
diff --git a/packages/zipper/tsconfig.json b/packages/zipper/tsconfig.json
new file mode 100644
index 0000000..9dc866c
--- /dev/null
+++ b/packages/zipper/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "outDir": "dist",
+ "types": ["chrome", "node"]
+ },
+ "include": ["index.ts", "lib"]
+}
diff --git a/pages/content-runtime/package.json b/pages/content-runtime/package.json
new file mode 100644
index 0000000..34b5f3c
--- /dev/null
+++ b/pages/content-runtime/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "@extension/content-runtime-script",
+ "version": "0.3.5",
+ "description": "chrome extension - content runtime script",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "@extension/hmr": "workspace:*",
+ "@extension/vite-config": "workspace:*"
+ }
+}
diff --git a/pages/content-runtime/src/App.tsx b/pages/content-runtime/src/App.tsx
new file mode 100644
index 0000000..8cbbd37
--- /dev/null
+++ b/pages/content-runtime/src/App.tsx
@@ -0,0 +1,9 @@
+import { useEffect } from 'react';
+
+export default function App() {
+ useEffect(() => {
+ console.log('runtime content view loaded');
+ }, []);
+
+ return runtime content view
;
+}
diff --git a/pages/content-runtime/src/Root.tsx b/pages/content-runtime/src/Root.tsx
new file mode 100644
index 0000000..8b39064
--- /dev/null
+++ b/pages/content-runtime/src/Root.tsx
@@ -0,0 +1,37 @@
+import { createRoot } from 'react-dom/client';
+import App from '@src/App';
+// eslint-disable-next-line
+// @ts-ignore
+import injectedStyle from '@src/index.css?inline';
+
+export function mount() {
+ const root = document.createElement('div');
+ root.id = 'chrome-extension-boilerplate-react-vite-runtime-content-view-root';
+
+ document.body.append(root);
+
+ const rootIntoShadow = document.createElement('div');
+ rootIntoShadow.id = 'shadow-root';
+
+ const shadowRoot = root.attachShadow({ mode: 'open' });
+
+ if (navigator.userAgent.includes('Firefox')) {
+ /**
+ * In the firefox environment, adoptedStyleSheets cannot be used due to the bug
+ * @url https://bugzilla.mozilla.org/show_bug.cgi?id=1770592
+ *
+ * Injecting styles into the document, this may cause style conflicts with the host page
+ */
+ const styleElement = document.createElement('style');
+ styleElement.innerHTML = injectedStyle;
+ shadowRoot.appendChild(styleElement);
+ } else {
+ /** Inject styles into shadow dom */
+ const globalStyleSheet = new CSSStyleSheet();
+ globalStyleSheet.replaceSync(injectedStyle);
+ shadowRoot.adoptedStyleSheets = [globalStyleSheet];
+ }
+
+ shadowRoot.appendChild(rootIntoShadow);
+ createRoot(rootIntoShadow).render( );
+}
diff --git a/pages/content-runtime/src/index.css b/pages/content-runtime/src/index.css
new file mode 100644
index 0000000..151be5a
--- /dev/null
+++ b/pages/content-runtime/src/index.css
@@ -0,0 +1,3 @@
+.runtime-content-view-text {
+ font-size: 20px;
+}
diff --git a/pages/content-runtime/src/index.ts b/pages/content-runtime/src/index.ts
new file mode 100644
index 0000000..c37dc9a
--- /dev/null
+++ b/pages/content-runtime/src/index.ts
@@ -0,0 +1,4 @@
+import { mount } from '@src/Root';
+
+mount();
+console.log('runtime script loaded');
diff --git a/pages/content-runtime/tsconfig.json b/pages/content-runtime/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/content-runtime/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/content-runtime/vite.config.mts b/pages/content-runtime/vite.config.mts
new file mode 100644
index 0000000..010e144
--- /dev/null
+++ b/pages/content-runtime/vite.config.mts
@@ -0,0 +1,23 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ lib: {
+ formats: ['iife'],
+ entry: resolve(__dirname, 'src/index.ts'),
+ name: 'ContentRuntimeScript',
+ fileName: 'index',
+ },
+ outDir: resolve(rootDir, '..', '..', 'dist', 'content-runtime'),
+ },
+});
diff --git a/pages/content-ui/package.json b/pages/content-ui/package.json
new file mode 100644
index 0000000..33ebe4d
--- /dev/null
+++ b/pages/content-ui/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "@extension/content-ui",
+ "version": "0.3.5",
+ "description": "chrome extension - content ui",
+ "type": "module",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:bundle": "rimraf dist",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:bundle && pnpm clean:node_modules && pnpm clean:turbo",
+ "build:tailwindcss": "pnpm tailwindcss -i ./src/tailwind-input.css -o ./dist/tailwind-output.css -m",
+ "build": "pnpm build:tailwindcss && vite build",
+ "build:watch": "concurrently \"cross-env __DEV__=true vite build --mode development\" \"pnpm build:tailwindcss -- -w\"",
+ "dev": "pnpm build:tailwindcss && pnpm build:watch",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*",
+ "@extension/ui": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tailwindcss-config": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/hmr": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "concurrently": "^9.0.1",
+ "cross-env": "^7.0.3"
+ }
+}
diff --git a/pages/content-ui/public/logo.svg b/pages/content-ui/public/logo.svg
new file mode 100644
index 0000000..6b60c10
--- /dev/null
+++ b/pages/content-ui/public/logo.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/pages/content-ui/src/App.tsx b/pages/content-ui/src/App.tsx
new file mode 100644
index 0000000..70a0de3
--- /dev/null
+++ b/pages/content-ui/src/App.tsx
@@ -0,0 +1,23 @@
+import { useEffect } from 'react';
+import { Button } from '@extension/ui';
+import { useStorage } from '@extension/shared';
+import { exampleThemeStorage } from '@extension/storage';
+
+export default function App() {
+ const theme = useStorage(exampleThemeStorage);
+
+ useEffect(() => {
+ console.log('content ui loaded');
+ }, []);
+
+ return (
+
+
+ Edit pages/content-ui/src/app.tsx and save to reload.
+
+
+ Toggle Theme
+
+
+ );
+}
diff --git a/pages/content-ui/src/index.tsx b/pages/content-ui/src/index.tsx
new file mode 100644
index 0000000..ad1aada
--- /dev/null
+++ b/pages/content-ui/src/index.tsx
@@ -0,0 +1,33 @@
+import { createRoot } from 'react-dom/client';
+import App from '@src/App';
+import tailwindcssOutput from '../dist/tailwind-output.css?inline';
+
+const root = document.createElement('div');
+root.id = 'chrome-extension-boilerplate-react-vite-content-view-root';
+
+document.body.append(root);
+
+const rootIntoShadow = document.createElement('div');
+rootIntoShadow.id = 'shadow-root';
+
+const shadowRoot = root.attachShadow({ mode: 'open' });
+
+if (navigator.userAgent.includes('Firefox')) {
+ /**
+ * In the firefox environment, adoptedStyleSheets cannot be used due to the bug
+ * @url https://bugzilla.mozilla.org/show_bug.cgi?id=1770592
+ *
+ * Injecting styles into the document, this may cause style conflicts with the host page
+ */
+ const styleElement = document.createElement('style');
+ styleElement.innerHTML = tailwindcssOutput;
+ shadowRoot.appendChild(styleElement);
+} else {
+ /** Inject styles into shadow dom */
+ const globalStyleSheet = new CSSStyleSheet();
+ globalStyleSheet.replaceSync(tailwindcssOutput);
+ shadowRoot.adoptedStyleSheets = [globalStyleSheet];
+}
+
+shadowRoot.appendChild(rootIntoShadow);
+createRoot(rootIntoShadow).render( );
diff --git a/pages/content-ui/src/tailwind-input.css b/pages/content-ui/src/tailwind-input.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/pages/content-ui/src/tailwind-input.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/pages/content-ui/tailwind.config.ts b/pages/content-ui/tailwind.config.ts
new file mode 100644
index 0000000..7be8fa8
--- /dev/null
+++ b/pages/content-ui/tailwind.config.ts
@@ -0,0 +1,7 @@
+import baseConfig from '@extension/tailwindcss-config';
+import { withUI } from '@extension/ui';
+
+export default withUI({
+ ...baseConfig,
+ content: ['src/**/*.{ts,tsx}'],
+});
diff --git a/pages/content-ui/tsconfig.json b/pages/content-ui/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/content-ui/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/content-ui/vite.config.mts b/pages/content-ui/vite.config.mts
new file mode 100644
index 0000000..2157014
--- /dev/null
+++ b/pages/content-ui/vite.config.mts
@@ -0,0 +1,25 @@
+import { resolve } from 'node:path';
+import { makeEntryPointPlugin } from '@extension/hmr';
+import { isDev, withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ plugins: [isDev && makeEntryPointPlugin()],
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ lib: {
+ entry: resolve(srcDir, 'index.tsx'),
+ name: 'contentUI',
+ formats: ['iife'],
+ fileName: 'index',
+ },
+ outDir: resolve(rootDir, '..', '..', 'dist', 'content-ui'),
+ },
+});
diff --git a/pages/content/package.json b/pages/content/package.json
new file mode 100644
index 0000000..a3c9e33
--- /dev/null
+++ b/pages/content/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "@extension/content-script",
+ "version": "0.3.5",
+ "description": "chrome extension - content script",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/hmr": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "cross-env": "^7.0.3"
+ }
+}
diff --git a/pages/content/public/logo.svg b/pages/content/public/logo.svg
new file mode 100644
index 0000000..6b60c10
--- /dev/null
+++ b/pages/content/public/logo.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/pages/content/src/index.ts b/pages/content/src/index.ts
new file mode 100644
index 0000000..50a3921
--- /dev/null
+++ b/pages/content/src/index.ts
@@ -0,0 +1,5 @@
+import { toggleTheme } from '@src/toggleTheme';
+
+console.log('content script loaded');
+
+void toggleTheme();
diff --git a/pages/content/src/toggleTheme.ts b/pages/content/src/toggleTheme.ts
new file mode 100644
index 0000000..6b27bc5
--- /dev/null
+++ b/pages/content/src/toggleTheme.ts
@@ -0,0 +1,7 @@
+import { exampleThemeStorage } from '@extension/storage';
+
+export async function toggleTheme() {
+ console.log('initial theme:', await exampleThemeStorage.get());
+ await exampleThemeStorage.toggle();
+ console.log('toggled theme:', await exampleThemeStorage.get());
+}
diff --git a/pages/content/tsconfig.json b/pages/content/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/content/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/content/vite.config.mts b/pages/content/vite.config.mts
new file mode 100644
index 0000000..3679a89
--- /dev/null
+++ b/pages/content/vite.config.mts
@@ -0,0 +1,25 @@
+import { resolve } from 'node:path';
+import { makeEntryPointPlugin } from '@extension/hmr';
+import { isDev, withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ plugins: [isDev && makeEntryPointPlugin()],
+ build: {
+ lib: {
+ entry: resolve(__dirname, 'src/index.ts'),
+ formats: ['iife'],
+ name: 'ContentScript',
+ fileName: 'index',
+ },
+ outDir: resolve(rootDir, '..', '..', 'dist', 'content'),
+ },
+});
diff --git a/pages/devtools-panel/index.html b/pages/devtools-panel/index.html
new file mode 100644
index 0000000..8402fc1
--- /dev/null
+++ b/pages/devtools-panel/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Devtools Panel
+
+
+
+
+
+
+
diff --git a/pages/devtools-panel/package.json b/pages/devtools-panel/package.json
new file mode 100644
index 0000000..15828b6
--- /dev/null
+++ b/pages/devtools-panel/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "@extension/devtools-panel",
+ "version": "0.3.5",
+ "description": "chrome extension - devtools panel",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tailwindcss-config": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "postcss-load-config": "^6.0.1",
+ "cross-env": "^7.0.3"
+ },
+ "postcss": {
+ "plugins": {
+ "tailwindcss": {},
+ "autoprefixer": {}
+ }
+ }
+}
diff --git a/pages/devtools-panel/public/logo_horizontal.svg b/pages/devtools-panel/public/logo_horizontal.svg
new file mode 100644
index 0000000..232e97b
--- /dev/null
+++ b/pages/devtools-panel/public/logo_horizontal.svg
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/devtools-panel/public/logo_horizontal_dark.svg b/pages/devtools-panel/public/logo_horizontal_dark.svg
new file mode 100644
index 0000000..cf19a3e
--- /dev/null
+++ b/pages/devtools-panel/public/logo_horizontal_dark.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/devtools-panel/src/Panel.css b/pages/devtools-panel/src/Panel.css
new file mode 100644
index 0000000..7354dea
--- /dev/null
+++ b/pages/devtools-panel/src/Panel.css
@@ -0,0 +1,28 @@
+.App {
+ text-align: center;
+ height: 100vh;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 2rem;
+}
+
+.App-logo {
+ height: 40vmin;
+}
+
+.App-header {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+}
+
+code {
+ background: rgba(148, 163, 184, 0.5);
+ border-radius: 0.25rem;
+ padding: 0.2rem 0.5rem;
+}
diff --git a/pages/devtools-panel/src/Panel.tsx b/pages/devtools-panel/src/Panel.tsx
new file mode 100644
index 0000000..f9e71ae
--- /dev/null
+++ b/pages/devtools-panel/src/Panel.tsx
@@ -0,0 +1,44 @@
+import '@src/Panel.css';
+import { useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
+import { exampleThemeStorage } from '@extension/storage';
+import type { ComponentPropsWithoutRef } from 'react';
+
+const Panel = () => {
+ const theme = useStorage(exampleThemeStorage);
+ const isLight = theme === 'light';
+ const logo = isLight ? 'devtools-panel/logo_horizontal.svg' : 'devtools-panel/logo_horizontal_dark.svg';
+ const goGithubSite = () =>
+ chrome.tabs.create({ url: 'https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite' });
+
+ return (
+
+ );
+};
+
+const ToggleButton = (props: ComponentPropsWithoutRef<'button'>) => {
+ const theme = useStorage(exampleThemeStorage);
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default withErrorBoundary(withSuspense(Panel, Loading ...
), Error Occur
);
diff --git a/pages/devtools-panel/src/index.css b/pages/devtools-panel/src/index.css
new file mode 100644
index 0000000..392b3d2
--- /dev/null
+++ b/pages/devtools-panel/src/index.css
@@ -0,0 +1,17 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
+ 'Droid Sans', 'Helvetica Neue', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ position: relative;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
diff --git a/pages/devtools-panel/src/index.tsx b/pages/devtools-panel/src/index.tsx
new file mode 100644
index 0000000..065021d
--- /dev/null
+++ b/pages/devtools-panel/src/index.tsx
@@ -0,0 +1,15 @@
+import { createRoot } from 'react-dom/client';
+import '@src/index.css';
+import Panel from '@src/Panel';
+
+function init() {
+ const appContainer = document.querySelector('#app-container');
+ if (!appContainer) {
+ throw new Error('Can not find #app-container');
+ }
+ const root = createRoot(appContainer);
+
+ root.render( );
+}
+
+init();
diff --git a/pages/devtools-panel/tailwind.config.ts b/pages/devtools-panel/tailwind.config.ts
new file mode 100644
index 0000000..3428bbb
--- /dev/null
+++ b/pages/devtools-panel/tailwind.config.ts
@@ -0,0 +1,7 @@
+import baseConfig from '@extension/tailwindcss-config';
+import type { Config } from 'tailwindcss/types/config';
+
+export default {
+ ...baseConfig,
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
+} as Config;
diff --git a/pages/devtools-panel/tsconfig.json b/pages/devtools-panel/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/devtools-panel/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/devtools-panel/vite.config.mts b/pages/devtools-panel/vite.config.mts
new file mode 100644
index 0000000..b5cccae
--- /dev/null
+++ b/pages/devtools-panel/vite.config.mts
@@ -0,0 +1,17 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ outDir: resolve(rootDir, '..', '..', 'dist', 'devtools-panel'),
+ },
+});
diff --git a/pages/devtools/index.html b/pages/devtools/index.html
new file mode 100644
index 0000000..80ebcea
--- /dev/null
+++ b/pages/devtools/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Devtools
+
+
+
+
+
+
diff --git a/pages/devtools/package.json b/pages/devtools/package.json
new file mode 100644
index 0000000..e30d6ff
--- /dev/null
+++ b/pages/devtools/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "@extension/devtools",
+ "version": "0.3.5",
+ "description": "chrome extension - devtools",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "cross-env": "^7.0.3"
+ }
+}
diff --git a/pages/devtools/public/logo.svg b/pages/devtools/public/logo.svg
new file mode 100644
index 0000000..6b60c10
--- /dev/null
+++ b/pages/devtools/public/logo.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/pages/devtools/src/index.ts b/pages/devtools/src/index.ts
new file mode 100644
index 0000000..41fd50c
--- /dev/null
+++ b/pages/devtools/src/index.ts
@@ -0,0 +1,6 @@
+try {
+ console.log("Edit 'pages/devtools/src/index.ts' and save to reload.");
+ chrome.devtools.panels.create('Dev Tools', '/icon-34.png', '/devtools-panel/index.html');
+} catch (e) {
+ console.error(e);
+}
diff --git a/pages/devtools/tsconfig.json b/pages/devtools/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/devtools/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/devtools/vite.config.mts b/pages/devtools/vite.config.mts
new file mode 100644
index 0000000..6aa03bf
--- /dev/null
+++ b/pages/devtools/vite.config.mts
@@ -0,0 +1,17 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ outDir: resolve(rootDir, '..', '..', 'dist', 'devtools'),
+ },
+});
diff --git a/pages/new-tab/index.html b/pages/new-tab/index.html
new file mode 100644
index 0000000..121ef98
--- /dev/null
+++ b/pages/new-tab/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ New Tab
+
+
+
+
+
+
+
diff --git a/pages/new-tab/package.json b/pages/new-tab/package.json
new file mode 100644
index 0000000..8757b80
--- /dev/null
+++ b/pages/new-tab/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "@extension/new-tab",
+ "version": "0.3.5",
+ "description": "chrome extension - new tab",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*",
+ "@extension/ui": "workspace:*",
+ "@extension/i18n": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tailwindcss-config": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "sass": "1.79.4",
+ "postcss-load-config": "^6.0.1",
+ "cross-env": "^7.0.3"
+ },
+ "postcss": {
+ "plugins": {
+ "tailwindcss": {},
+ "autoprefixer": {}
+ }
+ }
+}
diff --git a/pages/new-tab/public/logo_horizontal.svg b/pages/new-tab/public/logo_horizontal.svg
new file mode 100644
index 0000000..232e97b
--- /dev/null
+++ b/pages/new-tab/public/logo_horizontal.svg
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/new-tab/public/logo_horizontal_dark.svg b/pages/new-tab/public/logo_horizontal_dark.svg
new file mode 100644
index 0000000..cf19a3e
--- /dev/null
+++ b/pages/new-tab/public/logo_horizontal_dark.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/new-tab/src/NewTab.css b/pages/new-tab/src/NewTab.css
new file mode 100644
index 0000000..26c291a
--- /dev/null
+++ b/pages/new-tab/src/NewTab.css
@@ -0,0 +1,22 @@
+.App {
+ text-align: center;
+}
+
+.App-logo {
+ height: 40vmin;
+}
+
+.App-header {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+}
+
+code {
+ background: rgba(148, 163, 184, 0.5);
+ border-radius: 0.25rem;
+ padding: 0.2rem 0.5rem;
+}
diff --git a/pages/new-tab/src/NewTab.scss b/pages/new-tab/src/NewTab.scss
new file mode 100644
index 0000000..8960c7b
--- /dev/null
+++ b/pages/new-tab/src/NewTab.scss
@@ -0,0 +1,10 @@
+$myColor: red;
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ color: $myColor;
+}
diff --git a/pages/new-tab/src/NewTab.tsx b/pages/new-tab/src/NewTab.tsx
new file mode 100644
index 0000000..4f185af
--- /dev/null
+++ b/pages/new-tab/src/NewTab.tsx
@@ -0,0 +1,34 @@
+import '@src/NewTab.css';
+import '@src/NewTab.scss';
+import { useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
+import { exampleThemeStorage } from '@extension/storage';
+import { Button } from '@extension/ui';
+import { t } from '@extension/i18n';
+
+const NewTab = () => {
+ const theme = useStorage(exampleThemeStorage);
+ const isLight = theme === 'light';
+ const logo = isLight ? 'new-tab/logo_horizontal.svg' : 'new-tab/logo_horizontal_dark.svg';
+ const goGithubSite = () =>
+ chrome.tabs.create({ url: 'https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite' });
+
+ console.log(t('hello', 'World'));
+ return (
+
+ );
+};
+
+export default withErrorBoundary(withSuspense(NewTab, {t('loading')}
), Error Occur
);
diff --git a/pages/new-tab/src/index.css b/pages/new-tab/src/index.css
new file mode 100644
index 0000000..5138222
--- /dev/null
+++ b/pages/new-tab/src/index.css
@@ -0,0 +1,15 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
+ 'Droid Sans', 'Helvetica Neue', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
diff --git a/pages/new-tab/src/index.tsx b/pages/new-tab/src/index.tsx
new file mode 100644
index 0000000..1262fd0
--- /dev/null
+++ b/pages/new-tab/src/index.tsx
@@ -0,0 +1,16 @@
+import { createRoot } from 'react-dom/client';
+import '@src/index.css';
+import '@extension/ui/lib/global.css';
+import NewTab from '@src/NewTab';
+
+function init() {
+ const appContainer = document.querySelector('#app-container');
+ if (!appContainer) {
+ throw new Error('Can not find #app-container');
+ }
+ const root = createRoot(appContainer);
+
+ root.render( );
+}
+
+init();
diff --git a/pages/new-tab/tailwind.config.ts b/pages/new-tab/tailwind.config.ts
new file mode 100644
index 0000000..ef87645
--- /dev/null
+++ b/pages/new-tab/tailwind.config.ts
@@ -0,0 +1,7 @@
+import baseConfig from '@extension/tailwindcss-config';
+import { withUI } from '@extension/ui';
+
+export default withUI({
+ ...baseConfig,
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
+});
diff --git a/pages/new-tab/tsconfig.json b/pages/new-tab/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/new-tab/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/new-tab/vite.config.mts b/pages/new-tab/vite.config.mts
new file mode 100644
index 0000000..600a4f7
--- /dev/null
+++ b/pages/new-tab/vite.config.mts
@@ -0,0 +1,17 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ outDir: resolve(rootDir, '..', '..', 'dist', 'new-tab'),
+ },
+});
diff --git a/pages/options/index.html b/pages/options/index.html
new file mode 100644
index 0000000..65e1fdd
--- /dev/null
+++ b/pages/options/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Options
+
+
+
+
+
+
+
diff --git a/pages/options/package.json b/pages/options/package.json
new file mode 100644
index 0000000..707a1ae
--- /dev/null
+++ b/pages/options/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "@extension/options",
+ "version": "0.3.5",
+ "description": "chrome extension - options",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*",
+ "@extension/ui": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tailwindcss-config": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "postcss-load-config": "^6.0.1",
+ "cross-env": "^7.0.3"
+ },
+ "postcss": {
+ "plugins": {
+ "tailwindcss": {},
+ "autoprefixer": {}
+ }
+ }
+}
diff --git a/pages/options/public/logo_horizontal.svg b/pages/options/public/logo_horizontal.svg
new file mode 100644
index 0000000..232e97b
--- /dev/null
+++ b/pages/options/public/logo_horizontal.svg
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/options/public/logo_horizontal_dark.svg b/pages/options/public/logo_horizontal_dark.svg
new file mode 100644
index 0000000..cf19a3e
--- /dev/null
+++ b/pages/options/public/logo_horizontal_dark.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/options/src/Options.css b/pages/options/src/Options.css
new file mode 100644
index 0000000..6e36d2a
--- /dev/null
+++ b/pages/options/src/Options.css
@@ -0,0 +1,26 @@
+#app-container {
+ text-align: center;
+ width: 100vw;
+ height: 100vh;
+}
+
+.App-logo {
+ height: 40vmin;
+ pointer-events: none;
+}
+
+.App {
+ width: 100vw;
+ height: 100vh;
+ font-size: calc(10px + 2vmin);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+code {
+ background: rgba(148, 163, 184, 0.5);
+ border-radius: 0.25rem;
+ padding: 0.2rem 0.5rem;
+}
diff --git a/pages/options/src/Options.tsx b/pages/options/src/Options.tsx
new file mode 100644
index 0000000..4921001
--- /dev/null
+++ b/pages/options/src/Options.tsx
@@ -0,0 +1,28 @@
+import '@src/Options.css';
+import { useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
+import { exampleThemeStorage } from '@extension/storage';
+import { Button } from '@extension/ui';
+
+const Options = () => {
+ const theme = useStorage(exampleThemeStorage);
+ const isLight = theme === 'light';
+ const logo = isLight ? 'options/logo_horizontal.svg' : 'options/logo_horizontal_dark.svg';
+ const goGithubSite = () =>
+ chrome.tabs.create({ url: 'https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite' });
+
+ return (
+
+
+
+
+
+ Edit pages/options/src/Options.tsx
+
+
+ Toggle theme
+
+
+ );
+};
+
+export default withErrorBoundary(withSuspense(Options, Loading ...
), Error Occur
);
diff --git a/pages/options/src/index.css b/pages/options/src/index.css
new file mode 100644
index 0000000..1187072
--- /dev/null
+++ b/pages/options/src/index.css
@@ -0,0 +1,11 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
+ 'Droid Sans', 'Helvetica Neue', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
diff --git a/pages/options/src/index.tsx b/pages/options/src/index.tsx
new file mode 100644
index 0000000..e06e489
--- /dev/null
+++ b/pages/options/src/index.tsx
@@ -0,0 +1,15 @@
+import { createRoot } from 'react-dom/client';
+import '@src/index.css';
+import '@extension/ui/dist/global.css';
+import Options from '@src/Options';
+
+function init() {
+ const appContainer = document.querySelector('#app-container');
+ if (!appContainer) {
+ throw new Error('Can not find #app-container');
+ }
+ const root = createRoot(appContainer);
+ root.render( );
+}
+
+init();
diff --git a/pages/options/tailwind.config.ts b/pages/options/tailwind.config.ts
new file mode 100644
index 0000000..ef87645
--- /dev/null
+++ b/pages/options/tailwind.config.ts
@@ -0,0 +1,7 @@
+import baseConfig from '@extension/tailwindcss-config';
+import { withUI } from '@extension/ui';
+
+export default withUI({
+ ...baseConfig,
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
+});
diff --git a/pages/options/tsconfig.json b/pages/options/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/options/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/options/vite.config.mts b/pages/options/vite.config.mts
new file mode 100644
index 0000000..ab85dc1
--- /dev/null
+++ b/pages/options/vite.config.mts
@@ -0,0 +1,17 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ outDir: resolve(rootDir, '..', '..', 'dist', 'options'),
+ },
+});
diff --git a/pages/popup/index.html b/pages/popup/index.html
new file mode 100644
index 0000000..f75fabf
--- /dev/null
+++ b/pages/popup/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Popup
+
+
+
+
+
+
+
diff --git a/pages/popup/package.json b/pages/popup/package.json
new file mode 100644
index 0000000..a97e379
--- /dev/null
+++ b/pages/popup/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "@extension/popup",
+ "version": "0.3.5",
+ "description": "chrome extension - popup",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*",
+ "@extension/content-runtime-script": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tailwindcss-config": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "postcss-load-config": "^6.0.1",
+ "cross-env": "^7.0.3"
+ },
+ "postcss": {
+ "plugins": {
+ "tailwindcss": {},
+ "autoprefixer": {}
+ }
+ }
+}
diff --git a/pages/popup/public/logo_vertical.svg b/pages/popup/public/logo_vertical.svg
new file mode 100644
index 0000000..5768b87
--- /dev/null
+++ b/pages/popup/public/logo_vertical.svg
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/popup/public/logo_vertical_dark.svg b/pages/popup/public/logo_vertical_dark.svg
new file mode 100644
index 0000000..b4089d8
--- /dev/null
+++ b/pages/popup/public/logo_vertical_dark.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/popup/src/Popup.css b/pages/popup/src/Popup.css
new file mode 100644
index 0000000..e29c75f
--- /dev/null
+++ b/pages/popup/src/Popup.css
@@ -0,0 +1,30 @@
+.App {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ text-align: center;
+ height: 100%;
+ padding: 1rem;
+}
+
+.App-logo {
+ height: 50vmin;
+ margin-bottom: 1rem;
+}
+
+.App-header {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: flex-end;
+ font-size: 0.75rem;
+}
+
+code {
+ background: rgba(148, 163, 184, 0.5);
+ border-radius: 0.25rem;
+ padding: 0.2rem 0.5rem;
+}
diff --git a/pages/popup/src/Popup.tsx b/pages/popup/src/Popup.tsx
new file mode 100644
index 0000000..e7235b0
--- /dev/null
+++ b/pages/popup/src/Popup.tsx
@@ -0,0 +1,79 @@
+import '@src/Popup.css';
+import { useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
+import { exampleThemeStorage } from '@extension/storage';
+import type { ComponentPropsWithoutRef } from 'react';
+
+const notificationOptions = {
+ type: 'basic',
+ iconUrl: chrome.runtime.getURL('icon-34.png'),
+ title: 'Injecting content script error',
+ message: 'You cannot inject script here!',
+} as const;
+
+const Popup = () => {
+ const theme = useStorage(exampleThemeStorage);
+ const isLight = theme === 'light';
+ const logo = isLight ? 'popup/logo_vertical.svg' : 'popup/logo_vertical_dark.svg';
+ const goGithubSite = () =>
+ chrome.tabs.create({ url: 'https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite' });
+
+ const injectContentScript = async () => {
+ const [tab] = await chrome.tabs.query({ currentWindow: true, active: true });
+
+ if (tab.url!.startsWith('about:') || tab.url!.startsWith('chrome:')) {
+ chrome.notifications.create('inject-error', notificationOptions);
+ }
+
+ await chrome.scripting
+ .executeScript({
+ target: { tabId: tab.id! },
+ files: ['/content-runtime/index.iife.js'],
+ })
+ .catch(err => {
+ // Handling errors related to other paths
+ if (err.message.includes('Cannot access a chrome:// URL')) {
+ chrome.notifications.create('inject-error', notificationOptions);
+ }
+ });
+ };
+
+ return (
+
+ );
+};
+
+const ToggleButton = (props: ComponentPropsWithoutRef<'button'>) => {
+ const theme = useStorage(exampleThemeStorage);
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default withErrorBoundary(withSuspense(Popup, Loading ...
), Error Occur
);
diff --git a/pages/popup/src/index.css b/pages/popup/src/index.css
new file mode 100644
index 0000000..11e8d16
--- /dev/null
+++ b/pages/popup/src/index.css
@@ -0,0 +1,19 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ width: 300px;
+ height: 260px;
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
+ 'Droid Sans', 'Helvetica Neue', sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ position: relative;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
diff --git a/pages/popup/src/index.tsx b/pages/popup/src/index.tsx
new file mode 100644
index 0000000..7859d2b
--- /dev/null
+++ b/pages/popup/src/index.tsx
@@ -0,0 +1,15 @@
+import { createRoot } from 'react-dom/client';
+import '@src/index.css';
+import Popup from '@src/Popup';
+
+function init() {
+ const appContainer = document.querySelector('#app-container');
+ if (!appContainer) {
+ throw new Error('Can not find #app-container');
+ }
+ const root = createRoot(appContainer);
+
+ root.render( );
+}
+
+init();
diff --git a/pages/popup/tailwind.config.ts b/pages/popup/tailwind.config.ts
new file mode 100644
index 0000000..3428bbb
--- /dev/null
+++ b/pages/popup/tailwind.config.ts
@@ -0,0 +1,7 @@
+import baseConfig from '@extension/tailwindcss-config';
+import type { Config } from 'tailwindcss/types/config';
+
+export default {
+ ...baseConfig,
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
+} as Config;
diff --git a/pages/popup/tsconfig.json b/pages/popup/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/popup/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/popup/vite.config.mts b/pages/popup/vite.config.mts
new file mode 100644
index 0000000..74de3ee
--- /dev/null
+++ b/pages/popup/vite.config.mts
@@ -0,0 +1,17 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ outDir: resolve(rootDir, '..', '..', 'dist', 'popup'),
+ },
+});
diff --git a/pages/side-panel/index.html b/pages/side-panel/index.html
new file mode 100644
index 0000000..27859dc
--- /dev/null
+++ b/pages/side-panel/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+ Side Panel
+
+
+
+
+
+
+
diff --git a/pages/side-panel/package.json b/pages/side-panel/package.json
new file mode 100644
index 0000000..4d816dd
--- /dev/null
+++ b/pages/side-panel/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "@extension/sidepanel",
+ "version": "0.3.5",
+ "description": "chrome extension - side panel",
+ "private": true,
+ "sideEffects": true,
+ "files": [
+ "dist/**"
+ ],
+ "scripts": {
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules",
+ "build": "vite build",
+ "dev": "cross-env __DEV__=true vite build --mode development",
+ "lint": "eslint . --ext .ts,.tsx",
+ "lint:fix": "pnpm lint --fix",
+ "prettier": "prettier . --write --ignore-path ../../.prettierignore",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@extension/shared": "workspace:*",
+ "@extension/storage": "workspace:*"
+ },
+ "devDependencies": {
+ "@extension/tailwindcss-config": "workspace:*",
+ "@extension/tsconfig": "workspace:*",
+ "@extension/vite-config": "workspace:*",
+ "postcss-load-config": "^6.0.1",
+ "cross-env": "^7.0.3"
+ },
+ "postcss": {
+ "plugins": {
+ "tailwindcss": {},
+ "autoprefixer": {}
+ }
+ }
+}
diff --git a/pages/side-panel/public/logo_vertical.svg b/pages/side-panel/public/logo_vertical.svg
new file mode 100644
index 0000000..5768b87
--- /dev/null
+++ b/pages/side-panel/public/logo_vertical.svg
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/side-panel/public/logo_vertical_dark.svg b/pages/side-panel/public/logo_vertical_dark.svg
new file mode 100644
index 0000000..b4089d8
--- /dev/null
+++ b/pages/side-panel/public/logo_vertical_dark.svg
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/side-panel/src/SidePanel.css b/pages/side-panel/src/SidePanel.css
new file mode 100644
index 0000000..55fb324
--- /dev/null
+++ b/pages/side-panel/src/SidePanel.css
@@ -0,0 +1,30 @@
+.App {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ text-align: center;
+ height: 100%;
+ padding: 1rem;
+}
+
+.App-logo {
+ height: 50vmin;
+ margin-bottom: 1rem;
+}
+
+.App-header {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+}
+
+code {
+ background: rgba(148, 163, 184, 0.5);
+ border-radius: 0.25rem;
+ padding: 0.2rem 0.5rem;
+}
diff --git a/pages/side-panel/src/SidePanel.tsx b/pages/side-panel/src/SidePanel.tsx
new file mode 100644
index 0000000..a240bc7
--- /dev/null
+++ b/pages/side-panel/src/SidePanel.tsx
@@ -0,0 +1,44 @@
+import '@src/SidePanel.css';
+import { useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
+import { exampleThemeStorage } from '@extension/storage';
+import type { ComponentPropsWithoutRef } from 'react';
+
+const SidePanel = () => {
+ const theme = useStorage(exampleThemeStorage);
+ const isLight = theme === 'light';
+ const logo = isLight ? 'side-panel/logo_vertical.svg' : 'side-panel/logo_vertical_dark.svg';
+ const goGithubSite = () =>
+ chrome.tabs.create({ url: 'https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite' });
+
+ return (
+
+ );
+};
+
+const ToggleButton = (props: ComponentPropsWithoutRef<'button'>) => {
+ const theme = useStorage(exampleThemeStorage);
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default withErrorBoundary(withSuspense(SidePanel, Loading ...
), Error Occur
);
diff --git a/pages/side-panel/src/index.css b/pages/side-panel/src/index.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/pages/side-panel/src/index.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/pages/side-panel/src/index.tsx b/pages/side-panel/src/index.tsx
new file mode 100644
index 0000000..992622d
--- /dev/null
+++ b/pages/side-panel/src/index.tsx
@@ -0,0 +1,14 @@
+import { createRoot } from 'react-dom/client';
+import '@src/index.css';
+import SidePanel from '@src/SidePanel';
+
+function init() {
+ const appContainer = document.querySelector('#app-container');
+ if (!appContainer) {
+ throw new Error('Can not find #app-container');
+ }
+ const root = createRoot(appContainer);
+ root.render( );
+}
+
+init();
diff --git a/pages/side-panel/tailwind.config.ts b/pages/side-panel/tailwind.config.ts
new file mode 100644
index 0000000..3428bbb
--- /dev/null
+++ b/pages/side-panel/tailwind.config.ts
@@ -0,0 +1,7 @@
+import baseConfig from '@extension/tailwindcss-config';
+import type { Config } from 'tailwindcss/types/config';
+
+export default {
+ ...baseConfig,
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
+} as Config;
diff --git a/pages/side-panel/tsconfig.json b/pages/side-panel/tsconfig.json
new file mode 100644
index 0000000..0837c72
--- /dev/null
+++ b/pages/side-panel/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "@extension/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@src/*": ["src/*"]
+ },
+ "types": ["chrome", "../../vite-env.d.ts"]
+ },
+ "include": ["src"]
+}
diff --git a/pages/side-panel/vite.config.mts b/pages/side-panel/vite.config.mts
new file mode 100644
index 0000000..707bd2b
--- /dev/null
+++ b/pages/side-panel/vite.config.mts
@@ -0,0 +1,17 @@
+import { resolve } from 'node:path';
+import { withPageConfig } from '@extension/vite-config';
+
+const rootDir = resolve(__dirname);
+const srcDir = resolve(rootDir, 'src');
+
+export default withPageConfig({
+ resolve: {
+ alias: {
+ '@src': srcDir,
+ },
+ },
+ publicDir: resolve(rootDir, 'public'),
+ build: {
+ outDir: resolve(rootDir, '..', '..', 'dist', 'side-panel'),
+ },
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..684c025
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,8689 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ eslint-plugin-tailwindcss:
+ specifier: ^3.17.4
+ version: 3.17.4(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4)))
+ react:
+ specifier: 18.3.1
+ version: 18.3.1
+ react-dom:
+ specifier: 18.3.1
+ version: 18.3.1(react@18.3.1)
+ devDependencies:
+ '@types/chrome':
+ specifier: ^0.0.270
+ version: 0.0.270
+ '@types/node':
+ specifier: ^22.5.5
+ version: 22.7.4
+ '@types/react':
+ specifier: ^18.3.3
+ version: 18.3.5
+ '@types/react-dom':
+ specifier: ^18.3.0
+ version: 18.3.0
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^7.18.0
+ version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
+ '@typescript-eslint/parser':
+ specifier: ^7.18.0
+ version: 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ autoprefixer:
+ specifier: ^10.4.20
+ version: 10.4.20(postcss@8.4.47)
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ esbuild:
+ specifier: ^0.23.0
+ version: 0.23.1
+ eslint:
+ specifier: 8.57.0
+ version: 8.57.0
+ eslint-config-airbnb-typescript:
+ specifier: 18.0.0
+ version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0)
+ eslint-config-prettier:
+ specifier: 9.1.0
+ version: 9.1.0(eslint@8.57.0)
+ eslint-plugin-import:
+ specifier: 2.29.1
+ version: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)
+ eslint-plugin-jsx-a11y:
+ specifier: 6.9.0
+ version: 6.9.0(eslint@8.57.0)
+ eslint-plugin-prettier:
+ specifier: 5.2.1
+ version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3)
+ eslint-plugin-react:
+ specifier: 7.35.0
+ version: 7.35.0(eslint@8.57.0)
+ eslint-plugin-react-hooks:
+ specifier: 4.6.2
+ version: 4.6.2(eslint@8.57.0)
+ husky:
+ specifier: ^9.1.4
+ version: 9.1.5
+ lint-staged:
+ specifier: ^15.2.7
+ version: 15.2.10
+ postcss:
+ specifier: ^8.4.47
+ version: 8.4.47
+ prettier:
+ specifier: ^3.3.3
+ version: 3.3.3
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
+ run-script-os:
+ specifier: ^1.1.6
+ version: 1.1.6
+ tailwindcss:
+ specifier: ^3.4.14
+ version: 3.4.14(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4))
+ tslib:
+ specifier: ^2.6.3
+ version: 2.7.0
+ turbo:
+ specifier: ^2.3.3
+ version: 2.3.3
+ typescript:
+ specifier: 5.5.4
+ version: 5.5.4
+ vite:
+ specifier: 6.0.5
+ version: 6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1)
+
+ chrome-extension:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../packages/storage
+ webextension-polyfill:
+ specifier: ^0.12.0
+ version: 0.12.0
+ devDependencies:
+ '@extension/dev-utils':
+ specifier: workspace:*
+ version: link:../packages/dev-utils
+ '@extension/hmr':
+ specifier: workspace:*
+ version: link:../packages/hmr
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../packages/vite-config
+ '@laynezh/vite-plugin-lib-assets':
+ specifier: ^0.6.1
+ version: 0.6.1(vite@6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1))
+ '@types/ws':
+ specifier: ^8.5.13
+ version: 8.5.13
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ deepmerge:
+ specifier: ^4.3.1
+ version: 4.3.1
+ magic-string:
+ specifier: ^0.30.10
+ version: 0.30.11
+ ts-loader:
+ specifier: ^9.5.1
+ version: 9.5.1(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.9.3)(esbuild@0.23.1))
+
+ packages/dev-utils:
+ devDependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../shared
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+
+ packages/hmr:
+ devDependencies:
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+ '@rollup/plugin-sucrase':
+ specifier: ^5.0.2
+ version: 5.0.2(rollup@4.24.0)
+ '@types/ws':
+ specifier: ^8.5.13
+ version: 8.5.13
+ esm:
+ specifier: ^3.2.25
+ version: 3.2.25
+ fast-glob:
+ specifier: ^3.3.2
+ version: 3.3.2
+ rollup:
+ specifier: ^4.24.0
+ version: 4.24.0
+ ts-node:
+ specifier: ^10.9.2
+ version: 10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4)
+ ws:
+ specifier: 8.18.0
+ version: 8.18.0
+
+ packages/i18n:
+ devDependencies:
+ '@extension/hmr':
+ specifier: workspace:*
+ version: link:../hmr
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+
+ packages/shared:
+ devDependencies:
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../storage
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+
+ packages/storage:
+ devDependencies:
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+
+ packages/tailwind-config: {}
+
+ packages/tsconfig: {}
+
+ packages/ui:
+ dependencies:
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ tailwind-merge:
+ specifier: ^2.4.0
+ version: 2.5.2
+ devDependencies:
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+ deepmerge:
+ specifier: ^4.3.1
+ version: 4.3.1
+ tsc-alias:
+ specifier: ^1.8.10
+ version: 1.8.10
+
+ packages/vite-config:
+ devDependencies:
+ '@extension/hmr':
+ specifier: workspace:*
+ version: link:../hmr
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+ '@vitejs/plugin-react-swc':
+ specifier: ^3.7.2
+ version: 3.7.2(vite@6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1))
+ deepmerge:
+ specifier: ^4.3.1
+ version: 4.3.1
+
+ packages/zipper:
+ devDependencies:
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../tsconfig
+ fast-glob:
+ specifier: ^3.3.2
+ version: 3.3.2
+ fflate:
+ specifier: ^0.8.2
+ version: 0.8.2
+ tsx:
+ specifier: ^4.19.2
+ version: 4.19.2
+
+ pages/content:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ devDependencies:
+ '@extension/hmr':
+ specifier: workspace:*
+ version: link:../../packages/hmr
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+
+ pages/content-runtime:
+ devDependencies:
+ '@extension/hmr':
+ specifier: workspace:*
+ version: link:../../packages/hmr
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+
+ pages/content-ui:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ '@extension/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ devDependencies:
+ '@extension/hmr':
+ specifier: workspace:*
+ version: link:../../packages/hmr
+ '@extension/tailwindcss-config':
+ specifier: workspace:*
+ version: link:../../packages/tailwind-config
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ concurrently:
+ specifier: ^9.0.1
+ version: 9.0.1
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+
+ pages/devtools:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ devDependencies:
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+
+ pages/devtools-panel:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ devDependencies:
+ '@extension/tailwindcss-config':
+ specifier: workspace:*
+ version: link:../../packages/tailwind-config
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ postcss-load-config:
+ specifier: ^6.0.1
+ version: 6.0.1(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.5.1)
+
+ pages/new-tab:
+ dependencies:
+ '@extension/i18n':
+ specifier: workspace:*
+ version: link:../../packages/i18n
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ '@extension/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ devDependencies:
+ '@extension/tailwindcss-config':
+ specifier: workspace:*
+ version: link:../../packages/tailwind-config
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ postcss-load-config:
+ specifier: ^6.0.1
+ version: 6.0.1(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.5.1)
+ sass:
+ specifier: 1.79.4
+ version: 1.79.4
+
+ pages/options:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ '@extension/ui':
+ specifier: workspace:*
+ version: link:../../packages/ui
+ devDependencies:
+ '@extension/tailwindcss-config':
+ specifier: workspace:*
+ version: link:../../packages/tailwind-config
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ postcss-load-config:
+ specifier: ^6.0.1
+ version: 6.0.1(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.5.1)
+
+ pages/popup:
+ dependencies:
+ '@extension/content-runtime-script':
+ specifier: workspace:*
+ version: link:../content-runtime
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ devDependencies:
+ '@extension/tailwindcss-config':
+ specifier: workspace:*
+ version: link:../../packages/tailwind-config
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ postcss-load-config:
+ specifier: ^6.0.1
+ version: 6.0.1(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.5.1)
+
+ pages/side-panel:
+ dependencies:
+ '@extension/shared':
+ specifier: workspace:*
+ version: link:../../packages/shared
+ '@extension/storage':
+ specifier: workspace:*
+ version: link:../../packages/storage
+ devDependencies:
+ '@extension/tailwindcss-config':
+ specifier: workspace:*
+ version: link:../../packages/tailwind-config
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@extension/vite-config':
+ specifier: workspace:*
+ version: link:../../packages/vite-config
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ postcss-load-config:
+ specifier: ^6.0.1
+ version: 6.0.1(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.5.1)
+
+ tests/e2e:
+ devDependencies:
+ '@extension/tsconfig':
+ specifier: workspace:*
+ version: link:../../packages/tsconfig
+ '@wdio/cli':
+ specifier: ^9.4.5
+ version: 9.4.5
+ '@wdio/globals':
+ specifier: ^9.4.5
+ version: 9.4.5(@wdio/logger@9.1.0)
+ '@wdio/local-runner':
+ specifier: ^9.1.2
+ version: 9.1.2
+ '@wdio/mocha-framework':
+ specifier: ^9.1.2
+ version: 9.1.2
+ '@wdio/spec-reporter':
+ specifier: ^9.2.14
+ version: 9.2.14
+ '@wdio/types':
+ specifier: ^9.1.2
+ version: 9.1.2
+ tsx:
+ specifier: ^4.19.2
+ version: 4.19.2
+
+packages:
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@babel/code-frame@7.24.7':
+ resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.24.7':
+ resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/highlight@7.24.7':
+ resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
+ engines: {node: '>=6.9.0'}
+
+ '@cspotcode/source-map-support@0.8.1':
+ resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
+ engines: {node: '>=12'}
+
+ '@esbuild/aix-ppc64@0.23.1':
+ resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/aix-ppc64@0.24.0':
+ resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.23.1':
+ resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm64@0.24.0':
+ resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.23.1':
+ resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-arm@0.24.0':
+ resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.23.1':
+ resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/android-x64@0.24.0':
+ resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.23.1':
+ resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-arm64@0.24.0':
+ resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.23.1':
+ resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.24.0':
+ resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.23.1':
+ resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-arm64@0.24.0':
+ resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.23.1':
+ resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.24.0':
+ resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.23.1':
+ resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm64@0.24.0':
+ resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.23.1':
+ resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.24.0':
+ resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.23.1':
+ resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.24.0':
+ resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.23.1':
+ resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.24.0':
+ resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.23.1':
+ resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.24.0':
+ resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.23.1':
+ resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.24.0':
+ resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.23.1':
+ resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.24.0':
+ resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.23.1':
+ resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.24.0':
+ resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.23.1':
+ resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.24.0':
+ resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.23.1':
+ resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.24.0':
+ resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.23.1':
+ resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-arm64@0.24.0':
+ resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.23.1':
+ resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.24.0':
+ resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.23.1':
+ resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/sunos-x64@0.24.0':
+ resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.23.1':
+ resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-arm64@0.24.0':
+ resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.23.1':
+ resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.24.0':
+ resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.23.1':
+ resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.24.0':
+ resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.4.0':
+ resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.11.0':
+ resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/eslintrc@2.1.4':
+ resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ '@eslint/js@8.57.0':
+ resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ '@humanwhocodes/config-array@0.11.14':
+ resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
+ engines: {node: '>=10.10.0'}
+ deprecated: Use @eslint/config-array instead
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/object-schema@2.0.3':
+ resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
+ deprecated: Use @eslint/object-schema instead
+
+ '@inquirer/checkbox@3.0.1':
+ resolution: {integrity: sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/confirm@4.0.1':
+ resolution: {integrity: sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==}
+ engines: {node: '>=18'}
+
+ '@inquirer/core@9.2.1':
+ resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==}
+ engines: {node: '>=18'}
+
+ '@inquirer/editor@3.0.1':
+ resolution: {integrity: sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==}
+ engines: {node: '>=18'}
+
+ '@inquirer/expand@3.0.1':
+ resolution: {integrity: sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/figures@1.0.6':
+ resolution: {integrity: sha512-yfZzps3Cso2UbM7WlxKwZQh2Hs6plrbjs1QnzQDZhK2DgyCo6D8AaHps9olkNcUFlcYERMqU3uJSp1gmy3s/qQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/input@3.0.1':
+ resolution: {integrity: sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==}
+ engines: {node: '>=18'}
+
+ '@inquirer/number@2.0.1':
+ resolution: {integrity: sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/password@3.0.1':
+ resolution: {integrity: sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/prompts@6.0.1':
+ resolution: {integrity: sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==}
+ engines: {node: '>=18'}
+
+ '@inquirer/rawlist@3.0.1':
+ resolution: {integrity: sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==}
+ engines: {node: '>=18'}
+
+ '@inquirer/search@2.0.1':
+ resolution: {integrity: sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==}
+ engines: {node: '>=18'}
+
+ '@inquirer/select@3.0.1':
+ resolution: {integrity: sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==}
+ engines: {node: '>=18'}
+
+ '@inquirer/type@2.0.0':
+ resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==}
+ engines: {node: '>=18'}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@jest/expect-utils@29.7.0':
+ resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/schemas@29.6.3':
+ resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jest/types@29.6.3':
+ resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ '@jridgewell/gen-mapping@0.3.5':
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/source-map@0.3.6':
+ resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@jridgewell/trace-mapping@0.3.9':
+ resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+
+ '@laynezh/vite-plugin-lib-assets@0.6.1':
+ resolution: {integrity: sha512-pdIRW/PiJkuM7/OObjGBGfQmsWetmVObeez6uwT3nhP5cu2zT0L5QELq69caWD/v3QlPY3CPXVN0kZrzQzdvsQ==}
+ peerDependencies:
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
+ '@pkgr/core@0.1.1':
+ resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
+ engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+
+ '@promptbook/utils@0.70.0-1':
+ resolution: {integrity: sha512-qd2lLRRN+sE6UuNMi2tEeUUeb4zmXnxY5EMdfHVXNE+bqBDpUC7/aEfXgA3jnUXEr+xFjQ8PTFQgWvBMaKvw0g==}
+
+ '@puppeteer/browsers@2.4.0':
+ resolution: {integrity: sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@rollup/plugin-sucrase@5.0.2':
+ resolution: {integrity: sha512-4MhIVH9Dy2Hwose1/x5QMs0XF7yn9jDd/yozHqzdIrMWIolgFpGnrnVhQkqTaK1RALY/fpyrEKmwH/04vr1THA==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^2.53.1||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
+ '@rollup/pluginutils@5.1.0':
+ resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.24.0':
+ resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.24.0':
+ resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.24.0':
+ resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.24.0':
+ resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.24.0':
+ resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.24.0':
+ resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.24.0':
+ resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.24.0':
+ resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.24.0':
+ resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.24.0':
+ resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.24.0':
+ resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.24.0':
+ resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.24.0':
+ resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.24.0':
+ resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.24.0':
+ resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.24.0':
+ resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@sec-ant/readable-stream@0.4.1':
+ resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
+
+ '@sinclair/typebox@0.27.8':
+ resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
+
+ '@sindresorhus/merge-streams@4.0.0':
+ resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
+ engines: {node: '>=18'}
+
+ '@swc/core-darwin-arm64@1.9.3':
+ resolution: {integrity: sha512-hGfl/KTic/QY4tB9DkTbNuxy5cV4IeejpPD4zo+Lzt4iLlDWIeANL4Fkg67FiVceNJboqg48CUX+APhDHO5G1w==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@swc/core-darwin-x64@1.9.3':
+ resolution: {integrity: sha512-IaRq05ZLdtgF5h9CzlcgaNHyg4VXuiStnOFpfNEMuI5fm5afP2S0FHq8WdakUz5WppsbddTdplL+vpeApt/WCQ==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@swc/core-linux-arm-gnueabihf@1.9.3':
+ resolution: {integrity: sha512-Pbwe7xYprj/nEnZrNBvZfjnTxlBIcfApAGdz2EROhjpPj+FBqBa3wOogqbsuGGBdCphf8S+KPprL1z+oDWkmSQ==}
+ engines: {node: '>=10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@swc/core-linux-arm64-gnu@1.9.3':
+ resolution: {integrity: sha512-AQ5JZiwNGVV/2K2TVulg0mw/3LYfqpjZO6jDPtR2evNbk9Yt57YsVzS+3vHSlUBQDRV9/jqMuZYVU3P13xrk+g==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@swc/core-linux-arm64-musl@1.9.3':
+ resolution: {integrity: sha512-tzVH480RY6RbMl/QRgh5HK3zn1ZTFsThuxDGo6Iuk1MdwIbdFYUY034heWUTI4u3Db97ArKh0hNL0xhO3+PZdg==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@swc/core-linux-x64-gnu@1.9.3':
+ resolution: {integrity: sha512-ivXXBRDXDc9k4cdv10R21ccBmGebVOwKXT/UdH1PhxUn9m/h8erAWjz5pcELwjiMf27WokqPgaWVfaclDbgE+w==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@swc/core-linux-x64-musl@1.9.3':
+ resolution: {integrity: sha512-ILsGMgfnOz1HwdDz+ZgEuomIwkP1PHT6maigZxaCIuC6OPEhKE8uYna22uU63XvYcLQvZYDzpR3ms47WQPuNEg==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@swc/core-win32-arm64-msvc@1.9.3':
+ resolution: {integrity: sha512-e+XmltDVIHieUnNJHtspn6B+PCcFOMYXNJB1GqoCcyinkEIQNwC8KtWgMqUucUbEWJkPc35NHy9k8aCXRmw9Kg==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@swc/core-win32-ia32-msvc@1.9.3':
+ resolution: {integrity: sha512-rqpzNfpAooSL4UfQnHhkW8aL+oyjqJniDP0qwZfGnjDoJSbtPysHg2LpcOBEdSnEH+uIZq6J96qf0ZFD8AGfXA==}
+ engines: {node: '>=10'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@swc/core-win32-x64-msvc@1.9.3':
+ resolution: {integrity: sha512-3YJJLQ5suIEHEKc1GHtqVq475guiyqisKSoUnoaRtxkDaW5g1yvPt9IoSLOe2mRs7+FFhGGU693RsBUSwOXSdQ==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@swc/core@1.9.3':
+ resolution: {integrity: sha512-oRj0AFePUhtatX+BscVhnzaAmWjpfAeySpM1TCbxA1rtBDeH/JDhi5yYzAKneDYtVtBvA7ApfeuzhMC9ye4xSg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@swc/helpers': '*'
+ peerDependenciesMeta:
+ '@swc/helpers':
+ optional: true
+
+ '@swc/counter@0.1.3':
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+
+ '@swc/types@0.1.17':
+ resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==}
+
+ '@tootallnate/quickjs-emscripten@0.23.0':
+ resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
+
+ '@tsconfig/node10@1.0.11':
+ resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
+
+ '@tsconfig/node12@1.0.11':
+ resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
+
+ '@tsconfig/node14@1.0.3':
+ resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
+
+ '@tsconfig/node16@1.0.4':
+ resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+
+ '@types/chrome@0.0.270':
+ resolution: {integrity: sha512-ADvkowV7YnJfycZZxL2brluZ6STGW+9oKG37B422UePf2PCXuFA/XdERI0T18wtuWPx0tmFeZqq6MOXVk1IC+Q==}
+
+ '@types/estree@1.0.6':
+ resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+
+ '@types/filesystem@0.0.36':
+ resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==}
+
+ '@types/filewriter@0.0.33':
+ resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==}
+
+ '@types/har-format@1.2.15':
+ resolution: {integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==}
+
+ '@types/istanbul-lib-coverage@2.0.6':
+ resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
+
+ '@types/istanbul-lib-report@3.0.3':
+ resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==}
+
+ '@types/istanbul-reports@3.0.4':
+ resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/json5@0.0.29':
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+
+ '@types/mocha@10.0.7':
+ resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==}
+
+ '@types/mute-stream@0.0.4':
+ resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==}
+
+ '@types/node@20.16.10':
+ resolution: {integrity: sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==}
+
+ '@types/node@22.7.4':
+ resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==}
+
+ '@types/normalize-package-data@2.4.4':
+ resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
+
+ '@types/prop-types@15.7.12':
+ resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
+
+ '@types/react-dom@18.3.0':
+ resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
+
+ '@types/react@18.3.5':
+ resolution: {integrity: sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==}
+
+ '@types/sinonjs__fake-timers@8.1.5':
+ resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==}
+
+ '@types/stack-utils@2.0.3':
+ resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
+
+ '@types/which@2.0.2':
+ resolution: {integrity: sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==}
+
+ '@types/wrap-ansi@3.0.0':
+ resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==}
+
+ '@types/ws@8.5.13':
+ resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==}
+
+ '@types/yargs-parser@21.0.3':
+ resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
+
+ '@types/yargs@17.0.33':
+ resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==}
+
+ '@types/yauzl@2.10.3':
+ resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
+
+ '@typescript-eslint/eslint-plugin@7.18.0':
+ resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^7.0.0
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@typescript-eslint/parser@7.18.0':
+ resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@typescript-eslint/scope-manager@7.18.0':
+ resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+
+ '@typescript-eslint/type-utils@7.18.0':
+ resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@typescript-eslint/types@7.18.0':
+ resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+
+ '@typescript-eslint/typescript-estree@7.18.0':
+ resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@typescript-eslint/utils@7.18.0':
+ resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+
+ '@typescript-eslint/visitor-keys@7.18.0':
+ resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+
+ '@ungap/structured-clone@1.2.0':
+ resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+
+ '@vitejs/plugin-react-swc@3.7.2':
+ resolution: {integrity: sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==}
+ peerDependencies:
+ vite: ^4 || ^5 || ^6
+
+ '@vitest/pretty-format@2.0.5':
+ resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==}
+
+ '@vitest/pretty-format@2.1.8':
+ resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==}
+
+ '@vitest/snapshot@2.0.5':
+ resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==}
+
+ '@vitest/snapshot@2.1.8':
+ resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==}
+
+ '@wdio/cli@9.4.5':
+ resolution: {integrity: sha512-t4LfWunVw+z3VQ/pSVbNit6VyrboENhN0Rxt91PqlZKc3s0NOEMIiXVQIkUhZWDn2YvkHhxQRCJOt7pqe4n++A==}
+ engines: {node: '>=18.20.0'}
+ hasBin: true
+
+ '@wdio/config@9.1.2':
+ resolution: {integrity: sha512-M8jDFgTxOeljv5M75em7oCu2cV16jHWH6HWj5CD3ZNzaMeHf+EkIuHNyREJjt8PCnssehzXD26TF63tGPHdksA==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/config@9.4.4':
+ resolution: {integrity: sha512-w1Qo6QywLSGxmoglU4BiqDGNmFbwh/L6BRud4AO9nGgTuwKy6UkT7KevzlkIRiCHtdqkkjExR3xUi2OgjMdHAA==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/globals@9.1.2':
+ resolution: {integrity: sha512-1qqTZgae3WXOboUO7lqzz7Y75q6n7uKq1W9jn2wrvWByOQ9rVUM9PCKQGhmjVoQRcqXBOMAazqNrRK6Xy1cqAg==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/globals@9.4.5':
+ resolution: {integrity: sha512-zdN/2EGOr2HER59CNAtSfmr/M7BMAH5gQJix4iPkDN5buf8PQZHE16GnfKtqKTIBeNgpkBkUyjyCKoIKSUngjw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/local-runner@9.1.2':
+ resolution: {integrity: sha512-kGXNCzMHAax2d/HGx4ViHayi9zO1BZc7q9tnvamaBo4liP40DP1E8S5Kz3omsYMp0geXdZ87ZyaVRZo7tOKujw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/logger@8.38.0':
+ resolution: {integrity: sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==}
+ engines: {node: ^16.13 || >=18}
+
+ '@wdio/logger@9.1.0':
+ resolution: {integrity: sha512-1Rfg9VCy87I9IrViA1ned1Rqa66JwhCzdEo8rA8T3Ro6lBfOEwDbK1XW8ETKLWcweddzGeFalfVnvUlNgPmFdA==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/logger@9.1.3':
+ resolution: {integrity: sha512-cumRMK/gE1uedBUw3WmWXOQ7HtB6DR8EyKQioUz2P0IJtRRpglMBdZV7Svr3b++WWawOuzZHMfbTkJQmaVt8Gw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/logger@9.4.4':
+ resolution: {integrity: sha512-BXx8RXFUW2M4dcO6t5Le95Hi2ZkTQBRsvBQqLekT2rZ6Xmw8ZKZBPf0FptnoftFGg6dYmwnDidYv/0+4PiHjpQ==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/mocha-framework@9.1.2':
+ resolution: {integrity: sha512-LG8arSVsSNqV61LvyQddmtDuqjeh+mVWhNPSCUi4AjZ2mBC85DTMBbvsIBSDK59DF9Ijd4NLDpRGnPzzgXjbIA==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/protocols@9.0.8':
+ resolution: {integrity: sha512-xRH54byFf623/w/KW62xkf/C2mGyigSfMm+UT3tNEAd5ZA9X2VAWQWQBPzdcrsck7Fxk4zlQX8Kb34RSs7Cy4Q==}
+
+ '@wdio/protocols@9.4.4':
+ resolution: {integrity: sha512-IqbAWe5feY3xOwjbiW/2iwcbDU+nm5CX5Om835mxaNWqEoQiaZuTin4YgtgsPeSEBcSFtQ+2ooswr/6vIZdxSw==}
+
+ '@wdio/repl@9.0.8':
+ resolution: {integrity: sha512-3iubjl4JX5zD21aFxZwQghqC3lgu+mSs8c3NaiYYNCC+IT5cI/8QuKlgh9s59bu+N3gG988jqMJeCYlKuUv/iw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/repl@9.4.4':
+ resolution: {integrity: sha512-kchPRhoG/pCn4KhHGiL/ocNhdpR8OkD2e6sANlSUZ4TGBVi86YSIEjc2yXUwLacHknC/EnQk/SFnqd4MsNjGGg==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/reporter@9.2.14':
+ resolution: {integrity: sha512-njOqa9+w5zc9AY4fsUmW46EhZ2nzMFRXZPCmwnGZuYk81L3slVfAFhKk1wSTRhSbghjYAZndt9Yo3c4wFLh6Lg==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/runner@9.1.2':
+ resolution: {integrity: sha512-Hs/sPEzm1y9BehdQzK9vS6t6PS07gcigM42lfZSmai4xIAXDB0VZCvwWAZuq0okx2EcBTb9bIfPtx/6zqAoiXg==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/spec-reporter@9.2.14':
+ resolution: {integrity: sha512-/0QI/Lfld2gKscVAOTxgy1KyshxreDEu2F0FsiNQUUMQXuV8bN85lGgH6K3F+xZ0p17J/tg8UnWQCv2IaXTycw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/types@9.1.2':
+ resolution: {integrity: sha512-mROY3xSBBNujSH0Opo3Sfi1QUm3l7HbVQ8/bDmPCwHXOeYlx0q14rLyyZI3LrN5uJ0KPpuNrVgE36NFaG8+xxw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/types@9.2.2':
+ resolution: {integrity: sha512-nHZ9Ne9iRQFJ1TOYKUn4Fza69IshTTzk6RYmSZ51ImGs9uMZu0+S0Jm9REdly+VLN3FzxG6g2QSe0/F3uNVPdw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/types@9.4.4':
+ resolution: {integrity: sha512-Z2TAVMZiz4wCfP7ZdHqUXlYfF4qj5bBOV25A7tHxFbbdWPvFb8sSW3SU2+fxSwu02n5sV1mgfRYOsloypOXBnw==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/utils@9.1.2':
+ resolution: {integrity: sha512-8APCnvJjHkG/6KwXtrPhEYR29Ph+vs1Gx2mGRnbYXNgbworfPEIZETpienHXhDEbINdqSb7EY5LkapIjP7nKbg==}
+ engines: {node: '>=18.20.0'}
+
+ '@wdio/utils@9.4.4':
+ resolution: {integrity: sha512-CH2uHziYKZrm6xvI2Drfha+CBAK3cCHTFqhxfjP2dhz5kcCQfCEn22Bj12t2jYTILNvnxKFCxZyk+VEcQNMIKg==}
+ engines: {node: '>=18.20.0'}
+
+ '@webassemblyjs/ast@1.12.1':
+ resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==}
+
+ '@webassemblyjs/floating-point-hex-parser@1.11.6':
+ resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==}
+
+ '@webassemblyjs/helper-api-error@1.11.6':
+ resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==}
+
+ '@webassemblyjs/helper-buffer@1.12.1':
+ resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==}
+
+ '@webassemblyjs/helper-numbers@1.11.6':
+ resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==}
+
+ '@webassemblyjs/helper-wasm-bytecode@1.11.6':
+ resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==}
+
+ '@webassemblyjs/helper-wasm-section@1.12.1':
+ resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==}
+
+ '@webassemblyjs/ieee754@1.11.6':
+ resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==}
+
+ '@webassemblyjs/leb128@1.11.6':
+ resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==}
+
+ '@webassemblyjs/utf8@1.11.6':
+ resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==}
+
+ '@webassemblyjs/wasm-edit@1.12.1':
+ resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==}
+
+ '@webassemblyjs/wasm-gen@1.12.1':
+ resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==}
+
+ '@webassemblyjs/wasm-opt@1.12.1':
+ resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==}
+
+ '@webassemblyjs/wasm-parser@1.12.1':
+ resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==}
+
+ '@webassemblyjs/wast-printer@1.12.1':
+ resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==}
+
+ '@xtuc/ieee754@1.2.0':
+ resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
+
+ '@xtuc/long@4.2.2':
+ resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
+
+ '@zip.js/zip.js@2.7.52':
+ resolution: {integrity: sha512-+5g7FQswvrCHwYKNMd/KFxZSObctLSsQOgqBSi0LzwHo3li9Eh1w5cF5ndjQw9Zbr3ajVnd2+XyiX85gAetx1Q==}
+ engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'}
+
+ '@zip.js/zip.js@2.7.54':
+ resolution: {integrity: sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==}
+ engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'}
+
+ abort-controller@3.0.0:
+ resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
+ engines: {node: '>=6.5'}
+
+ acorn-import-attributes@1.9.5:
+ resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
+ peerDependencies:
+ acorn: ^8
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn-walk@8.3.4:
+ resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
+ engines: {node: '>=0.4.0'}
+
+ acorn@8.12.1:
+ resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ agent-base@7.1.1:
+ resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==}
+ engines: {node: '>= 14'}
+
+ ajv-keywords@3.5.2:
+ resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
+ peerDependencies:
+ ajv: ^6.9.1
+
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+
+ ansi-colors@4.1.3:
+ resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
+ engines: {node: '>=6'}
+
+ ansi-escapes@4.3.2:
+ resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
+ engines: {node: '>=8'}
+
+ ansi-escapes@7.0.0:
+ resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==}
+ engines: {node: '>=18'}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
+ ansi-styles@3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@5.2.0:
+ resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
+ engines: {node: '>=10'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ archiver-utils@5.0.2:
+ resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==}
+ engines: {node: '>= 14'}
+
+ archiver@7.0.1:
+ resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==}
+ engines: {node: '>= 14'}
+
+ arg@4.1.3:
+ resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-query@5.1.3:
+ resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==}
+
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
+ array-buffer-byte-length@1.0.1:
+ resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
+ engines: {node: '>= 0.4'}
+
+ array-includes@3.1.8:
+ resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
+ engines: {node: '>= 0.4'}
+
+ array-union@2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+
+ array.prototype.findlast@1.2.5:
+ resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.findlastindex@1.2.5:
+ resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flat@1.3.2:
+ resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.flatmap@1.3.2:
+ resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==}
+ engines: {node: '>= 0.4'}
+
+ array.prototype.tosorted@1.1.4:
+ resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==}
+ engines: {node: '>= 0.4'}
+
+ arraybuffer.prototype.slice@1.0.3:
+ resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
+ engines: {node: '>= 0.4'}
+
+ ast-types-flow@0.0.8:
+ resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
+
+ ast-types@0.13.4:
+ resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
+ engines: {node: '>=4'}
+
+ async-exit-hook@2.0.1:
+ resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==}
+ engines: {node: '>=0.12.0'}
+
+ async@3.2.6:
+ resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
+
+ autoprefixer@10.4.20:
+ resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ available-typed-arrays@1.0.7:
+ resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+ engines: {node: '>= 0.4'}
+
+ axe-core@4.10.0:
+ resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==}
+ engines: {node: '>=4'}
+
+ axobject-query@3.1.1:
+ resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==}
+
+ b4a@1.6.7:
+ resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ bare-events@2.5.0:
+ resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==}
+
+ bare-fs@2.3.5:
+ resolution: {integrity: sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==}
+
+ bare-os@2.4.4:
+ resolution: {integrity: sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==}
+
+ bare-path@2.1.3:
+ resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==}
+
+ bare-stream@2.3.0:
+ resolution: {integrity: sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==}
+
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ basic-ftp@5.0.5:
+ resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==}
+ engines: {node: '>=10.0.0'}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browser-stdout@1.3.1:
+ resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
+
+ browserslist@4.24.0:
+ resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer-crc32@0.2.13:
+ resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
+
+ buffer-crc32@1.0.0:
+ resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==}
+ engines: {node: '>=8.0.0'}
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ buffer@5.7.1:
+ resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
+
+ buffer@6.0.3:
+ resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
+
+ call-bind@1.0.7:
+ resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ camelcase@6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+
+ caniuse-lite@1.0.30001667:
+ resolution: {integrity: sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==}
+
+ chalk@2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chalk@5.3.0:
+ resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+
+ chardet@0.7.0:
+ resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
+
+ cheerio-select@2.1.0:
+ resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
+
+ cheerio@1.0.0:
+ resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==}
+ engines: {node: '>=18.17'}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ chokidar@4.0.1:
+ resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==}
+ engines: {node: '>= 14.16.0'}
+
+ chrome-trace-event@1.0.4:
+ resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
+ engines: {node: '>=6.0'}
+
+ ci-info@3.9.0:
+ resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
+ engines: {node: '>=8'}
+
+ cli-cursor@5.0.0:
+ resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
+ engines: {node: '>=18'}
+
+ cli-truncate@4.0.0:
+ resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
+ engines: {node: '>=18'}
+
+ cli-width@4.1.0:
+ resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
+ engines: {node: '>= 12'}
+
+ cliui@7.0.4:
+ resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ clone@1.0.4:
+ resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
+ engines: {node: '>=0.8'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ color-convert@1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.3:
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ colorette@2.0.20:
+ resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+
+ commander@12.1.0:
+ resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+ engines: {node: '>=18'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ commander@9.5.0:
+ resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
+ engines: {node: ^12.20.0 || >=14}
+
+ compress-commons@6.0.2:
+ resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==}
+ engines: {node: '>= 14'}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ concurrently@9.0.1:
+ resolution: {integrity: sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ confusing-browser-globals@1.0.11:
+ resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==}
+
+ core-util-is@1.0.3:
+ resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+
+ crc-32@1.2.2:
+ resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
+ engines: {node: '>=0.8'}
+ hasBin: true
+
+ crc32-stream@6.0.0:
+ resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==}
+ engines: {node: '>= 14'}
+
+ create-require@1.1.1:
+ resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+
+ cross-env@7.0.3:
+ resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
+ engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
+ hasBin: true
+
+ cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+
+ css-select@5.1.0:
+ resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
+
+ css-shorthand-properties@1.1.2:
+ resolution: {integrity: sha512-C2AugXIpRGQTxaCW0N7n5jD/p5irUmCrwl03TrnMFBHDbdq44CFWR2zO7rK9xPN4Eo3pUxC4vQzQgbIpzrD1PQ==}
+
+ css-value@0.0.1:
+ resolution: {integrity: sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==}
+
+ css-what@6.1.0:
+ resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
+ engines: {node: '>= 6'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ damerau-levenshtein@1.0.8:
+ resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
+
+ data-uri-to-buffer@4.0.1:
+ resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
+ engines: {node: '>= 12'}
+
+ data-uri-to-buffer@6.0.2:
+ resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
+ engines: {node: '>= 14'}
+
+ data-view-buffer@1.0.1:
+ resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
+ engines: {node: '>= 0.4'}
+
+ data-view-byte-length@1.0.1:
+ resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==}
+ engines: {node: '>= 0.4'}
+
+ data-view-byte-offset@1.0.0:
+ resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
+ engines: {node: '>= 0.4'}
+
+ debug@3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ debug@4.3.7:
+ resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decamelize@4.0.0:
+ resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
+ engines: {node: '>=10'}
+
+ decamelize@6.0.0:
+ resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ deep-equal@2.2.3:
+ resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==}
+ engines: {node: '>= 0.4'}
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ deepmerge-ts@7.1.1:
+ resolution: {integrity: sha512-M27OAbyR/XgJujhAd6ZlYvZGzejbzvGPSZWwuzezPCdKLT9VMtK0kpRNDc5LeUDYqFN3e254gWG1yKpjidCtow==}
+ engines: {node: '>=16.0.0'}
+
+ deepmerge@4.3.1:
+ resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
+ engines: {node: '>=0.10.0'}
+
+ defaults@1.0.4:
+ resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
+
+ define-data-property@1.1.4:
+ resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
+ engines: {node: '>= 0.4'}
+
+ define-properties@1.2.1:
+ resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+ engines: {node: '>= 0.4'}
+
+ degenerator@5.0.1:
+ resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
+ engines: {node: '>= 14'}
+
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ diff-sequences@29.6.3:
+ resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ diff@4.0.2:
+ resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
+ engines: {node: '>=0.3.1'}
+
+ diff@5.2.0:
+ resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
+ engines: {node: '>=0.3.1'}
+
+ diff@7.0.0:
+ resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==}
+ engines: {node: '>=0.3.1'}
+
+ dir-glob@3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ doctrine@2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+
+ doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
+ domutils@3.1.0:
+ resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
+
+ dotenv@16.4.5:
+ resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
+ engines: {node: '>=12'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ easy-table@1.2.0:
+ resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==}
+
+ edge-paths@3.0.5:
+ resolution: {integrity: sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==}
+ engines: {node: '>=14.0.0'}
+
+ edgedriver@5.6.1:
+ resolution: {integrity: sha512-3Ve9cd5ziLByUdigw6zovVeWJjVs8QHVmqOB0sJ0WNeVPcwf4p18GnxMmVvlFmYRloUwf5suNuorea4QzwBIOA==}
+ hasBin: true
+
+ edgedriver@6.1.1:
+ resolution: {integrity: sha512-/dM/PoBf22Xg3yypMWkmRQrBKEnSyNaZ7wHGCT9+qqT14izwtFT+QvdR89rjNkMfXwW+bSFoqOfbcvM+2Cyc7w==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ ejs@3.1.10:
+ resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
+ engines: {node: '>=0.10.0'}
+ hasBin: true
+
+ electron-to-chromium@1.5.32:
+ resolution: {integrity: sha512-M+7ph0VGBQqqpTT2YrabjNKSQ2fEl9PVx6AK3N558gDH9NO8O6XN9SXXFWRo9u9PbEg/bWq+tjXQr+eXmxubCw==}
+
+ emoji-regex@10.4.0:
+ resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ encoding-sniffer@0.2.0:
+ resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==}
+
+ end-of-stream@1.4.4:
+ resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+
+ enhanced-resolve@5.17.1:
+ resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==}
+ engines: {node: '>=10.13.0'}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ environment@1.1.0:
+ resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
+ engines: {node: '>=18'}
+
+ error-ex@1.3.2:
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+
+ es-abstract@1.23.3:
+ resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
+ engines: {node: '>= 0.4'}
+
+ es-define-property@1.0.0:
+ resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-get-iterator@1.1.3:
+ resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==}
+
+ es-iterator-helpers@1.0.19:
+ resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==}
+ engines: {node: '>= 0.4'}
+
+ es-module-lexer@1.5.4:
+ resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
+
+ es-object-atoms@1.0.0:
+ resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.0.3:
+ resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
+ engines: {node: '>= 0.4'}
+
+ es-shim-unscopables@1.0.2:
+ resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
+
+ es-to-primitive@1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.23.1:
+ resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ esbuild@0.24.0:
+ resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+
+ escape-string-regexp@2.0.0:
+ resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
+ engines: {node: '>=8'}
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ escodegen@2.1.0:
+ resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
+ engines: {node: '>=6.0'}
+ hasBin: true
+
+ eslint-config-airbnb-base@15.0.0:
+ resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ peerDependencies:
+ eslint: ^7.32.0 || ^8.2.0
+ eslint-plugin-import: ^2.25.2
+
+ eslint-config-airbnb-typescript@18.0.0:
+ resolution: {integrity: sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==}
+ peerDependencies:
+ '@typescript-eslint/eslint-plugin': ^7.0.0
+ '@typescript-eslint/parser': ^7.0.0
+ eslint: ^8.56.0
+
+ eslint-config-prettier@9.1.0:
+ resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==}
+ hasBin: true
+ peerDependencies:
+ eslint: '>=7.0.0'
+
+ eslint-import-resolver-node@0.3.9:
+ resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
+
+ eslint-module-utils@2.11.0:
+ resolution: {integrity: sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+
+ eslint-plugin-import@2.29.1:
+ resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+
+ eslint-plugin-jsx-a11y@6.9.0:
+ resolution: {integrity: sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+
+ eslint-plugin-prettier@5.2.1:
+ resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ 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
+
+ eslint-plugin-react-hooks@4.6.2:
+ resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+
+ eslint-plugin-react@7.35.0:
+ resolution: {integrity: sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
+
+ eslint-plugin-tailwindcss@3.17.4:
+ resolution: {integrity: sha512-gJAEHmCq2XFfUP/+vwEfEJ9igrPeZFg+skeMtsxquSQdxba9XRk5bn0Bp9jxG1VV9/wwPKi1g3ZjItu6MIjhNg==}
+ engines: {node: '>=18.12.0'}
+ peerDependencies:
+ tailwindcss: ^3.4.0
+
+ eslint-scope@5.1.1:
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+ engines: {node: '>=8.0.0'}
+
+ eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint@8.57.0:
+ resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
+ hasBin: true
+
+ esm@3.2.25:
+ resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
+ engines: {node: '>=6'}
+
+ espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ esquery@1.6.0:
+ resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@4.3.0:
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ event-target-shim@5.0.1:
+ resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
+ engines: {node: '>=6'}
+
+ eventemitter3@5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+
+ events@3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+
+ execa@8.0.1:
+ resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
+ engines: {node: '>=16.17'}
+
+ execa@9.3.1:
+ resolution: {integrity: sha512-gdhefCCNy/8tpH/2+ajP9IQc14vXchNdd0weyzSJEFURhRMGncQ+zKFxwjAufIewPEJm9BPOaJnvg2UtlH2gPQ==}
+ engines: {node: ^18.19.0 || >=20.5.0}
+
+ expect-webdriverio@5.0.2:
+ resolution: {integrity: sha512-vkUwoUvURH25pRClX1I5oCIObju8cT9kN5jQH4RN5QxKXK7hdowYd8dbDXD5JKOE/OutdYx67YtCl8vpZq/uSg==}
+ engines: {node: '>=18 || >=20 || >=22'}
+ peerDependencies:
+ '@wdio/globals': ^9.0.0
+ '@wdio/logger': ^9.0.0
+ webdriverio: ^9.0.0
+
+ expect@29.7.0:
+ resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ external-editor@3.1.0:
+ resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
+ engines: {node: '>=4'}
+
+ extract-zip@2.0.1:
+ resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
+ engines: {node: '>= 10.17.0'}
+ hasBin: true
+
+ fast-deep-equal@2.0.1:
+ resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-diff@1.3.0:
+ resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+
+ fast-fifo@1.3.2:
+ resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
+
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fast-xml-parser@4.5.0:
+ resolution: {integrity: sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==}
+ hasBin: true
+
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
+ fd-slicer@1.1.0:
+ resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
+
+ fetch-blob@3.2.0:
+ resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
+ engines: {node: ^12.20 || >= 14.13}
+
+ fflate@0.8.2:
+ resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
+
+ figures@6.1.0:
+ resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
+ engines: {node: '>=18'}
+
+ file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+
+ filelist@1.0.4:
+ resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ find-up@6.3.0:
+ resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ flat-cache@3.2.0:
+ resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+
+ flat@5.0.2:
+ resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+ hasBin: true
+
+ flatted@3.3.1:
+ resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
+
+ for-each@0.3.3:
+ resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
+
+ foreground-child@3.3.0:
+ resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+ engines: {node: '>=14'}
+
+ formdata-polyfill@4.0.10:
+ resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+ engines: {node: '>=12.20.0'}
+
+ fraction.js@4.3.7:
+ resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+
+ fs-extra@11.2.0:
+ resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
+ engines: {node: '>=14.14'}
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ function.prototype.name@1.1.6:
+ resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
+ engines: {node: '>= 0.4'}
+
+ functions-have-names@1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+
+ gaze@1.1.3:
+ resolution: {integrity: sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==}
+ engines: {node: '>= 4.0.0'}
+
+ geckodriver@4.5.0:
+ resolution: {integrity: sha512-EnBCT9kJ5oEoP3DaJKjzxAhm7bbNNK6k2q7oCkCT58OIOOiE6Hsr+nVDHflsNaR68HMGtBKOLSZ+YvCDHecScw==}
+ engines: {node: ^16.13 || >=18 || >=20}
+ hasBin: true
+
+ geckodriver@5.0.0:
+ resolution: {integrity: sha512-vn7TtQ3b9VMJtVXsyWtQQl1fyBVFhQy7UvJF96kPuuJ0or5THH496AD3eUyaDD11+EqCxH9t6V+EP9soZQk4YQ==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-east-asian-width@1.2.0:
+ resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
+ engines: {node: '>=18'}
+
+ get-intrinsic@1.2.4:
+ resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
+ engines: {node: '>= 0.4'}
+
+ get-port@7.1.0:
+ resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==}
+ engines: {node: '>=16'}
+
+ get-stream@5.2.0:
+ resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
+ engines: {node: '>=8'}
+
+ get-stream@8.0.1:
+ resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
+ engines: {node: '>=16'}
+
+ get-stream@9.0.1:
+ resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==}
+ engines: {node: '>=18'}
+
+ get-symbol-description@1.0.2:
+ resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
+ engines: {node: '>= 0.4'}
+
+ get-tsconfig@4.8.0:
+ resolution: {integrity: sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw==}
+
+ get-uri@6.0.3:
+ resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==}
+ engines: {node: '>= 14'}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob-to-regexp@0.4.1:
+ resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
+
+ glob@10.4.5:
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ hasBin: true
+
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ glob@7.1.7:
+ resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==}
+ deprecated: Glob versions prior to v9 are no longer supported
+
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Glob versions prior to v9 are no longer supported
+
+ glob@8.1.0:
+ resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
+ engines: {node: '>=12'}
+ deprecated: Glob versions prior to v9 are no longer supported
+
+ globals@13.24.0:
+ resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
+ engines: {node: '>=8'}
+
+ globalthis@1.0.4:
+ resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
+ engines: {node: '>= 0.4'}
+
+ globby@11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+
+ globule@1.3.4:
+ resolution: {integrity: sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==}
+ engines: {node: '>= 0.10'}
+
+ gopd@1.0.1:
+ resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ grapheme-splitter@1.0.4:
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
+
+ graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+
+ has-bigints@1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+
+ has-flag@3.0.0:
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+ engines: {node: '>=4'}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-property-descriptors@1.0.2:
+ resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
+
+ has-proto@1.0.3:
+ resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ hosted-git-info@7.0.2:
+ resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ htmlfy@0.2.1:
+ resolution: {integrity: sha512-HoomFHQ3av1uhq+7FxJTq4Ns0clAD+tGbQNrSd0WFY3UAjjUk6G3LaWEqdgmIXYkY4pexZiyZ3ykZJhQlM0J5A==}
+
+ htmlfy@0.3.2:
+ resolution: {integrity: sha512-FsxzfpeDYRqn1emox9VpxMPfGjADoUmmup8D604q497R0VNxiXs4ZZTN2QzkaMA5C9aHGUoe1iQRVSm+HK9xuA==}
+
+ htmlparser2@9.1.0:
+ resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
+
+ http-proxy-agent@7.0.2:
+ resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
+ engines: {node: '>= 14'}
+
+ https-proxy-agent@7.0.5:
+ resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==}
+ engines: {node: '>= 14'}
+
+ human-signals@5.0.0:
+ resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
+ engines: {node: '>=16.17.0'}
+
+ human-signals@8.0.0:
+ resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==}
+ engines: {node: '>=18.18.0'}
+
+ husky@9.1.5:
+ resolution: {integrity: sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ iconv-lite@0.4.24:
+ resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
+ engines: {node: '>=0.10.0'}
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ immediate@3.0.6:
+ resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
+
+ immutable@4.3.7:
+ resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
+
+ import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+
+ import-meta-resolve@4.1.0:
+ resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ inquirer@11.1.0:
+ resolution: {integrity: sha512-CmLAZT65GG/v30c+D2Fk8+ceP6pxD6RL+hIUOWAltCmeyEqWYwqu9v76q03OvjyZ3AB0C1Ala2stn1z/rMqGEw==}
+ engines: {node: '>=18'}
+
+ internal-slot@1.0.7:
+ resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
+ engines: {node: '>= 0.4'}
+
+ ip-address@9.0.5:
+ resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
+ engines: {node: '>= 12'}
+
+ is-arguments@1.1.1:
+ resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==}
+ engines: {node: '>= 0.4'}
+
+ is-array-buffer@3.0.4:
+ resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
+ engines: {node: '>= 0.4'}
+
+ is-arrayish@0.2.1:
+ resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+
+ is-async-function@2.0.0:
+ resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==}
+ engines: {node: '>= 0.4'}
+
+ is-bigint@1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-boolean-object@1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+
+ is-callable@1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+
+ is-core-module@2.15.1:
+ resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
+ engines: {node: '>= 0.4'}
+
+ is-data-view@1.0.1:
+ resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==}
+ engines: {node: '>= 0.4'}
+
+ is-date-object@1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-finalizationregistry@1.0.2:
+ resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-fullwidth-code-point@4.0.0:
+ resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
+ engines: {node: '>=12'}
+
+ is-fullwidth-code-point@5.0.0:
+ resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==}
+ engines: {node: '>=18'}
+
+ is-generator-function@1.0.10:
+ resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==}
+ engines: {node: '>= 0.4'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-map@2.0.3:
+ resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+ engines: {node: '>= 0.4'}
+
+ is-negative-zero@2.0.3:
+ resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
+ engines: {node: '>= 0.4'}
+
+ is-number-object@1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+
+ is-plain-obj@2.1.0:
+ resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
+ engines: {node: '>=8'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-regex@1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+
+ is-set@2.0.3:
+ resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+ engines: {node: '>= 0.4'}
+
+ is-shared-array-buffer@1.0.3:
+ resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
+ engines: {node: '>= 0.4'}
+
+ is-stream@2.0.1:
+ resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
+ engines: {node: '>=8'}
+
+ is-stream@3.0.0:
+ resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ is-stream@4.0.1:
+ resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
+ engines: {node: '>=18'}
+
+ is-string@1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+
+ is-symbol@1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+
+ is-typed-array@1.1.13:
+ resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
+ engines: {node: '>= 0.4'}
+
+ is-unicode-supported@0.1.0:
+ resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
+ engines: {node: '>=10'}
+
+ is-unicode-supported@2.1.0:
+ resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
+ engines: {node: '>=18'}
+
+ is-weakmap@2.0.2:
+ resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+ engines: {node: '>= 0.4'}
+
+ is-weakref@1.0.2:
+ resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+
+ is-weakset@2.0.3:
+ resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==}
+ engines: {node: '>= 0.4'}
+
+ isarray@1.0.0:
+ resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+
+ isarray@2.0.5:
+ resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ isexe@3.1.1:
+ resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
+ engines: {node: '>=16'}
+
+ iterator.prototype@1.1.2:
+ resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==}
+
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
+ jackspeak@4.0.1:
+ resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==}
+ engines: {node: 20 || >=22}
+
+ jake@10.9.2:
+ resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ jest-diff@29.7.0:
+ resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-get-type@29.6.3:
+ resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-matcher-utils@29.7.0:
+ resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-message-util@29.7.0:
+ resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-util@29.7.0:
+ resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ jest-worker@27.5.1:
+ resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
+ engines: {node: '>= 10.13.0'}
+
+ jiti@1.21.6:
+ resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
+ hasBin: true
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+
+ jsbn@1.1.0:
+ resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
+ json-parse-even-better-errors@3.0.2:
+ resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ json5@1.0.2:
+ resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
+ hasBin: true
+
+ jsonfile@6.1.0:
+ resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+
+ jsx-ast-utils@3.3.5:
+ resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
+ engines: {node: '>=4.0'}
+
+ jszip@3.10.1:
+ resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ language-subtag-registry@0.3.23:
+ resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==}
+
+ language-tags@1.0.9:
+ resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==}
+ engines: {node: '>=0.10'}
+
+ lazystream@1.0.1:
+ resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
+ engines: {node: '>= 0.6.3'}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ lie@3.3.0:
+ resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+
+ lilconfig@2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+
+ lilconfig@3.1.2:
+ resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ lines-and-columns@2.0.4:
+ resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ lint-staged@15.2.10:
+ resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==}
+ engines: {node: '>=18.12.0'}
+ hasBin: true
+
+ listr2@8.2.4:
+ resolution: {integrity: sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==}
+ engines: {node: '>=18.0.0'}
+
+ loader-runner@4.3.0:
+ resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
+ engines: {node: '>=6.11.5'}
+
+ loader-utils@3.3.1:
+ resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==}
+ engines: {node: '>= 12.13.0'}
+
+ locate-app@2.4.43:
+ resolution: {integrity: sha512-BX6NEdECUGcDQw8aqqg02qLyF9rF8V+dAfyAnBzL2AofIlIvf4Q6EGXnzVWpWot9uBE+x/o8CjXHo7Zlegu91Q==}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ locate-path@7.2.0:
+ resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ lodash.clonedeep@4.5.0:
+ resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
+
+ lodash.flattendeep@4.4.0:
+ resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==}
+
+ lodash.isequal@4.5.0:
+ resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ lodash.pickby@4.6.0:
+ resolution: {integrity: sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==}
+
+ lodash.union@4.6.0:
+ resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==}
+
+ lodash.zip@4.2.0:
+ resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==}
+
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+ log-symbols@4.1.0:
+ resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
+ engines: {node: '>=10'}
+
+ log-update@6.1.0:
+ resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
+ engines: {node: '>=18'}
+
+ loglevel-plugin-prefix@0.8.4:
+ resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==}
+
+ loglevel@1.9.2:
+ resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==}
+ engines: {node: '>= 0.6.0'}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
+ lru-cache@7.18.3:
+ resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
+ engines: {node: '>=12'}
+
+ magic-string@0.30.11:
+ resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
+
+ magic-string@0.30.17:
+ resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
+
+ make-error@1.3.6:
+ resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
+
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mimic-fn@4.0.0:
+ resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
+ engines: {node: '>=12'}
+
+ mimic-function@5.0.1:
+ resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
+ engines: {node: '>=18'}
+
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
+ minimatch@3.0.8:
+ resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==}
+
+ minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+
+ minimatch@5.1.6:
+ resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
+ engines: {node: '>=10'}
+
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ mocha@10.7.3:
+ resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==}
+ engines: {node: '>= 14.0.0'}
+ hasBin: true
+
+ mrmime@1.0.1:
+ resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==}
+ engines: {node: '>=10'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mute-stream@1.0.0:
+ resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ mylas@2.1.13:
+ resolution: {integrity: sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg==}
+ engines: {node: '>=12.0.0'}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.7:
+ resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ neo-async@2.6.2:
+ resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+
+ netmask@2.0.2:
+ resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
+ engines: {node: '>= 0.4.0'}
+
+ node-domexception@1.0.0:
+ resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
+ engines: {node: '>=10.5.0'}
+
+ node-fetch@3.3.2:
+ resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ node-releases@2.0.18:
+ resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+
+ normalize-package-data@6.0.2:
+ resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==}
+ engines: {node: ^16.14.0 || >=18.0.0}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ normalize-range@0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+
+ npm-run-path@5.3.0:
+ resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ object-inspect@1.13.2:
+ resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
+ engines: {node: '>= 0.4'}
+
+ object-is@1.1.6:
+ resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==}
+ engines: {node: '>= 0.4'}
+
+ object-keys@1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+
+ object.assign@4.1.5:
+ resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
+ engines: {node: '>= 0.4'}
+
+ object.entries@1.1.8:
+ resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==}
+ engines: {node: '>= 0.4'}
+
+ object.fromentries@2.0.8:
+ resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
+ engines: {node: '>= 0.4'}
+
+ object.groupby@1.0.3:
+ resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
+ engines: {node: '>= 0.4'}
+
+ object.values@1.2.0:
+ resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==}
+ engines: {node: '>= 0.4'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ onetime@6.0.0:
+ resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
+ engines: {node: '>=12'}
+
+ onetime@7.0.0:
+ resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
+ engines: {node: '>=18'}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ os-tmpdir@1.0.2:
+ resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
+ engines: {node: '>=0.10.0'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-limit@4.0.0:
+ resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ p-locate@6.0.0:
+ resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ pac-proxy-agent@7.0.2:
+ resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==}
+ engines: {node: '>= 14'}
+
+ pac-resolver@7.0.1:
+ resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==}
+ engines: {node: '>= 14'}
+
+ package-json-from-dist@1.0.0:
+ resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
+
+ pako@1.0.11:
+ resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ parse-json@7.1.1:
+ resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==}
+ engines: {node: '>=16'}
+
+ parse-ms@4.0.0:
+ resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
+ engines: {node: '>=18'}
+
+ parse5-htmlparser2-tree-adapter@7.0.0:
+ resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
+
+ parse5-parser-stream@7.1.2:
+ resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==}
+
+ parse5@7.1.2:
+ resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-exists@5.0.0:
+ resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-key@4.0.0:
+ resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+ engines: {node: '>=12'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+
+ pathe@1.1.2:
+ resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+
+ pend@1.2.0:
+ resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
+
+ picocolors@1.1.0:
+ resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ pidtree@0.6.0:
+ resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+
+ plimit-lit@1.6.1:
+ resolution: {integrity: sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==}
+ engines: {node: '>=12'}
+
+ possible-typed-array-names@1.0.0:
+ resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
+ engines: {node: '>= 0.4'}
+
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.0.1:
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@4.0.2:
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+
+ postcss-load-config@6.0.1:
+ resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ jiti: '>=1.21.0'
+ postcss: '>=8.0.9'
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+ postcss:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.47:
+ resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ postcss@8.4.49:
+ resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prettier-linter-helpers@1.0.0:
+ resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+ engines: {node: '>=6.0.0'}
+
+ prettier@3.3.3:
+ resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ pretty-format@29.7.0:
+ resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+
+ pretty-ms@9.1.0:
+ resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==}
+ engines: {node: '>=18'}
+
+ process-nextick-args@2.0.1:
+ resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+
+ process@0.11.10:
+ resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
+ engines: {node: '>= 0.6.0'}
+
+ progress@2.0.3:
+ resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
+ engines: {node: '>=0.4.0'}
+
+ prop-types@15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+
+ proxy-agent@6.4.0:
+ resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==}
+ engines: {node: '>= 14'}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
+ pump@3.0.2:
+ resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ query-selector-shadow-dom@1.0.1:
+ resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==}
+
+ queue-lit@1.5.2:
+ resolution: {integrity: sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw==}
+ engines: {node: '>=12'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ queue-tick@1.0.1:
+ resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
+
+ randombytes@2.1.0:
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
+
+ react-dom@18.3.1:
+ resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
+ peerDependencies:
+ react: ^18.3.1
+
+ react-is@16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+
+ react-is@18.3.1:
+ resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
+
+ react@18.3.1:
+ resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
+ engines: {node: '>=0.10.0'}
+
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
+ read-pkg-up@10.1.0:
+ resolution: {integrity: sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==}
+ engines: {node: '>=16'}
+
+ read-pkg@8.1.0:
+ resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==}
+ engines: {node: '>=16'}
+
+ readable-stream@2.3.8:
+ resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+
+ readable-stream@4.5.2:
+ resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ readdir-glob@1.1.3:
+ resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ readdirp@4.0.2:
+ resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
+ engines: {node: '>= 14.16.0'}
+
+ recursive-readdir@2.2.3:
+ resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==}
+ engines: {node: '>=6.0.0'}
+
+ reflect.getprototypeof@1.0.6:
+ resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==}
+ engines: {node: '>= 0.4'}
+
+ regexp.prototype.flags@1.5.2:
+ resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
+ engines: {node: '>= 0.4'}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
+ resolve@2.0.0-next.5:
+ resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==}
+ hasBin: true
+
+ resq@1.11.0:
+ resolution: {integrity: sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==}
+
+ restore-cursor@5.1.0:
+ resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
+ engines: {node: '>=18'}
+
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rgb2hex@0.2.5:
+ resolution: {integrity: sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==}
+
+ rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
+
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ rollup@4.24.0:
+ resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-async@3.0.0:
+ resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==}
+ engines: {node: '>=0.12.0'}
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ run-script-os@1.1.6:
+ resolution: {integrity: sha512-ql6P2LzhBTTDfzKts+Qo4H94VUKpxKDFz6QxxwaUZN0mwvi7L3lpOI7BqPCq7lgDh3XLl0dpeXwfcVIitlrYrw==}
+ hasBin: true
+
+ rxjs@7.8.1:
+ resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
+
+ safaridriver@0.1.2:
+ resolution: {integrity: sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==}
+
+ safaridriver@1.0.0:
+ resolution: {integrity: sha512-J92IFbskyo7OYB3Dt4aTdyhag1GlInrfbPCmMteb7aBK7PwlnGz1HI0+oyNN97j7pV9DqUAVoVgkNRMrfY47mQ==}
+ engines: {node: '>=18.0.0'}
+
+ safe-array-concat@1.1.2:
+ resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
+ engines: {node: '>=0.4'}
+
+ safe-buffer@5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ safe-regex-test@1.0.3:
+ resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
+ engines: {node: '>= 0.4'}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ sass@1.79.4:
+ resolution: {integrity: sha512-K0QDSNPXgyqO4GZq2HO5Q70TLxTH6cIT59RdoCHMivrC8rqzaTw5ab9prjz9KUN1El4FLXrBXJhik61JR4HcGg==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ scheduler@0.23.2:
+ resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
+
+ schema-utils@3.3.0:
+ resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
+ engines: {node: '>= 10.13.0'}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ serialize-error@11.0.3:
+ resolution: {integrity: sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==}
+ engines: {node: '>=14.16'}
+
+ serialize-javascript@6.0.2:
+ resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
+
+ set-function-length@1.2.2:
+ resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+ engines: {node: '>= 0.4'}
+
+ set-function-name@2.0.2:
+ resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+ engines: {node: '>= 0.4'}
+
+ setimmediate@1.0.5:
+ resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ shell-quote@1.8.1:
+ resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
+
+ side-channel@1.0.6:
+ resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
+ engines: {node: '>= 0.4'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+
+ slice-ansi@5.0.0:
+ resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
+ engines: {node: '>=12'}
+
+ slice-ansi@7.1.0:
+ resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
+ engines: {node: '>=18'}
+
+ smart-buffer@4.2.0:
+ resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
+ engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
+
+ socks-proxy-agent@8.0.4:
+ resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==}
+ engines: {node: '>= 14'}
+
+ socks@2.8.3:
+ resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==}
+ engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.7.4:
+ resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
+ engines: {node: '>= 8'}
+
+ spacetrim@0.11.39:
+ resolution: {integrity: sha512-S/baW29azJ7py5ausQRE2S6uEDQnlxgMHOEEq4V770ooBDD1/9kZnxRcco/tjZYuDuqYXblCk/r3N13ZmvHZ2g==}
+
+ spdx-correct@3.2.0:
+ resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
+
+ spdx-exceptions@2.5.0:
+ resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
+
+ spdx-expression-parse@3.0.1:
+ resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
+
+ spdx-license-ids@3.0.20:
+ resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==}
+
+ split2@4.2.0:
+ resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
+ engines: {node: '>= 10.x'}
+
+ sprintf-js@1.1.3:
+ resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
+
+ stack-utils@2.0.6:
+ resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
+ engines: {node: '>=10'}
+
+ stop-iteration-iterator@1.0.0:
+ resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
+ engines: {node: '>= 0.4'}
+
+ stream-buffers@3.0.3:
+ resolution: {integrity: sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==}
+ engines: {node: '>= 0.10.0'}
+
+ streamx@2.20.1:
+ resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==}
+
+ string-argv@0.3.2:
+ resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
+ engines: {node: '>=0.6.19'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ string-width@7.2.0:
+ resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
+ engines: {node: '>=18'}
+
+ string.prototype.includes@2.0.0:
+ resolution: {integrity: sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==}
+
+ string.prototype.matchall@4.0.11:
+ resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.repeat@1.0.0:
+ resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==}
+
+ string.prototype.trim@1.2.9:
+ resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
+ engines: {node: '>= 0.4'}
+
+ string.prototype.trimend@1.0.8:
+ resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==}
+
+ string.prototype.trimstart@1.0.8:
+ resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+ engines: {node: '>= 0.4'}
+
+ string_decoder@1.1.1:
+ resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+
+ string_decoder@1.3.0:
+ resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-final-newline@3.0.0:
+ resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
+ engines: {node: '>=12'}
+
+ strip-final-newline@4.0.0:
+ resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
+ engines: {node: '>=18'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ strnum@1.0.5:
+ resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
+
+ sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ supports-color@5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ synckit@0.9.1:
+ resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+
+ tailwind-merge@2.5.2:
+ resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==}
+
+ tailwindcss@3.4.14:
+ resolution: {integrity: sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ tapable@2.2.1:
+ resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+ engines: {node: '>=6'}
+
+ tar-fs@3.0.6:
+ resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==}
+
+ tar-stream@3.1.7:
+ resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
+
+ terser-webpack-plugin@5.3.10:
+ resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==}
+ engines: {node: '>= 10.13.0'}
+ peerDependencies:
+ '@swc/core': '*'
+ esbuild: '*'
+ uglify-js: '*'
+ webpack: ^5.1.0
+ peerDependenciesMeta:
+ '@swc/core':
+ optional: true
+ esbuild:
+ optional: true
+ uglify-js:
+ optional: true
+
+ terser@5.34.1:
+ resolution: {integrity: sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ text-decoder@1.2.0:
+ resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==}
+
+ text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ through@2.3.8:
+ resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
+
+ tinyrainbow@1.2.0:
+ resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==}
+ engines: {node: '>=14.0.0'}
+
+ tmp@0.0.33:
+ resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
+ engines: {node: '>=0.6.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
+ ts-api-utils@1.3.0:
+ resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ ts-loader@9.5.1:
+ resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ typescript: '*'
+ webpack: ^5.0.0
+
+ ts-node@10.9.2:
+ resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
+ hasBin: true
+ 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
+
+ tsc-alias@1.8.10:
+ resolution: {integrity: sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==}
+ hasBin: true
+
+ tsconfig-paths@3.15.0:
+ resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
+
+ tslib@2.7.0:
+ resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
+
+ tsx@4.19.2:
+ resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ turbo-darwin-64@2.3.3:
+ resolution: {integrity: sha512-bxX82xe6du/3rPmm4aCC5RdEilIN99VUld4HkFQuw+mvFg6darNBuQxyWSHZTtc25XgYjQrjsV05888w1grpaA==}
+ cpu: [x64]
+ os: [darwin]
+
+ turbo-darwin-arm64@2.3.3:
+ resolution: {integrity: sha512-DYbQwa3NsAuWkCUYVzfOUBbSUBVQzH5HWUFy2Kgi3fGjIWVZOFk86ss+xsWu//rlEAfYwEmopigsPYSmW4X15A==}
+ cpu: [arm64]
+ os: [darwin]
+
+ turbo-linux-64@2.3.3:
+ resolution: {integrity: sha512-eHj9OIB0dFaP6BxB88jSuaCLsOQSYWBgmhy2ErCu6D2GG6xW3b6e2UWHl/1Ho9FsTg4uVgo4DB9wGsKa5erjUA==}
+ cpu: [x64]
+ os: [linux]
+
+ turbo-linux-arm64@2.3.3:
+ resolution: {integrity: sha512-NmDE/NjZoDj1UWBhMtOPmqFLEBKhzGS61KObfrDEbXvU3lekwHeoPvAMfcovzswzch+kN2DrtbNIlz+/rp8OCg==}
+ cpu: [arm64]
+ os: [linux]
+
+ turbo-windows-64@2.3.3:
+ resolution: {integrity: sha512-O2+BS4QqjK3dOERscXqv7N2GXNcqHr9hXumkMxDj/oGx9oCatIwnnwx34UmzodloSnJpgSqjl8iRWiY65SmYoQ==}
+ cpu: [x64]
+ os: [win32]
+
+ turbo-windows-arm64@2.3.3:
+ resolution: {integrity: sha512-dW4ZK1r6XLPNYLIKjC4o87HxYidtRRcBeo/hZ9Wng2XM/MqqYkAyzJXJGgRMsc0MMEN9z4+ZIfnSNBrA0b08ag==}
+ cpu: [arm64]
+ os: [win32]
+
+ turbo@2.3.3:
+ resolution: {integrity: sha512-DUHWQAcC8BTiUZDRzAYGvpSpGLiaOQPfYXlCieQbwUvmml/LRGIe3raKdrOPOoiX0DYlzxs2nH6BoWJoZrj8hA==}
+ hasBin: true
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+
+ type-fest@0.21.3:
+ resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
+ engines: {node: '>=10'}
+
+ type-fest@2.13.0:
+ resolution: {integrity: sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==}
+ engines: {node: '>=12.20'}
+
+ type-fest@2.19.0:
+ resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
+ engines: {node: '>=12.20'}
+
+ type-fest@3.13.1:
+ resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
+ engines: {node: '>=14.16'}
+
+ type-fest@4.26.1:
+ resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==}
+ engines: {node: '>=16'}
+
+ typed-array-buffer@1.0.2:
+ resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-byte-length@1.0.1:
+ resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-byte-offset@1.0.2:
+ resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==}
+ engines: {node: '>= 0.4'}
+
+ typed-array-length@1.0.6:
+ resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
+ engines: {node: '>= 0.4'}
+
+ typescript@5.5.4:
+ resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ unbox-primitive@1.0.2:
+ resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+
+ unbzip2-stream@1.4.3:
+ resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==}
+
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
+ undici@6.21.0:
+ resolution: {integrity: sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==}
+ engines: {node: '>=18.17'}
+
+ universalify@2.0.1:
+ resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
+ engines: {node: '>= 10.0.0'}
+
+ update-browserslist-db@1.1.1:
+ resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ urlpattern-polyfill@10.0.0:
+ resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==}
+
+ userhome@1.0.0:
+ resolution: {integrity: sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==}
+ engines: {node: '>= 0.8.0'}
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ v8-compile-cache-lib@3.0.1:
+ resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+
+ validate-npm-package-license@3.0.4:
+ resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+
+ vite@6.0.5:
+ resolution: {integrity: sha512-akD5IAH/ID5imgue2DYhzsEwCi0/4VKY31uhMLEYJwPP4TiUp8pL5PIK+Wo7H8qT8JY9i+pVfPydcFPYD1EL7g==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ wait-port@1.1.0:
+ resolution: {integrity: sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ watchpack@2.4.2:
+ resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==}
+ engines: {node: '>=10.13.0'}
+
+ wcwidth@1.0.1:
+ resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
+
+ web-streams-polyfill@3.3.3:
+ resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
+ engines: {node: '>= 8'}
+
+ webdriver@9.1.2:
+ resolution: {integrity: sha512-NjeYVTCSMwQrd+EDpSSB8YnSNzYeEPU2IoJhvjaXUwTEhoaIvz6x6fM4UqCbm/ph8lZ1uWux43fqIcfDzFQl5Q==}
+ engines: {node: '>=18.20.0'}
+
+ webdriver@9.4.4:
+ resolution: {integrity: sha512-F/QxX3TNfkBWzYC0Ywz0oRRUtvUEFUM59pob19gs+lZ2seXKKCJ8vVLzIWcT9XBU8dFAWN6Mzqi5FypHWeBgfw==}
+ engines: {node: '>=18.20.0'}
+
+ webdriverio@9.1.2:
+ resolution: {integrity: sha512-Yk/OmxUmse6YVBMr+iM5zH3LKiy07cJQsq19qL2Zj29+2I3b8kK8uGxx8+DhqYF/A/MVwHUFxACzQDYsdW6pjw==}
+ engines: {node: '>=18.20.0'}
+ peerDependencies:
+ puppeteer-core: ^22.3.0
+ peerDependenciesMeta:
+ puppeteer-core:
+ optional: true
+
+ webdriverio@9.4.5:
+ resolution: {integrity: sha512-tc22NSwKbXNROhafzktoQnhfkx0bhvh9a+XVaVu3mLhaiOmymIGDcS2NyRoOn3Sq4JxWJuOUwTO6f6jNkFJ5bQ==}
+ engines: {node: '>=18.20.0'}
+ peerDependencies:
+ puppeteer-core: ^22.3.0
+ peerDependenciesMeta:
+ puppeteer-core:
+ optional: true
+
+ webextension-polyfill@0.12.0:
+ resolution: {integrity: sha512-97TBmpoWJEE+3nFBQ4VocyCdLKfw54rFaJ6EVQYLBCXqCIpLSZkwGgASpv4oPt9gdKCJ80RJlcmNzNn008Ag6Q==}
+
+ webpack-sources@3.2.3:
+ resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
+ engines: {node: '>=10.13.0'}
+
+ webpack@5.94.0:
+ resolution: {integrity: sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ peerDependencies:
+ webpack-cli: '*'
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+
+ whatwg-encoding@3.1.1:
+ resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
+ engines: {node: '>=18'}
+
+ whatwg-mimetype@4.0.0:
+ resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
+ engines: {node: '>=18'}
+
+ which-boxed-primitive@1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+
+ which-builtin-type@1.1.4:
+ resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==}
+ engines: {node: '>= 0.4'}
+
+ which-collection@1.0.2:
+ resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+ engines: {node: '>= 0.4'}
+
+ which-typed-array@1.1.15:
+ resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
+ engines: {node: '>= 0.4'}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ which@4.0.0:
+ resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
+ engines: {node: ^16.13.0 || >=18.0.0}
+ hasBin: true
+
+ which@5.0.0:
+ resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==}
+ engines: {node: ^18.17.0 || >=20.5.0}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ workerpool@6.5.1:
+ resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==}
+
+ wrap-ansi@6.2.0:
+ resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
+ engines: {node: '>=8'}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ wrap-ansi@9.0.0:
+ resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
+ engines: {node: '>=18'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ ws@8.18.0:
+ resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
+ 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
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yaml@2.5.1:
+ resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ yargs-parser@20.2.9:
+ resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
+ engines: {node: '>=10'}
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs-unparser@2.0.0:
+ resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==}
+ engines: {node: '>=10'}
+
+ yargs@16.2.0:
+ resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
+ engines: {node: '>=10'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
+ yauzl@2.10.0:
+ resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
+
+ yn@3.1.1:
+ resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
+ engines: {node: '>=6'}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+ yocto-queue@1.1.1:
+ resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==}
+ engines: {node: '>=12.20'}
+
+ yoctocolors-cjs@2.1.2:
+ resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
+ engines: {node: '>=18'}
+
+ yoctocolors@2.1.1:
+ resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==}
+ engines: {node: '>=18'}
+
+ zip-stream@6.0.1:
+ resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==}
+ engines: {node: '>= 14'}
+
+snapshots:
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@babel/code-frame@7.24.7':
+ dependencies:
+ '@babel/highlight': 7.24.7
+ picocolors: 1.1.0
+
+ '@babel/helper-validator-identifier@7.24.7': {}
+
+ '@babel/highlight@7.24.7':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.24.7
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ picocolors: 1.1.0
+
+ '@cspotcode/source-map-support@0.8.1':
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.9
+
+ '@esbuild/aix-ppc64@0.23.1':
+ optional: true
+
+ '@esbuild/aix-ppc64@0.24.0':
+ optional: true
+
+ '@esbuild/android-arm64@0.23.1':
+ optional: true
+
+ '@esbuild/android-arm64@0.24.0':
+ optional: true
+
+ '@esbuild/android-arm@0.23.1':
+ optional: true
+
+ '@esbuild/android-arm@0.24.0':
+ optional: true
+
+ '@esbuild/android-x64@0.23.1':
+ optional: true
+
+ '@esbuild/android-x64@0.24.0':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.23.1':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.24.0':
+ optional: true
+
+ '@esbuild/darwin-x64@0.23.1':
+ optional: true
+
+ '@esbuild/darwin-x64@0.24.0':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.23.1':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.24.0':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.23.1':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.24.0':
+ optional: true
+
+ '@esbuild/linux-arm64@0.23.1':
+ optional: true
+
+ '@esbuild/linux-arm64@0.24.0':
+ optional: true
+
+ '@esbuild/linux-arm@0.23.1':
+ optional: true
+
+ '@esbuild/linux-arm@0.24.0':
+ optional: true
+
+ '@esbuild/linux-ia32@0.23.1':
+ optional: true
+
+ '@esbuild/linux-ia32@0.24.0':
+ optional: true
+
+ '@esbuild/linux-loong64@0.23.1':
+ optional: true
+
+ '@esbuild/linux-loong64@0.24.0':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.23.1':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.24.0':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.23.1':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.24.0':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.23.1':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.24.0':
+ optional: true
+
+ '@esbuild/linux-s390x@0.23.1':
+ optional: true
+
+ '@esbuild/linux-s390x@0.24.0':
+ optional: true
+
+ '@esbuild/linux-x64@0.23.1':
+ optional: true
+
+ '@esbuild/linux-x64@0.24.0':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.23.1':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.24.0':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.23.1':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.24.0':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.23.1':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.24.0':
+ optional: true
+
+ '@esbuild/sunos-x64@0.23.1':
+ optional: true
+
+ '@esbuild/sunos-x64@0.24.0':
+ optional: true
+
+ '@esbuild/win32-arm64@0.23.1':
+ optional: true
+
+ '@esbuild/win32-arm64@0.24.0':
+ optional: true
+
+ '@esbuild/win32-ia32@0.23.1':
+ optional: true
+
+ '@esbuild/win32-ia32@0.24.0':
+ optional: true
+
+ '@esbuild/win32-x64@0.23.1':
+ optional: true
+
+ '@esbuild/win32-x64@0.24.0':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
+ dependencies:
+ eslint: 8.57.0
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.11.0': {}
+
+ '@eslint/eslintrc@2.1.4':
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.7(supports-color@8.1.1)
+ espree: 9.6.1
+ globals: 13.24.0
+ ignore: 5.3.2
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/js@8.57.0': {}
+
+ '@humanwhocodes/config-array@0.11.14':
+ dependencies:
+ '@humanwhocodes/object-schema': 2.0.3
+ debug: 4.3.7(supports-color@8.1.1)
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@humanwhocodes/module-importer@1.0.1': {}
+
+ '@humanwhocodes/object-schema@2.0.3': {}
+
+ '@inquirer/checkbox@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/figures': 1.0.6
+ '@inquirer/type': 2.0.0
+ ansi-escapes: 4.3.2
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/confirm@4.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+
+ '@inquirer/core@9.2.1':
+ dependencies:
+ '@inquirer/figures': 1.0.6
+ '@inquirer/type': 2.0.0
+ '@types/mute-stream': 0.0.4
+ '@types/node': 22.7.4
+ '@types/wrap-ansi': 3.0.0
+ ansi-escapes: 4.3.2
+ cli-width: 4.1.0
+ mute-stream: 1.0.0
+ signal-exit: 4.1.0
+ strip-ansi: 6.0.1
+ wrap-ansi: 6.2.0
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/editor@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+ external-editor: 3.1.0
+
+ '@inquirer/expand@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/figures@1.0.6': {}
+
+ '@inquirer/input@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+
+ '@inquirer/number@2.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+
+ '@inquirer/password@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+ ansi-escapes: 4.3.2
+
+ '@inquirer/prompts@6.0.1':
+ dependencies:
+ '@inquirer/checkbox': 3.0.1
+ '@inquirer/confirm': 4.0.1
+ '@inquirer/editor': 3.0.1
+ '@inquirer/expand': 3.0.1
+ '@inquirer/input': 3.0.1
+ '@inquirer/number': 2.0.1
+ '@inquirer/password': 3.0.1
+ '@inquirer/rawlist': 3.0.1
+ '@inquirer/search': 2.0.1
+ '@inquirer/select': 3.0.1
+
+ '@inquirer/rawlist@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/type': 2.0.0
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/search@2.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/figures': 1.0.6
+ '@inquirer/type': 2.0.0
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/select@3.0.1':
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/figures': 1.0.6
+ '@inquirer/type': 2.0.0
+ ansi-escapes: 4.3.2
+ yoctocolors-cjs: 2.1.2
+
+ '@inquirer/type@2.0.0':
+ dependencies:
+ mute-stream: 1.0.0
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@jest/expect-utils@29.7.0':
+ dependencies:
+ jest-get-type: 29.6.3
+
+ '@jest/schemas@29.6.3':
+ dependencies:
+ '@sinclair/typebox': 0.27.8
+
+ '@jest/types@29.6.3':
+ dependencies:
+ '@jest/schemas': 29.6.3
+ '@types/istanbul-lib-coverage': 2.0.6
+ '@types/istanbul-reports': 3.0.4
+ '@types/node': 22.7.4
+ '@types/yargs': 17.0.33
+ chalk: 4.1.2
+
+ '@jridgewell/gen-mapping@0.3.5':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/source-map@0.3.6':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@jridgewell/trace-mapping@0.3.9':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@laynezh/vite-plugin-lib-assets@0.6.1(vite@6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1))':
+ dependencies:
+ escape-string-regexp: 4.0.0
+ loader-utils: 3.3.1
+ mrmime: 1.0.1
+ semver: 7.6.3
+ vite: 6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1)
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
+ '@pkgr/core@0.1.1': {}
+
+ '@promptbook/utils@0.70.0-1':
+ dependencies:
+ spacetrim: 0.11.39
+
+ '@puppeteer/browsers@2.4.0':
+ dependencies:
+ debug: 4.3.7(supports-color@8.1.1)
+ extract-zip: 2.0.1
+ progress: 2.0.3
+ proxy-agent: 6.4.0
+ semver: 7.6.3
+ tar-fs: 3.0.6
+ unbzip2-stream: 1.4.3
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@rollup/plugin-sucrase@5.0.2(rollup@4.24.0)':
+ dependencies:
+ '@rollup/pluginutils': 5.1.0(rollup@4.24.0)
+ sucrase: 3.35.0
+ optionalDependencies:
+ rollup: 4.24.0
+
+ '@rollup/pluginutils@5.1.0(rollup@4.24.0)':
+ dependencies:
+ '@types/estree': 1.0.6
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ optionalDependencies:
+ rollup: 4.24.0
+
+ '@rollup/rollup-android-arm-eabi@4.24.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.24.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.24.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.24.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.24.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.24.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.24.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.24.0':
+ optional: true
+
+ '@sec-ant/readable-stream@0.4.1': {}
+
+ '@sinclair/typebox@0.27.8': {}
+
+ '@sindresorhus/merge-streams@4.0.0': {}
+
+ '@swc/core-darwin-arm64@1.9.3':
+ optional: true
+
+ '@swc/core-darwin-x64@1.9.3':
+ optional: true
+
+ '@swc/core-linux-arm-gnueabihf@1.9.3':
+ optional: true
+
+ '@swc/core-linux-arm64-gnu@1.9.3':
+ optional: true
+
+ '@swc/core-linux-arm64-musl@1.9.3':
+ optional: true
+
+ '@swc/core-linux-x64-gnu@1.9.3':
+ optional: true
+
+ '@swc/core-linux-x64-musl@1.9.3':
+ optional: true
+
+ '@swc/core-win32-arm64-msvc@1.9.3':
+ optional: true
+
+ '@swc/core-win32-ia32-msvc@1.9.3':
+ optional: true
+
+ '@swc/core-win32-x64-msvc@1.9.3':
+ optional: true
+
+ '@swc/core@1.9.3':
+ dependencies:
+ '@swc/counter': 0.1.3
+ '@swc/types': 0.1.17
+ optionalDependencies:
+ '@swc/core-darwin-arm64': 1.9.3
+ '@swc/core-darwin-x64': 1.9.3
+ '@swc/core-linux-arm-gnueabihf': 1.9.3
+ '@swc/core-linux-arm64-gnu': 1.9.3
+ '@swc/core-linux-arm64-musl': 1.9.3
+ '@swc/core-linux-x64-gnu': 1.9.3
+ '@swc/core-linux-x64-musl': 1.9.3
+ '@swc/core-win32-arm64-msvc': 1.9.3
+ '@swc/core-win32-ia32-msvc': 1.9.3
+ '@swc/core-win32-x64-msvc': 1.9.3
+
+ '@swc/counter@0.1.3': {}
+
+ '@swc/types@0.1.17':
+ dependencies:
+ '@swc/counter': 0.1.3
+
+ '@tootallnate/quickjs-emscripten@0.23.0': {}
+
+ '@tsconfig/node10@1.0.11': {}
+
+ '@tsconfig/node12@1.0.11': {}
+
+ '@tsconfig/node14@1.0.3': {}
+
+ '@tsconfig/node16@1.0.4': {}
+
+ '@types/chrome@0.0.270':
+ dependencies:
+ '@types/filesystem': 0.0.36
+ '@types/har-format': 1.2.15
+
+ '@types/estree@1.0.6': {}
+
+ '@types/filesystem@0.0.36':
+ dependencies:
+ '@types/filewriter': 0.0.33
+
+ '@types/filewriter@0.0.33': {}
+
+ '@types/har-format@1.2.15': {}
+
+ '@types/istanbul-lib-coverage@2.0.6': {}
+
+ '@types/istanbul-lib-report@3.0.3':
+ dependencies:
+ '@types/istanbul-lib-coverage': 2.0.6
+
+ '@types/istanbul-reports@3.0.4':
+ dependencies:
+ '@types/istanbul-lib-report': 3.0.3
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/json5@0.0.29': {}
+
+ '@types/mocha@10.0.7': {}
+
+ '@types/mute-stream@0.0.4':
+ dependencies:
+ '@types/node': 22.7.4
+
+ '@types/node@20.16.10':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@types/node@22.7.4':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@types/normalize-package-data@2.4.4': {}
+
+ '@types/prop-types@15.7.12': {}
+
+ '@types/react-dom@18.3.0':
+ dependencies:
+ '@types/react': 18.3.5
+
+ '@types/react@18.3.5':
+ dependencies:
+ '@types/prop-types': 15.7.12
+ csstype: 3.1.3
+
+ '@types/sinonjs__fake-timers@8.1.5': {}
+
+ '@types/stack-utils@2.0.3': {}
+
+ '@types/which@2.0.2': {}
+
+ '@types/wrap-ansi@3.0.0': {}
+
+ '@types/ws@8.5.13':
+ dependencies:
+ '@types/node': 20.16.10
+
+ '@types/yargs-parser@21.0.3': {}
+
+ '@types/yargs@17.0.33':
+ dependencies:
+ '@types/yargs-parser': 21.0.3
+
+ '@types/yauzl@2.10.3':
+ dependencies:
+ '@types/node': 22.7.4
+ optional: true
+
+ '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)':
+ dependencies:
+ '@eslint-community/regexpp': 4.11.0
+ '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ '@typescript-eslint/visitor-keys': 7.18.0
+ eslint: 8.57.0
+ graphemer: 1.4.0
+ ignore: 5.3.2
+ natural-compare: 1.4.0
+ ts-api-utils: 1.3.0(typescript@5.5.4)
+ optionalDependencies:
+ typescript: 5.5.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
+ '@typescript-eslint/visitor-keys': 7.18.0
+ debug: 4.3.7(supports-color@8.1.1)
+ eslint: 8.57.0
+ optionalDependencies:
+ typescript: 5.5.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@7.18.0':
+ dependencies:
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/visitor-keys': 7.18.0
+
+ '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)':
+ dependencies:
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
+ '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ debug: 4.3.7(supports-color@8.1.1)
+ eslint: 8.57.0
+ ts-api-utils: 1.3.0(typescript@5.5.4)
+ optionalDependencies:
+ typescript: 5.5.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@7.18.0': {}
+
+ '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)':
+ dependencies:
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/visitor-keys': 7.18.0
+ debug: 4.3.7(supports-color@8.1.1)
+ globby: 11.1.0
+ is-glob: 4.0.3
+ minimatch: 9.0.5
+ semver: 7.6.3
+ ts-api-utils: 1.3.0(typescript@5.5.4)
+ optionalDependencies:
+ typescript: 5.5.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4)
+ eslint: 8.57.0
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@typescript-eslint/visitor-keys@7.18.0':
+ dependencies:
+ '@typescript-eslint/types': 7.18.0
+ eslint-visitor-keys: 3.4.3
+
+ '@ungap/structured-clone@1.2.0': {}
+
+ '@vitejs/plugin-react-swc@3.7.2(vite@6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1))':
+ dependencies:
+ '@swc/core': 1.9.3
+ vite: 6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1)
+ transitivePeerDependencies:
+ - '@swc/helpers'
+
+ '@vitest/pretty-format@2.0.5':
+ dependencies:
+ tinyrainbow: 1.2.0
+
+ '@vitest/pretty-format@2.1.8':
+ dependencies:
+ tinyrainbow: 1.2.0
+
+ '@vitest/snapshot@2.0.5':
+ dependencies:
+ '@vitest/pretty-format': 2.0.5
+ magic-string: 0.30.11
+ pathe: 1.1.2
+
+ '@vitest/snapshot@2.1.8':
+ dependencies:
+ '@vitest/pretty-format': 2.1.8
+ magic-string: 0.30.17
+ pathe: 1.1.2
+
+ '@wdio/cli@9.4.5':
+ dependencies:
+ '@types/node': 20.16.10
+ '@vitest/snapshot': 2.1.8
+ '@wdio/config': 9.4.4
+ '@wdio/globals': 9.4.5(@wdio/logger@9.4.4)
+ '@wdio/logger': 9.4.4
+ '@wdio/protocols': 9.4.4
+ '@wdio/types': 9.4.4
+ '@wdio/utils': 9.4.4
+ async-exit-hook: 2.0.1
+ chalk: 5.3.0
+ chokidar: 4.0.1
+ dotenv: 16.4.5
+ ejs: 3.1.10
+ execa: 9.3.1
+ import-meta-resolve: 4.1.0
+ inquirer: 11.1.0
+ lodash.flattendeep: 4.4.0
+ lodash.pickby: 4.6.0
+ lodash.union: 4.6.0
+ read-pkg-up: 10.1.0
+ recursive-readdir: 2.2.3
+ tsx: 4.19.2
+ webdriverio: 9.4.5
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - bufferutil
+ - puppeteer-core
+ - supports-color
+ - utf-8-validate
+
+ '@wdio/config@9.1.2':
+ dependencies:
+ '@wdio/logger': 9.1.0
+ '@wdio/types': 9.1.2
+ '@wdio/utils': 9.1.2
+ decamelize: 6.0.0
+ deepmerge-ts: 7.1.1
+ glob: 10.4.5
+ import-meta-resolve: 4.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@wdio/config@9.4.4':
+ dependencies:
+ '@wdio/logger': 9.4.4
+ '@wdio/types': 9.4.4
+ '@wdio/utils': 9.4.4
+ deepmerge-ts: 7.1.1
+ glob: 10.4.5
+ import-meta-resolve: 4.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@wdio/globals@9.1.2(@wdio/logger@9.1.0)':
+ optionalDependencies:
+ expect-webdriverio: 5.0.2(@wdio/globals@9.1.2(@wdio/logger@9.1.0))(@wdio/logger@9.1.0)(webdriverio@9.1.2)
+ webdriverio: 9.1.2
+ transitivePeerDependencies:
+ - '@wdio/logger'
+ - bufferutil
+ - puppeteer-core
+ - supports-color
+ - utf-8-validate
+
+ '@wdio/globals@9.4.5(@wdio/logger@9.1.0)':
+ optionalDependencies:
+ expect-webdriverio: 5.0.2(@wdio/globals@9.4.5(@wdio/logger@9.1.0))(@wdio/logger@9.1.0)(webdriverio@9.4.5)
+ webdriverio: 9.4.5
+ transitivePeerDependencies:
+ - '@wdio/logger'
+ - bufferutil
+ - puppeteer-core
+ - supports-color
+ - utf-8-validate
+
+ '@wdio/globals@9.4.5(@wdio/logger@9.4.4)':
+ optionalDependencies:
+ expect-webdriverio: 5.0.2(@wdio/globals@9.4.5(@wdio/logger@9.1.0))(@wdio/logger@9.4.4)(webdriverio@9.4.5)
+ webdriverio: 9.4.5
+ transitivePeerDependencies:
+ - '@wdio/logger'
+ - bufferutil
+ - puppeteer-core
+ - supports-color
+ - utf-8-validate
+
+ '@wdio/local-runner@9.1.2':
+ dependencies:
+ '@types/node': 20.16.10
+ '@wdio/logger': 9.1.0
+ '@wdio/repl': 9.0.8
+ '@wdio/runner': 9.1.2
+ '@wdio/types': 9.1.2
+ async-exit-hook: 2.0.1
+ split2: 4.2.0
+ stream-buffers: 3.0.3
+ transitivePeerDependencies:
+ - bufferutil
+ - puppeteer-core
+ - supports-color
+ - utf-8-validate
+
+ '@wdio/logger@8.38.0':
+ dependencies:
+ chalk: 5.3.0
+ loglevel: 1.9.2
+ loglevel-plugin-prefix: 0.8.4
+ strip-ansi: 7.1.0
+
+ '@wdio/logger@9.1.0':
+ dependencies:
+ chalk: 5.3.0
+ loglevel: 1.9.2
+ loglevel-plugin-prefix: 0.8.4
+ strip-ansi: 7.1.0
+
+ '@wdio/logger@9.1.3':
+ dependencies:
+ chalk: 5.3.0
+ loglevel: 1.9.2
+ loglevel-plugin-prefix: 0.8.4
+ strip-ansi: 7.1.0
+
+ '@wdio/logger@9.4.4':
+ dependencies:
+ chalk: 5.3.0
+ loglevel: 1.9.2
+ loglevel-plugin-prefix: 0.8.4
+ strip-ansi: 7.1.0
+
+ '@wdio/mocha-framework@9.1.2':
+ dependencies:
+ '@types/mocha': 10.0.7
+ '@types/node': 20.16.10
+ '@wdio/logger': 9.1.0
+ '@wdio/types': 9.1.2
+ '@wdio/utils': 9.1.2
+ mocha: 10.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@wdio/protocols@9.0.8': {}
+
+ '@wdio/protocols@9.4.4': {}
+
+ '@wdio/repl@9.0.8':
+ dependencies:
+ '@types/node': 20.16.10
+
+ '@wdio/repl@9.4.4':
+ dependencies:
+ '@types/node': 20.16.10
+
+ '@wdio/reporter@9.2.14':
+ dependencies:
+ '@types/node': 20.16.10
+ '@wdio/logger': 9.1.3
+ '@wdio/types': 9.2.2
+ diff: 7.0.0
+ object-inspect: 1.13.2
+
+ '@wdio/runner@9.1.2':
+ dependencies:
+ '@types/node': 20.16.10
+ '@wdio/config': 9.1.2
+ '@wdio/globals': 9.1.2(@wdio/logger@9.1.0)
+ '@wdio/logger': 9.1.0
+ '@wdio/types': 9.1.2
+ '@wdio/utils': 9.1.2
+ deepmerge-ts: 7.1.1
+ expect-webdriverio: 5.0.2(@wdio/globals@9.1.2(@wdio/logger@9.1.0))(@wdio/logger@9.1.0)(webdriverio@9.1.2)
+ gaze: 1.1.3
+ webdriver: 9.1.2
+ webdriverio: 9.1.2
+ transitivePeerDependencies:
+ - bufferutil
+ - puppeteer-core
+ - supports-color
+ - utf-8-validate
+
+ '@wdio/spec-reporter@9.2.14':
+ dependencies:
+ '@wdio/reporter': 9.2.14
+ '@wdio/types': 9.2.2
+ chalk: 5.3.0
+ easy-table: 1.2.0
+ pretty-ms: 9.1.0
+
+ '@wdio/types@9.1.2':
+ dependencies:
+ '@types/node': 20.16.10
+
+ '@wdio/types@9.2.2':
+ dependencies:
+ '@types/node': 20.16.10
+
+ '@wdio/types@9.4.4':
+ dependencies:
+ '@types/node': 20.16.10
+
+ '@wdio/utils@9.1.2':
+ dependencies:
+ '@puppeteer/browsers': 2.4.0
+ '@wdio/logger': 9.1.0
+ '@wdio/types': 9.1.2
+ decamelize: 6.0.0
+ deepmerge-ts: 7.1.1
+ edgedriver: 5.6.1
+ geckodriver: 4.5.0
+ get-port: 7.1.0
+ import-meta-resolve: 4.1.0
+ locate-app: 2.4.43
+ safaridriver: 0.1.2
+ split2: 4.2.0
+ wait-port: 1.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@wdio/utils@9.4.4':
+ dependencies:
+ '@puppeteer/browsers': 2.4.0
+ '@wdio/logger': 9.4.4
+ '@wdio/types': 9.4.4
+ decamelize: 6.0.0
+ deepmerge-ts: 7.1.1
+ edgedriver: 6.1.1
+ geckodriver: 5.0.0
+ get-port: 7.1.0
+ import-meta-resolve: 4.1.0
+ locate-app: 2.4.43
+ safaridriver: 1.0.0
+ split2: 4.2.0
+ wait-port: 1.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@webassemblyjs/ast@1.12.1':
+ dependencies:
+ '@webassemblyjs/helper-numbers': 1.11.6
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+
+ '@webassemblyjs/floating-point-hex-parser@1.11.6': {}
+
+ '@webassemblyjs/helper-api-error@1.11.6': {}
+
+ '@webassemblyjs/helper-buffer@1.12.1': {}
+
+ '@webassemblyjs/helper-numbers@1.11.6':
+ dependencies:
+ '@webassemblyjs/floating-point-hex-parser': 1.11.6
+ '@webassemblyjs/helper-api-error': 1.11.6
+ '@xtuc/long': 4.2.2
+
+ '@webassemblyjs/helper-wasm-bytecode@1.11.6': {}
+
+ '@webassemblyjs/helper-wasm-section@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/wasm-gen': 1.12.1
+
+ '@webassemblyjs/ieee754@1.11.6':
+ dependencies:
+ '@xtuc/ieee754': 1.2.0
+
+ '@webassemblyjs/leb128@1.11.6':
+ dependencies:
+ '@xtuc/long': 4.2.2
+
+ '@webassemblyjs/utf8@1.11.6': {}
+
+ '@webassemblyjs/wasm-edit@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/helper-wasm-section': 1.12.1
+ '@webassemblyjs/wasm-gen': 1.12.1
+ '@webassemblyjs/wasm-opt': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+ '@webassemblyjs/wast-printer': 1.12.1
+
+ '@webassemblyjs/wasm-gen@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/ieee754': 1.11.6
+ '@webassemblyjs/leb128': 1.11.6
+ '@webassemblyjs/utf8': 1.11.6
+
+ '@webassemblyjs/wasm-opt@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/wasm-gen': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+
+ '@webassemblyjs/wasm-parser@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-api-error': 1.11.6
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/ieee754': 1.11.6
+ '@webassemblyjs/leb128': 1.11.6
+ '@webassemblyjs/utf8': 1.11.6
+
+ '@webassemblyjs/wast-printer@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@xtuc/long': 4.2.2
+
+ '@xtuc/ieee754@1.2.0': {}
+
+ '@xtuc/long@4.2.2': {}
+
+ '@zip.js/zip.js@2.7.52': {}
+
+ '@zip.js/zip.js@2.7.54': {}
+
+ abort-controller@3.0.0:
+ dependencies:
+ event-target-shim: 5.0.1
+
+ acorn-import-attributes@1.9.5(acorn@8.12.1):
+ dependencies:
+ acorn: 8.12.1
+
+ acorn-jsx@5.3.2(acorn@8.12.1):
+ dependencies:
+ acorn: 8.12.1
+
+ acorn-walk@8.3.4:
+ dependencies:
+ acorn: 8.12.1
+
+ acorn@8.12.1: {}
+
+ agent-base@7.1.1:
+ dependencies:
+ debug: 4.3.7(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ ajv-keywords@3.5.2(ajv@6.12.6):
+ dependencies:
+ ajv: 6.12.6
+
+ ajv@6.12.6:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ansi-colors@4.1.3: {}
+
+ ansi-escapes@4.3.2:
+ dependencies:
+ type-fest: 0.21.3
+
+ ansi-escapes@7.0.0:
+ dependencies:
+ environment: 1.1.0
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.1.0: {}
+
+ ansi-styles@3.2.1:
+ dependencies:
+ color-convert: 1.9.3
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@5.2.0: {}
+
+ ansi-styles@6.2.1: {}
+
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ archiver-utils@5.0.2:
+ dependencies:
+ glob: 10.4.5
+ graceful-fs: 4.2.11
+ is-stream: 2.0.1
+ lazystream: 1.0.1
+ lodash: 4.17.21
+ normalize-path: 3.0.0
+ readable-stream: 4.5.2
+
+ archiver@7.0.1:
+ dependencies:
+ archiver-utils: 5.0.2
+ async: 3.2.6
+ buffer-crc32: 1.0.0
+ readable-stream: 4.5.2
+ readdir-glob: 1.1.3
+ tar-stream: 3.1.7
+ zip-stream: 6.0.1
+
+ arg@4.1.3: {}
+
+ arg@5.0.2: {}
+
+ argparse@2.0.1: {}
+
+ aria-query@5.1.3:
+ dependencies:
+ deep-equal: 2.2.3
+
+ aria-query@5.3.2: {}
+
+ array-buffer-byte-length@1.0.1:
+ dependencies:
+ call-bind: 1.0.7
+ is-array-buffer: 3.0.4
+
+ array-includes@3.1.8:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+ get-intrinsic: 1.2.4
+ is-string: 1.0.7
+
+ array-union@2.1.0: {}
+
+ array.prototype.findlast@1.2.5:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-shim-unscopables: 1.0.2
+
+ array.prototype.findlastindex@1.2.5:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-shim-unscopables: 1.0.2
+
+ array.prototype.flat@1.3.2:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-shim-unscopables: 1.0.2
+
+ array.prototype.flatmap@1.3.2:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-shim-unscopables: 1.0.2
+
+ array.prototype.tosorted@1.1.4:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-shim-unscopables: 1.0.2
+
+ arraybuffer.prototype.slice@1.0.3:
+ dependencies:
+ array-buffer-byte-length: 1.0.1
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ is-array-buffer: 3.0.4
+ is-shared-array-buffer: 1.0.3
+
+ ast-types-flow@0.0.8: {}
+
+ ast-types@0.13.4:
+ dependencies:
+ tslib: 2.7.0
+
+ async-exit-hook@2.0.1: {}
+
+ async@3.2.6: {}
+
+ autoprefixer@10.4.20(postcss@8.4.47):
+ dependencies:
+ browserslist: 4.24.0
+ caniuse-lite: 1.0.30001667
+ fraction.js: 4.3.7
+ normalize-range: 0.1.2
+ picocolors: 1.1.0
+ postcss: 8.4.47
+ postcss-value-parser: 4.2.0
+
+ available-typed-arrays@1.0.7:
+ dependencies:
+ possible-typed-array-names: 1.0.0
+
+ axe-core@4.10.0: {}
+
+ axobject-query@3.1.1:
+ dependencies:
+ deep-equal: 2.2.3
+
+ b4a@1.6.7: {}
+
+ balanced-match@1.0.2: {}
+
+ bare-events@2.5.0:
+ optional: true
+
+ bare-fs@2.3.5:
+ dependencies:
+ bare-events: 2.5.0
+ bare-path: 2.1.3
+ bare-stream: 2.3.0
+ optional: true
+
+ bare-os@2.4.4:
+ optional: true
+
+ bare-path@2.1.3:
+ dependencies:
+ bare-os: 2.4.4
+ optional: true
+
+ bare-stream@2.3.0:
+ dependencies:
+ b4a: 1.6.7
+ streamx: 2.20.1
+ optional: true
+
+ base64-js@1.5.1: {}
+
+ basic-ftp@5.0.5: {}
+
+ binary-extensions@2.3.0: {}
+
+ boolbase@1.0.0: {}
+
+ brace-expansion@1.1.11:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browser-stdout@1.3.1: {}
+
+ browserslist@4.24.0:
+ dependencies:
+ caniuse-lite: 1.0.30001667
+ electron-to-chromium: 1.5.32
+ node-releases: 2.0.18
+ update-browserslist-db: 1.1.1(browserslist@4.24.0)
+
+ buffer-crc32@0.2.13: {}
+
+ buffer-crc32@1.0.0: {}
+
+ buffer-from@1.1.2: {}
+
+ buffer@5.7.1:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
+ buffer@6.0.3:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
+ call-bind@1.0.7:
+ 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.2
+
+ callsites@3.1.0: {}
+
+ camelcase-css@2.0.1: {}
+
+ camelcase@6.3.0: {}
+
+ caniuse-lite@1.0.30001667: {}
+
+ chalk@2.4.2:
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chalk@5.3.0: {}
+
+ chardet@0.7.0: {}
+
+ cheerio-select@2.1.0:
+ dependencies:
+ boolbase: 1.0.0
+ css-select: 5.1.0
+ css-what: 6.1.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.1.0
+
+ cheerio@1.0.0:
+ dependencies:
+ cheerio-select: 2.1.0
+ dom-serializer: 2.0.0
+ domhandler: 5.0.3
+ domutils: 3.1.0
+ encoding-sniffer: 0.2.0
+ htmlparser2: 9.1.0
+ parse5: 7.1.2
+ parse5-htmlparser2-tree-adapter: 7.0.0
+ parse5-parser-stream: 7.1.2
+ undici: 6.21.0
+ whatwg-mimetype: 4.0.0
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ chokidar@4.0.1:
+ dependencies:
+ readdirp: 4.0.2
+
+ chrome-trace-event@1.0.4: {}
+
+ ci-info@3.9.0: {}
+
+ cli-cursor@5.0.0:
+ dependencies:
+ restore-cursor: 5.1.0
+
+ cli-truncate@4.0.0:
+ dependencies:
+ slice-ansi: 5.0.0
+ string-width: 7.2.0
+
+ cli-width@4.1.0: {}
+
+ cliui@7.0.4:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ clone@1.0.4:
+ optional: true
+
+ clsx@2.1.1: {}
+
+ color-convert@1.9.3:
+ dependencies:
+ color-name: 1.1.3
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.3: {}
+
+ color-name@1.1.4: {}
+
+ colorette@2.0.20: {}
+
+ commander@12.1.0: {}
+
+ commander@2.20.3: {}
+
+ commander@4.1.1: {}
+
+ commander@9.5.0: {}
+
+ compress-commons@6.0.2:
+ dependencies:
+ crc-32: 1.2.2
+ crc32-stream: 6.0.0
+ is-stream: 2.0.1
+ normalize-path: 3.0.0
+ readable-stream: 4.5.2
+
+ concat-map@0.0.1: {}
+
+ concurrently@9.0.1:
+ dependencies:
+ chalk: 4.1.2
+ lodash: 4.17.21
+ rxjs: 7.8.1
+ shell-quote: 1.8.1
+ supports-color: 8.1.1
+ tree-kill: 1.2.2
+ yargs: 17.7.2
+
+ confusing-browser-globals@1.0.11: {}
+
+ core-util-is@1.0.3: {}
+
+ crc-32@1.2.2: {}
+
+ crc32-stream@6.0.0:
+ dependencies:
+ crc-32: 1.2.2
+ readable-stream: 4.5.2
+
+ create-require@1.1.1: {}
+
+ cross-env@7.0.3:
+ dependencies:
+ cross-spawn: 7.0.3
+
+ cross-spawn@7.0.3:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ css-select@5.1.0:
+ dependencies:
+ boolbase: 1.0.0
+ css-what: 6.1.0
+ domhandler: 5.0.3
+ domutils: 3.1.0
+ nth-check: 2.1.1
+
+ css-shorthand-properties@1.1.2: {}
+
+ css-value@0.0.1: {}
+
+ css-what@6.1.0: {}
+
+ cssesc@3.0.0: {}
+
+ csstype@3.1.3: {}
+
+ damerau-levenshtein@1.0.8: {}
+
+ data-uri-to-buffer@4.0.1: {}
+
+ data-uri-to-buffer@6.0.2: {}
+
+ data-view-buffer@1.0.1:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-data-view: 1.0.1
+
+ data-view-byte-length@1.0.1:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-data-view: 1.0.1
+
+ data-view-byte-offset@1.0.0:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-data-view: 1.0.1
+
+ debug@3.2.7:
+ dependencies:
+ ms: 2.1.3
+
+ debug@4.3.7(supports-color@8.1.1):
+ dependencies:
+ ms: 2.1.3
+ optionalDependencies:
+ supports-color: 8.1.1
+
+ decamelize@4.0.0: {}
+
+ decamelize@6.0.0: {}
+
+ deep-equal@2.2.3:
+ dependencies:
+ array-buffer-byte-length: 1.0.1
+ call-bind: 1.0.7
+ es-get-iterator: 1.1.3
+ get-intrinsic: 1.2.4
+ is-arguments: 1.1.1
+ is-array-buffer: 3.0.4
+ is-date-object: 1.0.5
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.3
+ isarray: 2.0.5
+ object-is: 1.1.6
+ object-keys: 1.1.1
+ object.assign: 4.1.5
+ regexp.prototype.flags: 1.5.2
+ side-channel: 1.0.6
+ which-boxed-primitive: 1.0.2
+ which-collection: 1.0.2
+ which-typed-array: 1.1.15
+
+ deep-is@0.1.4: {}
+
+ deepmerge-ts@7.1.1: {}
+
+ deepmerge@4.3.1: {}
+
+ defaults@1.0.4:
+ dependencies:
+ clone: 1.0.4
+ optional: true
+
+ define-data-property@1.1.4:
+ dependencies:
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ gopd: 1.0.1
+
+ define-properties@1.2.1:
+ dependencies:
+ define-data-property: 1.1.4
+ has-property-descriptors: 1.0.2
+ object-keys: 1.1.1
+
+ degenerator@5.0.1:
+ dependencies:
+ ast-types: 0.13.4
+ escodegen: 2.1.0
+ esprima: 4.0.1
+
+ didyoumean@1.2.2: {}
+
+ diff-sequences@29.6.3: {}
+
+ diff@4.0.2: {}
+
+ diff@5.2.0: {}
+
+ diff@7.0.0: {}
+
+ dir-glob@3.0.1:
+ dependencies:
+ path-type: 4.0.0
+
+ dlv@1.1.3: {}
+
+ doctrine@2.1.0:
+ dependencies:
+ esutils: 2.0.3
+
+ doctrine@3.0.0:
+ dependencies:
+ esutils: 2.0.3
+
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
+ domutils@3.1.0:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
+ dotenv@16.4.5: {}
+
+ eastasianwidth@0.2.0: {}
+
+ easy-table@1.2.0:
+ dependencies:
+ ansi-regex: 5.0.1
+ optionalDependencies:
+ wcwidth: 1.0.1
+
+ edge-paths@3.0.5:
+ dependencies:
+ '@types/which': 2.0.2
+ which: 2.0.2
+
+ edgedriver@5.6.1:
+ dependencies:
+ '@wdio/logger': 8.38.0
+ '@zip.js/zip.js': 2.7.52
+ decamelize: 6.0.0
+ edge-paths: 3.0.5
+ fast-xml-parser: 4.5.0
+ node-fetch: 3.3.2
+ which: 4.0.0
+
+ edgedriver@6.1.1:
+ dependencies:
+ '@wdio/logger': 9.4.4
+ '@zip.js/zip.js': 2.7.54
+ decamelize: 6.0.0
+ edge-paths: 3.0.5
+ fast-xml-parser: 4.5.0
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.5
+ node-fetch: 3.3.2
+ which: 5.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ ejs@3.1.10:
+ dependencies:
+ jake: 10.9.2
+
+ electron-to-chromium@1.5.32: {}
+
+ emoji-regex@10.4.0: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ encoding-sniffer@0.2.0:
+ dependencies:
+ iconv-lite: 0.6.3
+ whatwg-encoding: 3.1.1
+
+ end-of-stream@1.4.4:
+ dependencies:
+ once: 1.4.0
+
+ enhanced-resolve@5.17.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.2.1
+
+ entities@4.5.0: {}
+
+ environment@1.1.0: {}
+
+ error-ex@1.3.2:
+ dependencies:
+ is-arrayish: 0.2.1
+
+ es-abstract@1.23.3:
+ dependencies:
+ array-buffer-byte-length: 1.0.1
+ arraybuffer.prototype.slice: 1.0.3
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ data-view-buffer: 1.0.1
+ data-view-byte-length: 1.0.1
+ data-view-byte-offset: 1.0.0
+ es-define-property: 1.0.0
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ es-set-tostringtag: 2.0.3
+ es-to-primitive: 1.2.1
+ function.prototype.name: 1.1.6
+ get-intrinsic: 1.2.4
+ get-symbol-description: 1.0.2
+ globalthis: 1.0.4
+ gopd: 1.0.1
+ has-property-descriptors: 1.0.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ hasown: 2.0.2
+ internal-slot: 1.0.7
+ is-array-buffer: 3.0.4
+ is-callable: 1.2.7
+ is-data-view: 1.0.1
+ is-negative-zero: 2.0.3
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.3
+ is-string: 1.0.7
+ is-typed-array: 1.1.13
+ is-weakref: 1.0.2
+ object-inspect: 1.13.2
+ object-keys: 1.1.1
+ object.assign: 4.1.5
+ regexp.prototype.flags: 1.5.2
+ safe-array-concat: 1.1.2
+ safe-regex-test: 1.0.3
+ string.prototype.trim: 1.2.9
+ string.prototype.trimend: 1.0.8
+ string.prototype.trimstart: 1.0.8
+ typed-array-buffer: 1.0.2
+ typed-array-byte-length: 1.0.1
+ typed-array-byte-offset: 1.0.2
+ typed-array-length: 1.0.6
+ unbox-primitive: 1.0.2
+ which-typed-array: 1.1.15
+
+ es-define-property@1.0.0:
+ dependencies:
+ get-intrinsic: 1.2.4
+
+ es-errors@1.3.0: {}
+
+ es-get-iterator@1.1.3:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ is-arguments: 1.1.1
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-string: 1.0.7
+ isarray: 2.0.5
+ stop-iteration-iterator: 1.0.0
+
+ es-iterator-helpers@1.0.19:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-set-tostringtag: 2.0.3
+ function-bind: 1.1.2
+ get-intrinsic: 1.2.4
+ globalthis: 1.0.4
+ has-property-descriptors: 1.0.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ internal-slot: 1.0.7
+ iterator.prototype: 1.1.2
+ safe-array-concat: 1.1.2
+
+ es-module-lexer@1.5.4: {}
+
+ es-object-atoms@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.0.3:
+ dependencies:
+ get-intrinsic: 1.2.4
+ has-tostringtag: 1.0.2
+ hasown: 2.0.2
+
+ es-shim-unscopables@1.0.2:
+ dependencies:
+ hasown: 2.0.2
+
+ es-to-primitive@1.2.1:
+ dependencies:
+ is-callable: 1.2.7
+ is-date-object: 1.0.5
+ is-symbol: 1.0.4
+
+ esbuild@0.23.1:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.23.1
+ '@esbuild/android-arm': 0.23.1
+ '@esbuild/android-arm64': 0.23.1
+ '@esbuild/android-x64': 0.23.1
+ '@esbuild/darwin-arm64': 0.23.1
+ '@esbuild/darwin-x64': 0.23.1
+ '@esbuild/freebsd-arm64': 0.23.1
+ '@esbuild/freebsd-x64': 0.23.1
+ '@esbuild/linux-arm': 0.23.1
+ '@esbuild/linux-arm64': 0.23.1
+ '@esbuild/linux-ia32': 0.23.1
+ '@esbuild/linux-loong64': 0.23.1
+ '@esbuild/linux-mips64el': 0.23.1
+ '@esbuild/linux-ppc64': 0.23.1
+ '@esbuild/linux-riscv64': 0.23.1
+ '@esbuild/linux-s390x': 0.23.1
+ '@esbuild/linux-x64': 0.23.1
+ '@esbuild/netbsd-x64': 0.23.1
+ '@esbuild/openbsd-arm64': 0.23.1
+ '@esbuild/openbsd-x64': 0.23.1
+ '@esbuild/sunos-x64': 0.23.1
+ '@esbuild/win32-arm64': 0.23.1
+ '@esbuild/win32-ia32': 0.23.1
+ '@esbuild/win32-x64': 0.23.1
+
+ esbuild@0.24.0:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.24.0
+ '@esbuild/android-arm': 0.24.0
+ '@esbuild/android-arm64': 0.24.0
+ '@esbuild/android-x64': 0.24.0
+ '@esbuild/darwin-arm64': 0.24.0
+ '@esbuild/darwin-x64': 0.24.0
+ '@esbuild/freebsd-arm64': 0.24.0
+ '@esbuild/freebsd-x64': 0.24.0
+ '@esbuild/linux-arm': 0.24.0
+ '@esbuild/linux-arm64': 0.24.0
+ '@esbuild/linux-ia32': 0.24.0
+ '@esbuild/linux-loong64': 0.24.0
+ '@esbuild/linux-mips64el': 0.24.0
+ '@esbuild/linux-ppc64': 0.24.0
+ '@esbuild/linux-riscv64': 0.24.0
+ '@esbuild/linux-s390x': 0.24.0
+ '@esbuild/linux-x64': 0.24.0
+ '@esbuild/netbsd-x64': 0.24.0
+ '@esbuild/openbsd-arm64': 0.24.0
+ '@esbuild/openbsd-x64': 0.24.0
+ '@esbuild/sunos-x64': 0.24.0
+ '@esbuild/win32-arm64': 0.24.0
+ '@esbuild/win32-ia32': 0.24.0
+ '@esbuild/win32-x64': 0.24.0
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@1.0.5: {}
+
+ escape-string-regexp@2.0.0: {}
+
+ escape-string-regexp@4.0.0: {}
+
+ escodegen@2.1.0:
+ dependencies:
+ esprima: 4.0.1
+ estraverse: 5.3.0
+ esutils: 2.0.3
+ optionalDependencies:
+ source-map: 0.6.1
+
+ eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0):
+ dependencies:
+ confusing-browser-globals: 1.0.11
+ eslint: 8.57.0
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)
+ object.assign: 4.1.5
+ object.entries: 1.1.8
+ semver: 6.3.1
+
+ eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
+ '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ eslint: 8.57.0
+ eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0))(eslint@8.57.0)
+ transitivePeerDependencies:
+ - eslint-plugin-import
+
+ eslint-config-prettier@9.1.0(eslint@8.57.0):
+ dependencies:
+ eslint: 8.57.0
+
+ eslint-import-resolver-node@0.3.9:
+ dependencies:
+ debug: 3.2.7
+ is-core-module: 2.15.1
+ resolve: 1.22.8
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-module-utils@2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0):
+ dependencies:
+ debug: 3.2.7
+ optionalDependencies:
+ '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0):
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.findlastindex: 1.2.5
+ array.prototype.flat: 1.3.2
+ array.prototype.flatmap: 1.3.2
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0)
+ hasown: 2.0.2
+ is-core-module: 2.15.1
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.0
+ semver: 6.3.1
+ tsconfig-paths: 3.15.0
+ optionalDependencies:
+ '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4)
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+
+ eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0):
+ dependencies:
+ aria-query: 5.1.3
+ array-includes: 3.1.8
+ array.prototype.flatmap: 1.3.2
+ ast-types-flow: 0.0.8
+ axe-core: 4.10.0
+ axobject-query: 3.1.1
+ damerau-levenshtein: 1.0.8
+ emoji-regex: 9.2.2
+ es-iterator-helpers: 1.0.19
+ eslint: 8.57.0
+ hasown: 2.0.2
+ jsx-ast-utils: 3.3.5
+ language-tags: 1.0.9
+ minimatch: 3.1.2
+ object.fromentries: 2.0.8
+ safe-regex-test: 1.0.3
+ string.prototype.includes: 2.0.0
+
+ eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3):
+ dependencies:
+ eslint: 8.57.0
+ prettier: 3.3.3
+ prettier-linter-helpers: 1.0.0
+ synckit: 0.9.1
+ optionalDependencies:
+ eslint-config-prettier: 9.1.0(eslint@8.57.0)
+
+ eslint-plugin-react-hooks@4.6.2(eslint@8.57.0):
+ dependencies:
+ eslint: 8.57.0
+
+ eslint-plugin-react@7.35.0(eslint@8.57.0):
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.findlast: 1.2.5
+ array.prototype.flatmap: 1.3.2
+ array.prototype.tosorted: 1.1.4
+ doctrine: 2.1.0
+ es-iterator-helpers: 1.0.19
+ eslint: 8.57.0
+ estraverse: 5.3.0
+ hasown: 2.0.2
+ jsx-ast-utils: 3.3.5
+ minimatch: 3.1.2
+ object.entries: 1.1.8
+ object.fromentries: 2.0.8
+ object.values: 1.2.0
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.5
+ semver: 6.3.1
+ string.prototype.matchall: 4.0.11
+ string.prototype.repeat: 1.0.0
+
+ eslint-plugin-tailwindcss@3.17.4(tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4))):
+ dependencies:
+ fast-glob: 3.3.2
+ postcss: 8.4.47
+ tailwindcss: 3.4.14(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4))
+
+ eslint-scope@5.1.1:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 4.3.0
+
+ eslint-scope@7.2.2:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint@8.57.0:
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+ '@eslint-community/regexpp': 4.11.0
+ '@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.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.7(supports-color@8.1.1)
+ 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.6.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.24.0
+ graphemer: 1.4.0
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ 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.4
+ strip-ansi: 6.0.1
+ text-table: 0.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ esm@3.2.25: {}
+
+ espree@9.6.1:
+ dependencies:
+ acorn: 8.12.1
+ acorn-jsx: 5.3.2(acorn@8.12.1)
+ eslint-visitor-keys: 3.4.3
+
+ esprima@4.0.1: {}
+
+ esquery@1.6.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@4.3.0: {}
+
+ estraverse@5.3.0: {}
+
+ estree-walker@2.0.2: {}
+
+ esutils@2.0.3: {}
+
+ event-target-shim@5.0.1: {}
+
+ eventemitter3@5.0.1: {}
+
+ events@3.3.0: {}
+
+ execa@8.0.1:
+ 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.3.0
+ onetime: 6.0.0
+ signal-exit: 4.1.0
+ strip-final-newline: 3.0.0
+
+ execa@9.3.1:
+ dependencies:
+ '@sindresorhus/merge-streams': 4.0.0
+ cross-spawn: 7.0.3
+ figures: 6.1.0
+ get-stream: 9.0.1
+ human-signals: 8.0.0
+ is-plain-obj: 4.1.0
+ is-stream: 4.0.1
+ npm-run-path: 5.3.0
+ pretty-ms: 9.1.0
+ signal-exit: 4.1.0
+ strip-final-newline: 4.0.0
+ yoctocolors: 2.1.1
+
+ expect-webdriverio@5.0.2(@wdio/globals@9.1.2(@wdio/logger@9.1.0))(@wdio/logger@9.1.0)(webdriverio@9.1.2):
+ dependencies:
+ '@vitest/snapshot': 2.0.5
+ '@wdio/globals': 9.1.2(@wdio/logger@9.1.0)
+ '@wdio/logger': 9.1.0
+ expect: 29.7.0
+ jest-matcher-utils: 29.7.0
+ lodash.isequal: 4.5.0
+ webdriverio: 9.1.2
+
+ expect-webdriverio@5.0.2(@wdio/globals@9.4.5(@wdio/logger@9.1.0))(@wdio/logger@9.1.0)(webdriverio@9.4.5):
+ dependencies:
+ '@vitest/snapshot': 2.0.5
+ '@wdio/globals': 9.4.5(@wdio/logger@9.1.0)
+ '@wdio/logger': 9.1.0
+ expect: 29.7.0
+ jest-matcher-utils: 29.7.0
+ lodash.isequal: 4.5.0
+ webdriverio: 9.4.5
+ optional: true
+
+ expect-webdriverio@5.0.2(@wdio/globals@9.4.5(@wdio/logger@9.1.0))(@wdio/logger@9.4.4)(webdriverio@9.4.5):
+ dependencies:
+ '@vitest/snapshot': 2.0.5
+ '@wdio/globals': 9.4.5(@wdio/logger@9.1.0)
+ '@wdio/logger': 9.4.4
+ expect: 29.7.0
+ jest-matcher-utils: 29.7.0
+ lodash.isequal: 4.5.0
+ webdriverio: 9.4.5
+ optional: true
+
+ expect@29.7.0:
+ dependencies:
+ '@jest/expect-utils': 29.7.0
+ jest-get-type: 29.6.3
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+
+ external-editor@3.1.0:
+ dependencies:
+ chardet: 0.7.0
+ iconv-lite: 0.4.24
+ tmp: 0.0.33
+
+ extract-zip@2.0.1:
+ dependencies:
+ debug: 4.3.7(supports-color@8.1.1)
+ get-stream: 5.2.0
+ yauzl: 2.10.0
+ optionalDependencies:
+ '@types/yauzl': 2.10.3
+ transitivePeerDependencies:
+ - supports-color
+
+ fast-deep-equal@2.0.1: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-diff@1.3.0: {}
+
+ fast-fifo@1.3.2: {}
+
+ fast-glob@3.3.2:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fast-xml-parser@4.5.0:
+ dependencies:
+ strnum: 1.0.5
+
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
+ fd-slicer@1.1.0:
+ dependencies:
+ pend: 1.2.0
+
+ fetch-blob@3.2.0:
+ dependencies:
+ node-domexception: 1.0.0
+ web-streams-polyfill: 3.3.3
+
+ fflate@0.8.2: {}
+
+ figures@6.1.0:
+ dependencies:
+ is-unicode-supported: 2.1.0
+
+ file-entry-cache@6.0.1:
+ dependencies:
+ flat-cache: 3.2.0
+
+ filelist@1.0.4:
+ dependencies:
+ minimatch: 5.1.6
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ find-up@6.3.0:
+ dependencies:
+ locate-path: 7.2.0
+ path-exists: 5.0.0
+
+ flat-cache@3.2.0:
+ dependencies:
+ flatted: 3.3.1
+ keyv: 4.5.4
+ rimraf: 3.0.2
+
+ flat@5.0.2: {}
+
+ flatted@3.3.1: {}
+
+ for-each@0.3.3:
+ dependencies:
+ is-callable: 1.2.7
+
+ foreground-child@3.3.0:
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
+ formdata-polyfill@4.0.10:
+ dependencies:
+ fetch-blob: 3.2.0
+
+ fraction.js@4.3.7: {}
+
+ fs-extra@11.2.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ jsonfile: 6.1.0
+ universalify: 2.0.1
+
+ fs.realpath@1.0.0: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ function.prototype.name@1.1.6:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ functions-have-names: 1.2.3
+
+ functions-have-names@1.2.3: {}
+
+ gaze@1.1.3:
+ dependencies:
+ globule: 1.3.4
+
+ geckodriver@4.5.0:
+ dependencies:
+ '@wdio/logger': 9.1.3
+ '@zip.js/zip.js': 2.7.52
+ decamelize: 6.0.0
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.5
+ node-fetch: 3.3.2
+ tar-fs: 3.0.6
+ which: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ geckodriver@5.0.0:
+ dependencies:
+ '@wdio/logger': 9.4.4
+ '@zip.js/zip.js': 2.7.54
+ decamelize: 6.0.0
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.5
+ node-fetch: 3.3.2
+ tar-fs: 3.0.6
+ which: 5.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ get-caller-file@2.0.5: {}
+
+ get-east-asian-width@1.2.0: {}
+
+ get-intrinsic@1.2.4:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+ has-proto: 1.0.3
+ has-symbols: 1.0.3
+ hasown: 2.0.2
+
+ get-port@7.1.0: {}
+
+ get-stream@5.2.0:
+ dependencies:
+ pump: 3.0.2
+
+ get-stream@8.0.1: {}
+
+ get-stream@9.0.1:
+ dependencies:
+ '@sec-ant/readable-stream': 0.4.1
+ is-stream: 4.0.1
+
+ get-symbol-description@1.0.2:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+
+ get-tsconfig@4.8.0:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
+ get-uri@6.0.3:
+ dependencies:
+ basic-ftp: 5.0.5
+ data-uri-to-buffer: 6.0.2
+ debug: 4.3.7(supports-color@8.1.1)
+ fs-extra: 11.2.0
+ transitivePeerDependencies:
+ - supports-color
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-to-regexp@0.4.1: {}
+
+ glob@10.4.5:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 1.11.1
+
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 4.0.1
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 2.0.0
+
+ glob@7.1.7:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
+ glob@7.2.3:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
+ glob@8.1.0:
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 5.1.6
+ once: 1.4.0
+
+ globals@13.24.0:
+ dependencies:
+ type-fest: 0.20.2
+
+ globalthis@1.0.4:
+ dependencies:
+ define-properties: 1.2.1
+ gopd: 1.0.1
+
+ globby@11.1.0:
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.3.2
+ ignore: 5.3.2
+ merge2: 1.4.1
+ slash: 3.0.0
+
+ globule@1.3.4:
+ dependencies:
+ glob: 7.1.7
+ lodash: 4.17.21
+ minimatch: 3.0.8
+
+ gopd@1.0.1:
+ dependencies:
+ get-intrinsic: 1.2.4
+
+ graceful-fs@4.2.11: {}
+
+ grapheme-splitter@1.0.4: {}
+
+ graphemer@1.4.0: {}
+
+ has-bigints@1.0.2: {}
+
+ has-flag@3.0.0: {}
+
+ has-flag@4.0.0: {}
+
+ has-property-descriptors@1.0.2:
+ dependencies:
+ es-define-property: 1.0.0
+
+ has-proto@1.0.3: {}
+
+ has-symbols@1.0.3: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.0.3
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ he@1.2.0: {}
+
+ hosted-git-info@7.0.2:
+ dependencies:
+ lru-cache: 10.4.3
+
+ htmlfy@0.2.1: {}
+
+ htmlfy@0.3.2: {}
+
+ htmlparser2@9.1.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.1.0
+ entities: 4.5.0
+
+ http-proxy-agent@7.0.2:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ https-proxy-agent@7.0.5:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ human-signals@5.0.0: {}
+
+ human-signals@8.0.0: {}
+
+ husky@9.1.5: {}
+
+ iconv-lite@0.4.24:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ ieee754@1.2.1: {}
+
+ ignore@5.3.2: {}
+
+ immediate@3.0.6: {}
+
+ immutable@4.3.7: {}
+
+ import-fresh@3.3.0:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ import-meta-resolve@4.1.0: {}
+
+ imurmurhash@0.1.4: {}
+
+ inflight@1.0.6:
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
+ inherits@2.0.4: {}
+
+ inquirer@11.1.0:
+ dependencies:
+ '@inquirer/core': 9.2.1
+ '@inquirer/prompts': 6.0.1
+ '@inquirer/type': 2.0.0
+ '@types/mute-stream': 0.0.4
+ ansi-escapes: 4.3.2
+ mute-stream: 1.0.0
+ run-async: 3.0.0
+ rxjs: 7.8.1
+
+ internal-slot@1.0.7:
+ dependencies:
+ es-errors: 1.3.0
+ hasown: 2.0.2
+ side-channel: 1.0.6
+
+ ip-address@9.0.5:
+ dependencies:
+ jsbn: 1.1.0
+ sprintf-js: 1.1.3
+
+ is-arguments@1.1.1:
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+
+ is-array-buffer@3.0.4:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+
+ is-arrayish@0.2.1: {}
+
+ is-async-function@2.0.0:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-bigint@1.0.4:
+ dependencies:
+ has-bigints: 1.0.2
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-boolean-object@1.1.2:
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+
+ is-callable@1.2.7: {}
+
+ is-core-module@2.15.1:
+ dependencies:
+ hasown: 2.0.2
+
+ is-data-view@1.0.1:
+ dependencies:
+ is-typed-array: 1.1.13
+
+ is-date-object@1.0.5:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-extglob@2.1.1: {}
+
+ is-finalizationregistry@1.0.2:
+ dependencies:
+ call-bind: 1.0.7
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-fullwidth-code-point@4.0.0: {}
+
+ is-fullwidth-code-point@5.0.0:
+ dependencies:
+ get-east-asian-width: 1.2.0
+
+ is-generator-function@1.0.10:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-map@2.0.3: {}
+
+ is-negative-zero@2.0.3: {}
+
+ is-number-object@1.0.7:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-number@7.0.0: {}
+
+ is-path-inside@3.0.3: {}
+
+ is-plain-obj@2.1.0: {}
+
+ is-plain-obj@4.1.0: {}
+
+ is-regex@1.1.4:
+ dependencies:
+ call-bind: 1.0.7
+ has-tostringtag: 1.0.2
+
+ is-set@2.0.3: {}
+
+ is-shared-array-buffer@1.0.3:
+ dependencies:
+ call-bind: 1.0.7
+
+ is-stream@2.0.1: {}
+
+ is-stream@3.0.0: {}
+
+ is-stream@4.0.1: {}
+
+ is-string@1.0.7:
+ dependencies:
+ has-tostringtag: 1.0.2
+
+ is-symbol@1.0.4:
+ dependencies:
+ has-symbols: 1.0.3
+
+ is-typed-array@1.1.13:
+ dependencies:
+ which-typed-array: 1.1.15
+
+ is-unicode-supported@0.1.0: {}
+
+ is-unicode-supported@2.1.0: {}
+
+ is-weakmap@2.0.2: {}
+
+ is-weakref@1.0.2:
+ dependencies:
+ call-bind: 1.0.7
+
+ is-weakset@2.0.3:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+
+ isarray@1.0.0: {}
+
+ isarray@2.0.5: {}
+
+ isexe@2.0.0: {}
+
+ isexe@3.1.1: {}
+
+ iterator.prototype@1.1.2:
+ dependencies:
+ define-properties: 1.2.1
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ reflect.getprototypeof: 1.0.6
+ set-function-name: 2.0.2
+
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ jackspeak@4.0.1:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ jake@10.9.2:
+ dependencies:
+ async: 3.2.6
+ chalk: 4.1.2
+ filelist: 1.0.4
+ minimatch: 3.1.2
+
+ jest-diff@29.7.0:
+ dependencies:
+ chalk: 4.1.2
+ diff-sequences: 29.6.3
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+
+ jest-get-type@29.6.3: {}
+
+ jest-matcher-utils@29.7.0:
+ dependencies:
+ chalk: 4.1.2
+ jest-diff: 29.7.0
+ jest-get-type: 29.6.3
+ pretty-format: 29.7.0
+
+ jest-message-util@29.7.0:
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@jest/types': 29.6.3
+ '@types/stack-utils': 2.0.3
+ chalk: 4.1.2
+ graceful-fs: 4.2.11
+ micromatch: 4.0.8
+ pretty-format: 29.7.0
+ slash: 3.0.0
+ stack-utils: 2.0.6
+
+ jest-util@29.7.0:
+ dependencies:
+ '@jest/types': 29.6.3
+ '@types/node': 22.7.4
+ chalk: 4.1.2
+ ci-info: 3.9.0
+ graceful-fs: 4.2.11
+ picomatch: 2.3.1
+
+ jest-worker@27.5.1:
+ dependencies:
+ '@types/node': 22.7.4
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
+
+ jiti@1.21.6: {}
+
+ js-tokens@4.0.0: {}
+
+ js-yaml@4.1.0:
+ dependencies:
+ argparse: 2.0.1
+
+ jsbn@1.1.0: {}
+
+ json-buffer@3.0.1: {}
+
+ json-parse-even-better-errors@2.3.1: {}
+
+ json-parse-even-better-errors@3.0.2: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ json5@1.0.2:
+ dependencies:
+ minimist: 1.2.8
+
+ jsonfile@6.1.0:
+ dependencies:
+ universalify: 2.0.1
+ optionalDependencies:
+ graceful-fs: 4.2.11
+
+ jsx-ast-utils@3.3.5:
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.flat: 1.3.2
+ object.assign: 4.1.5
+ object.values: 1.2.0
+
+ jszip@3.10.1:
+ dependencies:
+ lie: 3.3.0
+ pako: 1.0.11
+ readable-stream: 2.3.8
+ setimmediate: 1.0.5
+
+ keyv@4.5.4:
+ dependencies:
+ json-buffer: 3.0.1
+
+ language-subtag-registry@0.3.23: {}
+
+ language-tags@1.0.9:
+ dependencies:
+ language-subtag-registry: 0.3.23
+
+ lazystream@1.0.1:
+ dependencies:
+ readable-stream: 2.3.8
+
+ levn@0.4.1:
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ lie@3.3.0:
+ dependencies:
+ immediate: 3.0.6
+
+ lilconfig@2.1.0: {}
+
+ lilconfig@3.1.2: {}
+
+ lines-and-columns@1.2.4: {}
+
+ lines-and-columns@2.0.4: {}
+
+ lint-staged@15.2.10:
+ dependencies:
+ chalk: 5.3.0
+ commander: 12.1.0
+ debug: 4.3.7(supports-color@8.1.1)
+ execa: 8.0.1
+ lilconfig: 3.1.2
+ listr2: 8.2.4
+ micromatch: 4.0.8
+ pidtree: 0.6.0
+ string-argv: 0.3.2
+ yaml: 2.5.1
+ transitivePeerDependencies:
+ - supports-color
+
+ listr2@8.2.4:
+ dependencies:
+ cli-truncate: 4.0.0
+ colorette: 2.0.20
+ eventemitter3: 5.0.1
+ log-update: 6.1.0
+ rfdc: 1.4.1
+ wrap-ansi: 9.0.0
+
+ loader-runner@4.3.0: {}
+
+ loader-utils@3.3.1: {}
+
+ locate-app@2.4.43:
+ dependencies:
+ '@promptbook/utils': 0.70.0-1
+ type-fest: 2.13.0
+ userhome: 1.0.0
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ locate-path@7.2.0:
+ dependencies:
+ p-locate: 6.0.0
+
+ lodash.clonedeep@4.5.0: {}
+
+ lodash.flattendeep@4.4.0: {}
+
+ lodash.isequal@4.5.0: {}
+
+ lodash.merge@4.6.2: {}
+
+ lodash.pickby@4.6.0: {}
+
+ lodash.union@4.6.0: {}
+
+ lodash.zip@4.2.0: {}
+
+ lodash@4.17.21: {}
+
+ log-symbols@4.1.0:
+ dependencies:
+ chalk: 4.1.2
+ is-unicode-supported: 0.1.0
+
+ log-update@6.1.0:
+ dependencies:
+ ansi-escapes: 7.0.0
+ cli-cursor: 5.0.0
+ slice-ansi: 7.1.0
+ strip-ansi: 7.1.0
+ wrap-ansi: 9.0.0
+
+ loglevel-plugin-prefix@0.8.4: {}
+
+ loglevel@1.9.2: {}
+
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
+ lru-cache@10.4.3: {}
+
+ lru-cache@11.0.1: {}
+
+ lru-cache@7.18.3: {}
+
+ magic-string@0.30.11:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ magic-string@0.30.17:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ make-error@1.3.6: {}
+
+ merge-stream@2.0.0: {}
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ mimic-fn@4.0.0: {}
+
+ mimic-function@5.0.1: {}
+
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minimatch@3.0.8:
+ dependencies:
+ brace-expansion: 1.1.11
+
+ minimatch@3.1.2:
+ dependencies:
+ brace-expansion: 1.1.11
+
+ minimatch@5.1.6:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minimatch@9.0.5:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minimist@1.2.8: {}
+
+ minipass@7.1.2: {}
+
+ mocha@10.7.3:
+ dependencies:
+ ansi-colors: 4.1.3
+ browser-stdout: 1.3.1
+ chokidar: 3.6.0
+ debug: 4.3.7(supports-color@8.1.1)
+ diff: 5.2.0
+ escape-string-regexp: 4.0.0
+ find-up: 5.0.0
+ glob: 8.1.0
+ he: 1.2.0
+ js-yaml: 4.1.0
+ log-symbols: 4.1.0
+ minimatch: 5.1.6
+ ms: 2.1.3
+ serialize-javascript: 6.0.2
+ strip-json-comments: 3.1.1
+ supports-color: 8.1.1
+ workerpool: 6.5.1
+ yargs: 16.2.0
+ yargs-parser: 20.2.9
+ yargs-unparser: 2.0.0
+
+ mrmime@1.0.1: {}
+
+ ms@2.1.3: {}
+
+ mute-stream@1.0.0: {}
+
+ mylas@2.1.13: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ nanoid@3.3.7: {}
+
+ natural-compare@1.4.0: {}
+
+ neo-async@2.6.2: {}
+
+ netmask@2.0.2: {}
+
+ node-domexception@1.0.0: {}
+
+ node-fetch@3.3.2:
+ dependencies:
+ data-uri-to-buffer: 4.0.1
+ fetch-blob: 3.2.0
+ formdata-polyfill: 4.0.10
+
+ node-releases@2.0.18: {}
+
+ normalize-package-data@6.0.2:
+ dependencies:
+ hosted-git-info: 7.0.2
+ semver: 7.6.3
+ validate-npm-package-license: 3.0.4
+
+ normalize-path@3.0.0: {}
+
+ normalize-range@0.1.2: {}
+
+ npm-run-path@5.3.0:
+ dependencies:
+ path-key: 4.0.0
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ object-assign@4.1.1: {}
+
+ object-hash@3.0.0: {}
+
+ object-inspect@1.13.2: {}
+
+ object-is@1.1.6:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+
+ object-keys@1.1.1: {}
+
+ object.assign@4.1.5:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+
+ object.entries@1.1.8:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+
+ object.fromentries@2.0.8:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+
+ object.groupby@1.0.3:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+
+ object.values@1.2.0:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ onetime@6.0.0:
+ dependencies:
+ mimic-fn: 4.0.0
+
+ onetime@7.0.0:
+ dependencies:
+ mimic-function: 5.0.1
+
+ optionator@0.9.4:
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
+
+ os-tmpdir@1.0.2: {}
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-limit@4.0.0:
+ dependencies:
+ yocto-queue: 1.1.1
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ p-locate@6.0.0:
+ dependencies:
+ p-limit: 4.0.0
+
+ pac-proxy-agent@7.0.2:
+ dependencies:
+ '@tootallnate/quickjs-emscripten': 0.23.0
+ agent-base: 7.1.1
+ debug: 4.3.7(supports-color@8.1.1)
+ get-uri: 6.0.3
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.5
+ pac-resolver: 7.0.1
+ socks-proxy-agent: 8.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ pac-resolver@7.0.1:
+ dependencies:
+ degenerator: 5.0.1
+ netmask: 2.0.2
+
+ package-json-from-dist@1.0.0: {}
+
+ pako@1.0.11: {}
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ parse-json@7.1.1:
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ error-ex: 1.3.2
+ json-parse-even-better-errors: 3.0.2
+ lines-and-columns: 2.0.4
+ type-fest: 3.13.1
+
+ parse-ms@4.0.0: {}
+
+ parse5-htmlparser2-tree-adapter@7.0.0:
+ dependencies:
+ domhandler: 5.0.3
+ parse5: 7.1.2
+
+ parse5-parser-stream@7.1.2:
+ dependencies:
+ parse5: 7.1.2
+
+ parse5@7.1.2:
+ dependencies:
+ entities: 4.5.0
+
+ path-exists@4.0.0: {}
+
+ path-exists@5.0.0: {}
+
+ path-is-absolute@1.0.1: {}
+
+ path-key@3.1.1: {}
+
+ path-key@4.0.0: {}
+
+ path-parse@1.0.7: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.2
+
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
+ path-type@4.0.0: {}
+
+ pathe@1.1.2: {}
+
+ pend@1.2.0: {}
+
+ picocolors@1.1.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.1: {}
+
+ pidtree@0.6.0: {}
+
+ pify@2.3.0: {}
+
+ pirates@4.0.6: {}
+
+ plimit-lit@1.6.1:
+ dependencies:
+ queue-lit: 1.5.2
+
+ possible-typed-array-names@1.0.0: {}
+
+ postcss-import@15.1.0(postcss@8.4.47):
+ dependencies:
+ postcss: 8.4.47
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.8
+
+ postcss-js@4.0.1(postcss@8.4.47):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.47
+
+ postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4)):
+ dependencies:
+ lilconfig: 3.1.2
+ yaml: 2.5.1
+ optionalDependencies:
+ postcss: 8.4.47
+ ts-node: 10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4)
+
+ postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.49)(tsx@4.19.2)(yaml@2.5.1):
+ dependencies:
+ lilconfig: 3.1.2
+ optionalDependencies:
+ jiti: 1.21.6
+ postcss: 8.4.49
+ tsx: 4.19.2
+ yaml: 2.5.1
+
+ postcss-nested@6.2.0(postcss@8.4.47):
+ dependencies:
+ postcss: 8.4.47
+ postcss-selector-parser: 6.1.2
+
+ postcss-selector-parser@6.1.2:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.47:
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.1.0
+ source-map-js: 1.2.1
+
+ postcss@8.4.49:
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prelude-ls@1.2.1: {}
+
+ prettier-linter-helpers@1.0.0:
+ dependencies:
+ fast-diff: 1.3.0
+
+ prettier@3.3.3: {}
+
+ pretty-format@29.7.0:
+ dependencies:
+ '@jest/schemas': 29.6.3
+ ansi-styles: 5.2.0
+ react-is: 18.3.1
+
+ pretty-ms@9.1.0:
+ dependencies:
+ parse-ms: 4.0.0
+
+ process-nextick-args@2.0.1: {}
+
+ process@0.11.10: {}
+
+ progress@2.0.3: {}
+
+ prop-types@15.8.1:
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+
+ proxy-agent@6.4.0:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7(supports-color@8.1.1)
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.5
+ lru-cache: 7.18.3
+ pac-proxy-agent: 7.0.2
+ proxy-from-env: 1.1.0
+ socks-proxy-agent: 8.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ proxy-from-env@1.1.0: {}
+
+ pump@3.0.2:
+ dependencies:
+ end-of-stream: 1.4.4
+ once: 1.4.0
+
+ punycode@2.3.1: {}
+
+ query-selector-shadow-dom@1.0.1: {}
+
+ queue-lit@1.5.2: {}
+
+ queue-microtask@1.2.3: {}
+
+ queue-tick@1.0.1: {}
+
+ randombytes@2.1.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ react-dom@18.3.1(react@18.3.1):
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.3.1
+ scheduler: 0.23.2
+
+ react-is@16.13.1: {}
+
+ react-is@18.3.1: {}
+
+ react@18.3.1:
+ dependencies:
+ loose-envify: 1.4.0
+
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
+ read-pkg-up@10.1.0:
+ dependencies:
+ find-up: 6.3.0
+ read-pkg: 8.1.0
+ type-fest: 4.26.1
+
+ read-pkg@8.1.0:
+ dependencies:
+ '@types/normalize-package-data': 2.4.4
+ normalize-package-data: 6.0.2
+ parse-json: 7.1.1
+ type-fest: 4.26.1
+
+ readable-stream@2.3.8:
+ dependencies:
+ core-util-is: 1.0.3
+ inherits: 2.0.4
+ isarray: 1.0.0
+ process-nextick-args: 2.0.1
+ safe-buffer: 5.1.2
+ string_decoder: 1.1.1
+ util-deprecate: 1.0.2
+
+ readable-stream@4.5.2:
+ dependencies:
+ abort-controller: 3.0.0
+ buffer: 6.0.3
+ events: 3.3.0
+ process: 0.11.10
+ string_decoder: 1.3.0
+
+ readdir-glob@1.1.3:
+ dependencies:
+ minimatch: 5.1.6
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
+ readdirp@4.0.2: {}
+
+ recursive-readdir@2.2.3:
+ dependencies:
+ minimatch: 3.1.2
+
+ reflect.getprototypeof@1.0.6:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ globalthis: 1.0.4
+ which-builtin-type: 1.1.4
+
+ regexp.prototype.flags@1.5.2:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-errors: 1.3.0
+ set-function-name: 2.0.2
+
+ require-directory@2.1.1: {}
+
+ resolve-from@4.0.0: {}
+
+ resolve-pkg-maps@1.0.0: {}
+
+ resolve@1.22.8:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ resolve@2.0.0-next.5:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ resq@1.11.0:
+ dependencies:
+ fast-deep-equal: 2.0.1
+
+ restore-cursor@5.1.0:
+ dependencies:
+ onetime: 7.0.0
+ signal-exit: 4.1.0
+
+ reusify@1.0.4: {}
+
+ rfdc@1.4.1: {}
+
+ rgb2hex@0.2.5: {}
+
+ rimraf@3.0.2:
+ dependencies:
+ glob: 7.2.3
+
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.0
+
+ rollup@4.24.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.24.0
+ '@rollup/rollup-android-arm64': 4.24.0
+ '@rollup/rollup-darwin-arm64': 4.24.0
+ '@rollup/rollup-darwin-x64': 4.24.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.24.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.24.0
+ '@rollup/rollup-linux-arm64-gnu': 4.24.0
+ '@rollup/rollup-linux-arm64-musl': 4.24.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.24.0
+ '@rollup/rollup-linux-s390x-gnu': 4.24.0
+ '@rollup/rollup-linux-x64-gnu': 4.24.0
+ '@rollup/rollup-linux-x64-musl': 4.24.0
+ '@rollup/rollup-win32-arm64-msvc': 4.24.0
+ '@rollup/rollup-win32-ia32-msvc': 4.24.0
+ '@rollup/rollup-win32-x64-msvc': 4.24.0
+ fsevents: 2.3.3
+
+ run-async@3.0.0: {}
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ run-script-os@1.1.6: {}
+
+ rxjs@7.8.1:
+ dependencies:
+ tslib: 2.7.0
+
+ safaridriver@0.1.2: {}
+
+ safaridriver@1.0.0: {}
+
+ safe-array-concat@1.1.2:
+ dependencies:
+ call-bind: 1.0.7
+ get-intrinsic: 1.2.4
+ has-symbols: 1.0.3
+ isarray: 2.0.5
+
+ safe-buffer@5.1.2: {}
+
+ safe-buffer@5.2.1: {}
+
+ safe-regex-test@1.0.3:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-regex: 1.1.4
+
+ safer-buffer@2.1.2: {}
+
+ sass@1.79.4:
+ dependencies:
+ chokidar: 4.0.1
+ immutable: 4.3.7
+ source-map-js: 1.2.1
+
+ scheduler@0.23.2:
+ dependencies:
+ loose-envify: 1.4.0
+
+ schema-utils@3.3.0:
+ dependencies:
+ '@types/json-schema': 7.0.15
+ ajv: 6.12.6
+ ajv-keywords: 3.5.2(ajv@6.12.6)
+
+ semver@6.3.1: {}
+
+ semver@7.6.3: {}
+
+ serialize-error@11.0.3:
+ dependencies:
+ type-fest: 2.19.0
+
+ serialize-javascript@6.0.2:
+ dependencies:
+ randombytes: 2.1.0
+
+ set-function-length@1.2.2:
+ 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
+
+ set-function-name@2.0.2:
+ dependencies:
+ define-data-property: 1.1.4
+ es-errors: 1.3.0
+ functions-have-names: 1.2.3
+ has-property-descriptors: 1.0.2
+
+ setimmediate@1.0.5: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ shell-quote@1.8.1: {}
+
+ side-channel@1.0.6:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ get-intrinsic: 1.2.4
+ object-inspect: 1.13.2
+
+ signal-exit@4.1.0: {}
+
+ slash@3.0.0: {}
+
+ slice-ansi@5.0.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 4.0.0
+
+ slice-ansi@7.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ is-fullwidth-code-point: 5.0.0
+
+ smart-buffer@4.2.0: {}
+
+ socks-proxy-agent@8.0.4:
+ dependencies:
+ agent-base: 7.1.1
+ debug: 4.3.7(supports-color@8.1.1)
+ socks: 2.8.3
+ transitivePeerDependencies:
+ - supports-color
+
+ socks@2.8.3:
+ dependencies:
+ ip-address: 9.0.5
+ smart-buffer: 4.2.0
+
+ source-map-js@1.2.1: {}
+
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.6.1: {}
+
+ source-map@0.7.4: {}
+
+ spacetrim@0.11.39: {}
+
+ spdx-correct@3.2.0:
+ dependencies:
+ spdx-expression-parse: 3.0.1
+ spdx-license-ids: 3.0.20
+
+ spdx-exceptions@2.5.0: {}
+
+ spdx-expression-parse@3.0.1:
+ dependencies:
+ spdx-exceptions: 2.5.0
+ spdx-license-ids: 3.0.20
+
+ spdx-license-ids@3.0.20: {}
+
+ split2@4.2.0: {}
+
+ sprintf-js@1.1.3: {}
+
+ stack-utils@2.0.6:
+ dependencies:
+ escape-string-regexp: 2.0.0
+
+ stop-iteration-iterator@1.0.0:
+ dependencies:
+ internal-slot: 1.0.7
+
+ stream-buffers@3.0.3: {}
+
+ streamx@2.20.1:
+ dependencies:
+ fast-fifo: 1.3.2
+ queue-tick: 1.0.1
+ text-decoder: 1.2.0
+ optionalDependencies:
+ bare-events: 2.5.0
+
+ string-argv@0.3.2: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ string-width@7.2.0:
+ dependencies:
+ emoji-regex: 10.4.0
+ get-east-asian-width: 1.2.0
+ strip-ansi: 7.1.0
+
+ string.prototype.includes@2.0.0:
+ dependencies:
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+
+ string.prototype.matchall@4.0.11:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-errors: 1.3.0
+ es-object-atoms: 1.0.0
+ get-intrinsic: 1.2.4
+ gopd: 1.0.1
+ has-symbols: 1.0.3
+ internal-slot: 1.0.7
+ regexp.prototype.flags: 1.5.2
+ set-function-name: 2.0.2
+ side-channel: 1.0.6
+
+ string.prototype.repeat@1.0.0:
+ dependencies:
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+
+ string.prototype.trim@1.2.9:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-abstract: 1.23.3
+ es-object-atoms: 1.0.0
+
+ string.prototype.trimend@1.0.8:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+
+ string.prototype.trimstart@1.0.8:
+ dependencies:
+ call-bind: 1.0.7
+ define-properties: 1.2.1
+ es-object-atoms: 1.0.0
+
+ string_decoder@1.1.1:
+ dependencies:
+ safe-buffer: 5.1.2
+
+ string_decoder@1.3.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
+ strip-bom@3.0.0: {}
+
+ strip-final-newline@3.0.0: {}
+
+ strip-final-newline@4.0.0: {}
+
+ strip-json-comments@3.1.1: {}
+
+ strnum@1.0.5: {}
+
+ sucrase@3.35.0:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ commander: 4.1.1
+ glob: 10.4.5
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ ts-interface-checker: 0.1.13
+
+ supports-color@5.5.0:
+ dependencies:
+ has-flag: 3.0.0
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ synckit@0.9.1:
+ dependencies:
+ '@pkgr/core': 0.1.1
+ tslib: 2.7.0
+
+ tailwind-merge@2.5.2: {}
+
+ tailwindcss@3.4.14(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4)):
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.6
+ lilconfig: 2.1.0
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.0
+ postcss: 8.4.47
+ postcss-import: 15.1.0(postcss@8.4.47)
+ postcss-js: 4.0.1(postcss@8.4.47)
+ postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4))
+ postcss-nested: 6.2.0(postcss@8.4.47)
+ postcss-selector-parser: 6.1.2
+ resolve: 1.22.8
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+
+ tapable@2.2.1: {}
+
+ tar-fs@3.0.6:
+ dependencies:
+ pump: 3.0.2
+ tar-stream: 3.1.7
+ optionalDependencies:
+ bare-fs: 2.3.5
+ bare-path: 2.1.3
+
+ tar-stream@3.1.7:
+ dependencies:
+ b4a: 1.6.7
+ fast-fifo: 1.3.2
+ streamx: 2.20.1
+
+ terser-webpack-plugin@5.3.10(@swc/core@1.9.3)(esbuild@0.23.1)(webpack@5.94.0(@swc/core@1.9.3)(esbuild@0.23.1)):
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.25
+ jest-worker: 27.5.1
+ schema-utils: 3.3.0
+ serialize-javascript: 6.0.2
+ terser: 5.34.1
+ webpack: 5.94.0(@swc/core@1.9.3)(esbuild@0.23.1)
+ optionalDependencies:
+ '@swc/core': 1.9.3
+ esbuild: 0.23.1
+
+ terser@5.34.1:
+ dependencies:
+ '@jridgewell/source-map': 0.3.6
+ acorn: 8.12.1
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
+ text-decoder@1.2.0:
+ dependencies:
+ b4a: 1.6.7
+
+ text-table@0.2.0: {}
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
+ through@2.3.8: {}
+
+ tinyrainbow@1.2.0: {}
+
+ tmp@0.0.33:
+ dependencies:
+ os-tmpdir: 1.0.2
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ tree-kill@1.2.2: {}
+
+ ts-api-utils@1.3.0(typescript@5.5.4):
+ dependencies:
+ typescript: 5.5.4
+
+ ts-interface-checker@0.1.13: {}
+
+ ts-loader@9.5.1(typescript@5.5.4)(webpack@5.94.0(@swc/core@1.9.3)(esbuild@0.23.1)):
+ dependencies:
+ chalk: 4.1.2
+ enhanced-resolve: 5.17.1
+ micromatch: 4.0.8
+ semver: 7.6.3
+ source-map: 0.7.4
+ typescript: 5.5.4
+ webpack: 5.94.0(@swc/core@1.9.3)(esbuild@0.23.1)
+
+ ts-node@10.9.2(@swc/core@1.9.3)(@types/node@22.7.4)(typescript@5.5.4):
+ dependencies:
+ '@cspotcode/source-map-support': 0.8.1
+ '@tsconfig/node10': 1.0.11
+ '@tsconfig/node12': 1.0.11
+ '@tsconfig/node14': 1.0.3
+ '@tsconfig/node16': 1.0.4
+ '@types/node': 22.7.4
+ acorn: 8.12.1
+ acorn-walk: 8.3.4
+ arg: 4.1.3
+ create-require: 1.1.1
+ diff: 4.0.2
+ make-error: 1.3.6
+ typescript: 5.5.4
+ v8-compile-cache-lib: 3.0.1
+ yn: 3.1.1
+ optionalDependencies:
+ '@swc/core': 1.9.3
+
+ tsc-alias@1.8.10:
+ dependencies:
+ chokidar: 3.6.0
+ commander: 9.5.0
+ globby: 11.1.0
+ mylas: 2.1.13
+ normalize-path: 3.0.0
+ plimit-lit: 1.6.1
+
+ tsconfig-paths@3.15.0:
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.2
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
+ tslib@2.7.0: {}
+
+ tsx@4.19.2:
+ dependencies:
+ esbuild: 0.23.1
+ get-tsconfig: 4.8.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ turbo-darwin-64@2.3.3:
+ optional: true
+
+ turbo-darwin-arm64@2.3.3:
+ optional: true
+
+ turbo-linux-64@2.3.3:
+ optional: true
+
+ turbo-linux-arm64@2.3.3:
+ optional: true
+
+ turbo-windows-64@2.3.3:
+ optional: true
+
+ turbo-windows-arm64@2.3.3:
+ optional: true
+
+ turbo@2.3.3:
+ optionalDependencies:
+ turbo-darwin-64: 2.3.3
+ turbo-darwin-arm64: 2.3.3
+ turbo-linux-64: 2.3.3
+ turbo-linux-arm64: 2.3.3
+ turbo-windows-64: 2.3.3
+ turbo-windows-arm64: 2.3.3
+
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
+
+ type-fest@0.20.2: {}
+
+ type-fest@0.21.3: {}
+
+ type-fest@2.13.0: {}
+
+ type-fest@2.19.0: {}
+
+ type-fest@3.13.1: {}
+
+ type-fest@4.26.1: {}
+
+ typed-array-buffer@1.0.2:
+ dependencies:
+ call-bind: 1.0.7
+ es-errors: 1.3.0
+ is-typed-array: 1.1.13
+
+ typed-array-byte-length@1.0.1:
+ dependencies:
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+
+ typed-array-byte-offset@1.0.2:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+
+ typed-array-length@1.0.6:
+ dependencies:
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-proto: 1.0.3
+ is-typed-array: 1.1.13
+ possible-typed-array-names: 1.0.0
+
+ typescript@5.5.4: {}
+
+ unbox-primitive@1.0.2:
+ dependencies:
+ call-bind: 1.0.7
+ has-bigints: 1.0.2
+ has-symbols: 1.0.3
+ which-boxed-primitive: 1.0.2
+
+ unbzip2-stream@1.4.3:
+ dependencies:
+ buffer: 5.7.1
+ through: 2.3.8
+
+ undici-types@6.19.8: {}
+
+ undici@6.21.0: {}
+
+ universalify@2.0.1: {}
+
+ update-browserslist-db@1.1.1(browserslist@4.24.0):
+ dependencies:
+ browserslist: 4.24.0
+ escalade: 3.2.0
+ picocolors: 1.1.0
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ urlpattern-polyfill@10.0.0: {}
+
+ userhome@1.0.0: {}
+
+ util-deprecate@1.0.2: {}
+
+ v8-compile-cache-lib@3.0.1: {}
+
+ validate-npm-package-license@3.0.4:
+ dependencies:
+ spdx-correct: 3.2.0
+ spdx-expression-parse: 3.0.1
+
+ vite@6.0.5(@types/node@22.7.4)(jiti@1.21.6)(sass@1.79.4)(terser@5.34.1)(tsx@4.19.2)(yaml@2.5.1):
+ dependencies:
+ esbuild: 0.24.0
+ postcss: 8.4.49
+ rollup: 4.24.0
+ optionalDependencies:
+ '@types/node': 22.7.4
+ fsevents: 2.3.3
+ jiti: 1.21.6
+ sass: 1.79.4
+ terser: 5.34.1
+ tsx: 4.19.2
+ yaml: 2.5.1
+
+ wait-port@1.1.0:
+ dependencies:
+ chalk: 4.1.2
+ commander: 9.5.0
+ debug: 4.3.7(supports-color@8.1.1)
+ transitivePeerDependencies:
+ - supports-color
+
+ watchpack@2.4.2:
+ dependencies:
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.11
+
+ wcwidth@1.0.1:
+ dependencies:
+ defaults: 1.0.4
+ optional: true
+
+ web-streams-polyfill@3.3.3: {}
+
+ webdriver@9.1.2:
+ dependencies:
+ '@types/node': 20.16.10
+ '@types/ws': 8.5.13
+ '@wdio/config': 9.1.2
+ '@wdio/logger': 9.1.0
+ '@wdio/protocols': 9.0.8
+ '@wdio/types': 9.1.2
+ '@wdio/utils': 9.1.2
+ deepmerge-ts: 7.1.1
+ ws: 8.18.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ webdriver@9.4.4:
+ dependencies:
+ '@types/node': 20.16.10
+ '@types/ws': 8.5.13
+ '@wdio/config': 9.4.4
+ '@wdio/logger': 9.4.4
+ '@wdio/protocols': 9.4.4
+ '@wdio/types': 9.4.4
+ '@wdio/utils': 9.4.4
+ deepmerge-ts: 7.1.1
+ undici: 6.21.0
+ ws: 8.18.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ webdriverio@9.1.2:
+ dependencies:
+ '@types/node': 20.16.10
+ '@types/sinonjs__fake-timers': 8.1.5
+ '@wdio/config': 9.1.2
+ '@wdio/logger': 9.1.0
+ '@wdio/protocols': 9.0.8
+ '@wdio/repl': 9.0.8
+ '@wdio/types': 9.1.2
+ '@wdio/utils': 9.1.2
+ archiver: 7.0.1
+ aria-query: 5.3.2
+ cheerio: 1.0.0
+ css-shorthand-properties: 1.1.2
+ css-value: 0.0.1
+ grapheme-splitter: 1.0.4
+ htmlfy: 0.2.1
+ import-meta-resolve: 4.1.0
+ is-plain-obj: 4.1.0
+ jszip: 3.10.1
+ lodash.clonedeep: 4.5.0
+ lodash.zip: 4.2.0
+ minimatch: 9.0.5
+ query-selector-shadow-dom: 1.0.1
+ resq: 1.11.0
+ rgb2hex: 0.2.5
+ serialize-error: 11.0.3
+ urlpattern-polyfill: 10.0.0
+ webdriver: 9.1.2
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ webdriverio@9.4.5:
+ dependencies:
+ '@types/node': 20.16.10
+ '@types/sinonjs__fake-timers': 8.1.5
+ '@wdio/config': 9.4.4
+ '@wdio/logger': 9.4.4
+ '@wdio/protocols': 9.4.4
+ '@wdio/repl': 9.4.4
+ '@wdio/types': 9.4.4
+ '@wdio/utils': 9.4.4
+ archiver: 7.0.1
+ aria-query: 5.3.2
+ cheerio: 1.0.0
+ css-shorthand-properties: 1.1.2
+ css-value: 0.0.1
+ grapheme-splitter: 1.0.4
+ htmlfy: 0.3.2
+ import-meta-resolve: 4.1.0
+ is-plain-obj: 4.1.0
+ jszip: 3.10.1
+ lodash.clonedeep: 4.5.0
+ lodash.zip: 4.2.0
+ minimatch: 9.0.5
+ query-selector-shadow-dom: 1.0.1
+ resq: 1.11.0
+ rgb2hex: 0.2.5
+ serialize-error: 11.0.3
+ urlpattern-polyfill: 10.0.0
+ webdriver: 9.4.4
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ webextension-polyfill@0.12.0: {}
+
+ webpack-sources@3.2.3: {}
+
+ webpack@5.94.0(@swc/core@1.9.3)(esbuild@0.23.1):
+ dependencies:
+ '@types/estree': 1.0.6
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/wasm-edit': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+ acorn: 8.12.1
+ acorn-import-attributes: 1.9.5(acorn@8.12.1)
+ browserslist: 4.24.0
+ chrome-trace-event: 1.0.4
+ enhanced-resolve: 5.17.1
+ es-module-lexer: 1.5.4
+ eslint-scope: 5.1.1
+ events: 3.3.0
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.11
+ json-parse-even-better-errors: 2.3.1
+ loader-runner: 4.3.0
+ mime-types: 2.1.35
+ neo-async: 2.6.2
+ schema-utils: 3.3.0
+ tapable: 2.2.1
+ terser-webpack-plugin: 5.3.10(@swc/core@1.9.3)(esbuild@0.23.1)(webpack@5.94.0(@swc/core@1.9.3)(esbuild@0.23.1))
+ watchpack: 2.4.2
+ webpack-sources: 3.2.3
+ transitivePeerDependencies:
+ - '@swc/core'
+ - esbuild
+ - uglify-js
+
+ whatwg-encoding@3.1.1:
+ dependencies:
+ iconv-lite: 0.6.3
+
+ whatwg-mimetype@4.0.0: {}
+
+ which-boxed-primitive@1.0.2:
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+
+ which-builtin-type@1.1.4:
+ dependencies:
+ function.prototype.name: 1.1.6
+ has-tostringtag: 1.0.2
+ is-async-function: 2.0.0
+ is-date-object: 1.0.5
+ is-finalizationregistry: 1.0.2
+ is-generator-function: 1.0.10
+ is-regex: 1.1.4
+ is-weakref: 1.0.2
+ isarray: 2.0.5
+ which-boxed-primitive: 1.0.2
+ which-collection: 1.0.2
+ which-typed-array: 1.1.15
+
+ which-collection@1.0.2:
+ dependencies:
+ is-map: 2.0.3
+ is-set: 2.0.3
+ is-weakmap: 2.0.2
+ is-weakset: 2.0.3
+
+ which-typed-array@1.1.15:
+ dependencies:
+ available-typed-arrays: 1.0.7
+ call-bind: 1.0.7
+ for-each: 0.3.3
+ gopd: 1.0.1
+ has-tostringtag: 1.0.2
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ which@4.0.0:
+ dependencies:
+ isexe: 3.1.1
+
+ which@5.0.0:
+ dependencies:
+ isexe: 3.1.1
+
+ word-wrap@1.2.5: {}
+
+ workerpool@6.5.1: {}
+
+ wrap-ansi@6.2.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ wrap-ansi@9.0.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 7.2.0
+ strip-ansi: 7.1.0
+
+ wrappy@1.0.2: {}
+
+ ws@8.18.0: {}
+
+ y18n@5.0.8: {}
+
+ yaml@2.5.1: {}
+
+ yargs-parser@20.2.9: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs-unparser@2.0.0:
+ dependencies:
+ camelcase: 6.3.0
+ decamelize: 4.0.0
+ flat: 5.0.2
+ is-plain-obj: 2.1.0
+
+ yargs@16.2.0:
+ dependencies:
+ cliui: 7.0.4
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 20.2.9
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
+
+ yauzl@2.10.0:
+ dependencies:
+ buffer-crc32: 0.2.13
+ fd-slicer: 1.1.0
+
+ yn@3.1.1: {}
+
+ yocto-queue@0.1.0: {}
+
+ yocto-queue@1.1.1: {}
+
+ yoctocolors-cjs@2.1.2: {}
+
+ yoctocolors@2.1.1: {}
+
+ zip-stream@6.0.1:
+ dependencies:
+ archiver-utils: 5.0.2
+ compress-commons: 6.0.2
+ readable-stream: 4.5.2
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..86894b4
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,5 @@
+packages:
+ - "chrome-extension"
+ - "pages/*"
+ - "packages/*"
+ - "tests/*"
diff --git a/tests/e2e/config/wdio.browser.conf.ts b/tests/e2e/config/wdio.browser.conf.ts
new file mode 100644
index 0000000..dee58cd
--- /dev/null
+++ b/tests/e2e/config/wdio.browser.conf.ts
@@ -0,0 +1,64 @@
+import { config as baseConfig } from './wdio.conf';
+import path from 'node:path';
+import url from 'node:url';
+import fs from 'node:fs/promises';
+import { getChromeExtensionPath, getFirefoxExtensionPath } from '../utils/extension-path';
+
+const isFirefox = process.env.__FIREFOX__ === 'true';
+const isCI = process.env.CI === 'true';
+const extName = isFirefox ? '.xpi' : '.zip';
+const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
+const extensions = await fs.readdir(path.join(__dirname, '../../../dist-zip'));
+const latestExtension = extensions
+ .filter(file => path.extname(file) === extName)
+ .sort()
+ .reverse()[0];
+const extPath = path.join(__dirname, `../../../dist-zip/${latestExtension}`);
+const bundledExtension = (await fs.readFile(extPath)).toString('base64');
+
+const chromeCapabilities = {
+ browserName: 'chrome',
+ acceptInsecureCerts: true,
+ 'goog:chromeOptions': {
+ args: [
+ '--disable-web-security',
+ '--disable-gpu',
+ '--no-sandbox',
+ '--disable-dev-shm-usage',
+ ...(isCI ? ['--headless'] : []),
+ ],
+ prefs: { 'extensions.ui.developer_mode': true },
+ extensions: [bundledExtension],
+ },
+};
+
+const firefoxCapabilities = {
+ browserName: 'firefox',
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [...(isCI ? ['--headless'] : [])],
+ },
+};
+
+export const config: WebdriverIO.Config = {
+ ...baseConfig,
+ capabilities: isFirefox ? [firefoxCapabilities] : [chromeCapabilities],
+
+ maxInstances: isCI ? 10 : 1,
+ logLevel: 'error',
+ execArgv: isCI ? [] : ['--inspect'],
+ before: async ({ browserName }: WebdriverIO.Capabilities, _specs, browser: WebdriverIO.Browser) => {
+ if (browserName === 'firefox') {
+ await browser.installAddOn(bundledExtension, true);
+
+ browser.addCommand('getExtensionPath', async () => getFirefoxExtensionPath(browser));
+ } else if (browserName === 'chrome') {
+ browser.addCommand('getExtensionPath', async () => getChromeExtensionPath(browser));
+ }
+ },
+ afterTest: async () => {
+ if (!isCI) {
+ await browser.pause(500);
+ }
+ },
+};
diff --git a/tests/e2e/config/wdio.conf.ts b/tests/e2e/config/wdio.conf.ts
new file mode 100644
index 0000000..2567bb6
--- /dev/null
+++ b/tests/e2e/config/wdio.conf.ts
@@ -0,0 +1,97 @@
+/**
+ * WebdriverIO v9 configuration file
+ * https://webdriver.io/docs/configurationfile
+ */
+export const config: WebdriverIO.Config = {
+ runner: 'local',
+ tsConfigPath: '../tsconfig.json',
+
+ //
+ // ==================
+ // Specify Test Files
+ // ==================
+ // Define which test specs should run. The pattern is relative to the directory
+ // of the configuration file being run.
+ //
+ // The specs are defined as an array of spec files (optionally using wildcards
+ // that will be expanded). The test for each spec file will be run in a separate
+ // worker process. In order to have a group of spec files run in the same worker
+ // process simply enclose them in an array within the specs array.
+ //
+ // The path of the spec files will be resolved relative from the directory
+ // of the config file unless it's absolute.
+ specs: ['../specs/**/*.ts'],
+ // Patterns to exclude.
+ exclude: [],
+ //
+ // ============
+ // Capabilities
+ // ============
+ // Define your capabilities here. WebdriverIO can run multiple capabilities at the same
+ // time. Depending on the number of capabilities, WebdriverIO launches several test
+ // sessions. Within your capabilities you can overwrite the spec and exclude options in
+ // order to group specific specs to a specific capability.
+ //
+ // First, you can define how many instances should be started at the same time. Let's
+ // say you have 3 different capabilities (Chrome, Firefox, and Safari) and you have
+ // set maxInstances to 1; wdio will spawn 3 processes. Therefore, if you have 10 spec
+ // files and you set maxInstances to 10, all spec files will get tested at the same time
+ // and 30 processes will get spawned. The property handles how many capabilities
+ // from the same test should run tests.
+ //
+ maxInstances: 10,
+ //
+ // If you have trouble getting all important capabilities together, check out the
+ // Sauce Labs platform configurator - a great tool to configure your capabilities:
+ // https://saucelabs.com/platform/platform-configurator
+ //
+ capabilities: [],
+
+ //
+ // ===================
+ // Test Configurations
+ // ===================
+ // Define all options that are relevant for the WebdriverIO instance here
+ //
+ // Level of logging verbosity: trace | debug | info | warn | error | silent
+ logLevel: 'info',
+
+ //
+ // If you only want to run your tests until a specific amount of tests have failed use
+ // bail (default is 0 - don't bail, run all tests).
+ bail: 0,
+ //
+ // Default timeout for all waitFor* commands.
+ waitforTimeout: 10000,
+
+ //
+ // Default timeout in milliseconds for request
+ // if browser driver or grid doesn't send response
+ connectionRetryTimeout: 120000,
+
+ //
+ // Default request retries count
+ connectionRetryCount: 3,
+
+ //
+ // Framework you want to run your specs with.
+ // The following are supported: Mocha, Jasmine, and Cucumber
+ // see also: https://webdriver.io/docs/frameworks
+ //
+ // Make sure you have the wdio adapter package for the specific framework installed
+ // before running any tests.
+ framework: 'mocha',
+
+ //
+ // Test reporter for stdout.
+ // The only one supported by default is 'dot'
+ // see also: https://webdriver.io/docs/dot-reporter
+ reporters: ['spec'],
+
+ // Options to be passed to Mocha.
+ // See the full list at http://mochajs.org/
+ mochaOpts: {
+ ui: 'bdd',
+ timeout: 60000,
+ },
+};
diff --git a/tests/e2e/config/wdio.d.ts b/tests/e2e/config/wdio.d.ts
new file mode 100644
index 0000000..8dbebe4
--- /dev/null
+++ b/tests/e2e/config/wdio.d.ts
@@ -0,0 +1,7 @@
+declare namespace WebdriverIO {
+ interface Browser extends WebdriverIO.Browser {
+ getExtensionPath: () => Promise;
+ installAddOn: (extension: string, temporary: boolean) => Promise;
+ addCommand: (name: string, func: () => Promise) => void;
+ }
+}
diff --git a/tests/e2e/helpers/theme.ts b/tests/e2e/helpers/theme.ts
new file mode 100644
index 0000000..9dfd6c1
--- /dev/null
+++ b/tests/e2e/helpers/theme.ts
@@ -0,0 +1,26 @@
+/**
+ * Helper method to check if user can click on theme button and toggle theme color
+ */
+export const canSwitchTheme = async () => {
+ const LIGHT_THEME_CLASS = 'bg-slate-50';
+ const DARK_THEME_CLASS = 'bg-gray-800';
+ const TOGGLE_BUTTON_TEXT = 'Toggle theme';
+
+ const app = await $('.App').getElement();
+ const toggleThemeButton = await $(`button=${TOGGLE_BUTTON_TEXT}`).getElement();
+
+ await expect(app).toBeExisting();
+ await expect(toggleThemeButton).toBeExisting();
+
+ const appClasses = await app.getAttribute('class');
+ const initialThemeClass = appClasses.includes(LIGHT_THEME_CLASS) ? LIGHT_THEME_CLASS : DARK_THEME_CLASS;
+ const afterClickThemeClass = appClasses.includes(LIGHT_THEME_CLASS) ? DARK_THEME_CLASS : LIGHT_THEME_CLASS;
+
+ // Toggle theme
+ await toggleThemeButton.click();
+ await expect(app).toHaveElementClass(afterClickThemeClass);
+
+ // Toggle back to initial theme
+ await toggleThemeButton.click();
+ await expect(app).toHaveElementClass(initialThemeClass);
+};
diff --git a/tests/e2e/package.json b/tests/e2e/package.json
new file mode 100644
index 0000000..232f203
--- /dev/null
+++ b/tests/e2e/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "@extension/e2e",
+ "version": "0.3.5",
+ "description": "E2e tests configuration boilerplate",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "e2e": "wdio run ./config/wdio.browser.conf.ts",
+ "clean:node_modules": "pnpx rimraf node_modules",
+ "clean:turbo": "pnpx rimraf .turbo",
+ "clean": "pnpm clean:turbo && pnpm clean:node_modules"
+ },
+ "devDependencies": {
+ "@extension/tsconfig": "workspace:*",
+ "@wdio/cli": "^9.4.5",
+ "@wdio/globals": "^9.4.5",
+ "@wdio/local-runner": "^9.1.2",
+ "@wdio/mocha-framework": "^9.1.2",
+ "@wdio/spec-reporter": "^9.2.14",
+ "@wdio/types": "^9.1.2",
+ "tsx": "^4.19.2"
+ }
+}
diff --git a/tests/e2e/specs/page-content-runtime.test.ts b/tests/e2e/specs/page-content-runtime.test.ts
new file mode 100644
index 0000000..7706751
--- /dev/null
+++ b/tests/e2e/specs/page-content-runtime.test.ts
@@ -0,0 +1,28 @@
+describe('Webextension Content Runtime Script', () => {
+ before(function () {
+ if ((browser.capabilities as WebdriverIO.Capabilities).browserName === 'chrome') {
+ // Chrome doesn't allow content scripts on the extension pages
+ this.skip();
+ }
+ });
+
+ it('should create runtime element on the page', async () => {
+ // Open the popup
+ const extensionPath = await browser.getExtensionPath();
+ const popupUrl = `${extensionPath}/popup/index.html`;
+ await browser.url(popupUrl);
+
+ await expect(browser).toHaveTitle('Popup');
+
+ // Trigger the content script on the popup
+ // button contains "Content Script" text
+ const contentScriptButton = await $('button*=Content Script').getElement();
+
+ await contentScriptButton.click();
+
+ // Check if id chrome-extension-boilerplate-react-vite-runtime-content-view-root exists on page
+ const runtimeElement = await $('#chrome-extension-boilerplate-react-vite-runtime-content-view-root').getElement();
+
+ await expect(runtimeElement).toBeExisting();
+ });
+});
diff --git a/tests/e2e/specs/page-content-ui.test.ts b/tests/e2e/specs/page-content-ui.test.ts
new file mode 100644
index 0000000..50fbb13
--- /dev/null
+++ b/tests/e2e/specs/page-content-ui.test.ts
@@ -0,0 +1,8 @@
+describe('Content UI Injection', () => {
+ it('should locate the injected content UI div', async () => {
+ await browser.url('https://www.example.com');
+
+ const contentDiv = await $('#chrome-extension-boilerplate-react-vite-content-view-root').getElement();
+ await expect(contentDiv).toBeDisplayed();
+ });
+});
diff --git a/tests/e2e/specs/page-content.test.ts b/tests/e2e/specs/page-content.test.ts
new file mode 100644
index 0000000..3fda55d
--- /dev/null
+++ b/tests/e2e/specs/page-content.test.ts
@@ -0,0 +1,17 @@
+describe('Webextension Content Script', () => {
+ it('should log "content script loaded" in console', async () => {
+ await browser.sessionSubscribe({ events: ['log.entryAdded'] });
+ const logs: (string | null)[] = [];
+
+ browser.on('log.entryAdded', logEntry => {
+ logs.push(logEntry.text);
+ });
+
+ await browser.url('https://www.example.com');
+
+ const EXPECTED_LOG_MESSAGE = 'content script loaded';
+ await browser.waitUntil(() => logs.includes(EXPECTED_LOG_MESSAGE));
+
+ expect(logs).toContain(EXPECTED_LOG_MESSAGE);
+ });
+});
diff --git a/tests/e2e/specs/page-dev-tools.test.ts b/tests/e2e/specs/page-dev-tools.test.ts
new file mode 100644
index 0000000..1fe29e6
--- /dev/null
+++ b/tests/e2e/specs/page-dev-tools.test.ts
@@ -0,0 +1,12 @@
+import { canSwitchTheme } from '../helpers/theme';
+
+describe('Webextension DevTools Panel', () => {
+ it('should make DevTools panel available', async () => {
+ const extensionPath = await browser.getExtensionPath();
+ const devtoolsPanelUrl = `${extensionPath}/devtools-panel/index.html`;
+
+ await browser.url(devtoolsPanelUrl);
+ await expect(browser).toHaveTitle('Devtools Panel');
+ await canSwitchTheme();
+ });
+});
diff --git a/tests/e2e/specs/page-new-tab.test.ts b/tests/e2e/specs/page-new-tab.test.ts
new file mode 100644
index 0000000..a7ab69c
--- /dev/null
+++ b/tests/e2e/specs/page-new-tab.test.ts
@@ -0,0 +1,14 @@
+import { canSwitchTheme } from '../helpers/theme';
+
+describe('Webextension New Tab', () => {
+ it('should open the extension page when a new tab is opened', async () => {
+ const extensionPath = await browser.getExtensionPath();
+ const newTabUrl = process.env.__FIREFOX__ === 'true' ? `${extensionPath}/new-tab/index.html` : 'chrome://newtab';
+
+ await browser.url(newTabUrl);
+
+ const appDiv = await $('.App').getElement();
+ await expect(appDiv).toBeExisting();
+ await canSwitchTheme();
+ });
+});
diff --git a/tests/e2e/specs/page-options.test.ts b/tests/e2e/specs/page-options.test.ts
new file mode 100644
index 0000000..16f1497
--- /dev/null
+++ b/tests/e2e/specs/page-options.test.ts
@@ -0,0 +1,13 @@
+import { canSwitchTheme } from '../helpers/theme';
+
+describe('Webextension Options Page', () => {
+ it('should make options page accessible', async () => {
+ const extensionPath = await browser.getExtensionPath();
+ const optionsUrl = `${extensionPath}/options/index.html`;
+
+ await browser.url(optionsUrl);
+
+ await expect(browser).toHaveTitle('Options');
+ await canSwitchTheme();
+ });
+});
diff --git a/tests/e2e/specs/page-popup.test.ts b/tests/e2e/specs/page-popup.test.ts
new file mode 100644
index 0000000..9128db1
--- /dev/null
+++ b/tests/e2e/specs/page-popup.test.ts
@@ -0,0 +1,12 @@
+import { canSwitchTheme } from '../helpers/theme';
+
+describe('Webextension Popup', () => {
+ it('should open the popup successfully', async () => {
+ const extensionPath = await browser.getExtensionPath();
+ const popupUrl = `${extensionPath}/popup/index.html`;
+ await browser.url(popupUrl);
+
+ await expect(browser).toHaveTitle('Popup');
+ await canSwitchTheme();
+ });
+});
diff --git a/tests/e2e/specs/page-side-panel.test.ts b/tests/e2e/specs/page-side-panel.test.ts
new file mode 100644
index 0000000..0f33ac5
--- /dev/null
+++ b/tests/e2e/specs/page-side-panel.test.ts
@@ -0,0 +1,12 @@
+import { canSwitchTheme } from '../helpers/theme';
+
+describe('Webextension Side Panel', () => {
+ it('should make side panel accessible', async () => {
+ const extensionPath = await browser.getExtensionPath();
+ const sidePanelUrl = `${extensionPath}/side-panel/index.html`;
+
+ await browser.url(sidePanelUrl);
+ await expect(browser).toHaveTitle('Side Panel');
+ await canSwitchTheme();
+ });
+});
diff --git a/tests/e2e/specs/smoke.test.ts b/tests/e2e/specs/smoke.test.ts
new file mode 100644
index 0000000..ba2d9ac
--- /dev/null
+++ b/tests/e2e/specs/smoke.test.ts
@@ -0,0 +1,7 @@
+describe('The example page can be loaded', () => {
+ it('should be able to go to example page', async () => {
+ await browser.url('https://www.example.com');
+
+ await expect(browser).toHaveTitle('Example Domain');
+ });
+});
diff --git a/tests/e2e/tsconfig.json b/tests/e2e/tsconfig.json
new file mode 100644
index 0000000..1778b50
--- /dev/null
+++ b/tests/e2e/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "@extension/tsconfig/utils",
+ "compilerOptions": {
+ "moduleResolution": "node",
+ "module": "ESNext",
+ "target": "es2022",
+ "lib": ["es2022", "dom"],
+ "types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"],
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["specs", "config", "helpers"]
+}
diff --git a/tests/e2e/utils/extension-path.ts b/tests/e2e/utils/extension-path.ts
new file mode 100644
index 0000000..47af370
--- /dev/null
+++ b/tests/e2e/utils/extension-path.ts
@@ -0,0 +1,49 @@
+/**
+ * Returns the Chrome extension path.
+ * @param browser
+ * @returns path to the Chrome extension
+ */
+export const getChromeExtensionPath = async (browser: WebdriverIO.Browser) => {
+ await browser.url('chrome://extensions/');
+ /**
+ * https://webdriver.io/docs/extension-testing/web-extensions/#test-popup-modal-in-chrome
+ * ```ts
+ * const extensionItem = await $('extensions-item').getElement();
+ * ```
+ * The above code is not working. I guess it's because the shadow root is not accessible.
+ * So I used the following code to access the shadow root manually.
+ *
+ * @url https://github.com/webdriverio/webdriverio/issues/13521
+ * @url https://github.com/Jonghakseo/chrome-extension-boilerplate-react-vite/issues/786
+ */
+ const extensionItem = await (async () => {
+ const extensionsManager = await $('extensions-manager').getElement();
+ const itemList = await extensionsManager.shadow$('#container > #viewManager > extensions-item-list');
+ return await itemList.shadow$('extensions-item');
+ })();
+
+ const extensionId = await extensionItem.getAttribute('id');
+
+ if (!extensionId) {
+ throw new Error('Extension ID not found');
+ }
+
+ return `chrome-extension://${extensionId}`;
+};
+
+/**
+ * Returns the Firefox extension path.
+ * @param browser
+ * @returns path to the Firefox extension
+ */
+export const getFirefoxExtensionPath = async (browser: WebdriverIO.Browser) => {
+ await browser.url('about:debugging#/runtime/this-firefox');
+ const uuidElement = await browser.$('//dt[contains(text(), "Internal UUID")]/following-sibling::dd').getElement();
+ const internalUUID = await uuidElement.getText();
+
+ if (!internalUUID) {
+ throw new Error('Internal UUID not found');
+ }
+
+ return `moz-extension://${internalUUID}`;
+};
diff --git a/turbo.json b/turbo.json
new file mode 100644
index 0000000..6a346bd
--- /dev/null
+++ b/turbo.json
@@ -0,0 +1,54 @@
+{
+ "$schema": "https://turbo.build/schema.json",
+ "ui": "tui",
+ "globalEnv": ["__FIREFOX__"],
+ "daemon": false,
+ "tasks": {
+ "ready": {
+ "dependsOn": ["^ready"],
+ "outputs": ["dist/**", "build/**"]
+ },
+ "dev": {
+ "dependsOn": ["ready"],
+ "outputs": ["dist/**", "build/**", "i18n/locales/**"],
+ "cache": false,
+ "persistent": true
+ },
+ "build": {
+ "dependsOn": ["^build"],
+ "outputs": ["../../dist/**", "dist/**", "build/**"],
+ "cache": false
+ },
+ "e2e": {
+ "cache": false
+ },
+ "type-check": {
+ "cache": false
+ },
+ "lint": {
+ "cache": false
+ },
+ "lint:fix": {
+ "cache": false
+ },
+ "prettier": {
+ "cache": false
+ },
+ "clean:node_modules": {
+ "dependsOn": ["^clean:node_modules"],
+ "cache": false
+ },
+ "clean:turbo": {
+ "dependsOn": ["^clean:turbo"],
+ "cache": false
+ },
+ "clean:bundle": {
+ "dependsOn": ["^clean:bundle"],
+ "cache": false
+ },
+ "clean": {
+ "dependsOn": ["^clean"],
+ "cache": false
+ }
+ }
+}
diff --git a/update_version.sh b/update_version.sh
new file mode 100755
index 0000000..3bee333
--- /dev/null
+++ b/update_version.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# Usage: ./update_version.sh
+# FORMAT IS <0.0.0>
+
+if [[ "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
+ find . -name 'package.json' -not -path '*/node_modules/*' -exec bash -c '
+ # Parse the version from package.json
+ current_version=$(grep -o "\"version\": \"[^\"]*" "$0" | cut -d"\"" -f4)
+
+ # Update the version
+ perl -i -pe"s/$current_version/'$1'/" "$0"
+ ' {} \;
+
+ echo "Updated versions to $1";
+else
+ echo "Version format <$1> isn't correct, proper format is <0.0.0>";
+fi
diff --git a/vite-env.d.ts b/vite-env.d.ts
new file mode 100644
index 0000000..1a43b1b
--- /dev/null
+++ b/vite-env.d.ts
@@ -0,0 +1,9 @@
+///
+
+interface ImportMetaEnv {
+ readonly VITE_EXAMPLE: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}